Home | History | Annotate | Download | only in stl
      1 /*
      2  * Copyright (c) 1999
      3  * Silicon Graphics Computer Systems, Inc.
      4  *
      5  * Copyright (c) 1999
      6  * Boris Fomitchev
      7  *
      8  * This material is provided "as is", with absolutely no warranty expressed
      9  * or implied. Any use is at your own risk.
     10  *
     11  * Permission to use or copy this software for any purpose is hereby granted
     12  * without fee, provided the above notices are retained on all copies.
     13  * Permission to modify the code and to distribute modified code is granted,
     14  * provided the above notices are retained, and a notice that the code was
     15  * modified is included with the above copyright notice.
     16  *
     17  */
     18 // WARNING: This is an internal header file, included by other C++
     19 // standard library headers.  You should not attempt to use this header
     20 // file directly.
     21 
     22 
     23 #ifndef _STLP_INTERNAL_LOCALE_H
     24 #define _STLP_INTERNAL_LOCALE_H
     25 
     26 #ifndef _STLP_INTERNAL_CSTDLIB
     27 #  include <stl/_cstdlib.h>
     28 #endif
     29 
     30 #ifndef _STLP_INTERNAL_CWCHAR
     31 #  include <stl/_cwchar.h>
     32 #endif
     33 
     34 #ifndef _STLP_INTERNAL_THREADS_H
     35 #  include <stl/_threads.h>
     36 #endif
     37 
     38 #ifndef _STLP_STRING_FWD_H
     39 #  include <stl/_string_fwd.h>
     40 #endif
     41 
     42 #include <stl/_facets_fwd.h>
     43 
     44 _STLP_BEGIN_NAMESPACE
     45 
     46 class _Locale_impl;        // Forward declaration of opaque type.
     47 class locale;
     48 
     49 template <class _CharT, class _Traits, class _Alloc>
     50 bool __locale_do_operator_call(const locale& __loc,
     51                                const basic_string<_CharT, _Traits, _Alloc>& __x,
     52                                const basic_string<_CharT, _Traits, _Alloc>& __y);
     53 
     54 _STLP_DECLSPEC _Locale_impl * _STLP_CALL _get_Locale_impl( _Locale_impl *locimpl );
     55 _STLP_DECLSPEC _Locale_impl * _STLP_CALL _copy_Nameless_Locale_impl( _Locale_impl *locimpl );
     56 
     57 _STLP_MOVE_TO_PRIV_NAMESPACE
     58 
     59 template <class _Facet>
     60 bool _HasFacet(const locale& __loc, const _Facet* __facet) _STLP_NOTHROW;
     61 
     62 template <class _Facet>
     63 _Facet* _UseFacet(const locale& __loc, const _Facet* __facet);
     64 
     65 template <class _Facet>
     66 void _InsertFacet(locale& __loc, _Facet* __facet);
     67 
     68 _STLP_MOVE_TO_STD_NAMESPACE
     69 
     70 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) || \
     71     defined (_STLP_SIGNAL_RUNTIME_COMPATIBILITY) || defined (_STLP_CHECK_RUNTIME_COMPATIBILITY)
     72 #  define locale _STLP_NO_MEM_T_NAME(loc)
     73 #endif
     74 
     75 class _STLP_CLASS_DECLSPEC locale {
     76 public:
     77   // types:
     78   class _STLP_CLASS_DECLSPEC facet : protected _Refcount_Base {
     79   protected:
     80     /* Here we filter __init_count user value to 0 or 1 because __init_count is a
     81      * size_t instance and _Refcount_Base use __stl_atomic_t instances that might
     82      * have lower sizeof and generate roll issues. 1 is enough to keep the facet
     83      * alive when required. */
     84     explicit facet(size_t __init_count = 0) : _Refcount_Base( __init_count == 0 ? 0 : 1 ) {}
     85     virtual ~facet();
     86     friend class locale;
     87     friend class _Locale_impl;
     88     friend facet * _STLP_CALL _get_facet( facet * );
     89     friend void _STLP_CALL _release_facet( facet *& );
     90 
     91   private:                        // Invalidate assignment and copying.
     92     facet(const facet& ) /* : _Refcount_Base(1) {} */;
     93     void operator=(const facet&);
     94   };
     95 
     96 #if defined (__MVS__) || defined (__OS400__)
     97   struct
     98 #else
     99   class
    100 #endif
    101   _STLP_CLASS_DECLSPEC id {
    102   public:
    103     size_t _M_index;
    104     static size_t _S_max;
    105   };
    106 
    107   typedef int category;
    108   _STLP_STATIC_CONSTANT(category, none = 0x000);
    109   _STLP_STATIC_CONSTANT(category, collate = 0x010);
    110   _STLP_STATIC_CONSTANT(category, ctype = 0x020);
    111   _STLP_STATIC_CONSTANT(category, monetary = 0x040);
    112   _STLP_STATIC_CONSTANT(category, numeric = 0x100);
    113   _STLP_STATIC_CONSTANT(category, time = 0x200);
    114   _STLP_STATIC_CONSTANT(category, messages = 0x400);
    115   _STLP_STATIC_CONSTANT(category, all = collate | ctype | monetary | numeric | time | messages);
    116 
    117   // construct/copy/destroy:
    118   locale() _STLP_NOTHROW;
    119   locale(const locale&) _STLP_NOTHROW;
    120   explicit locale(const char *);
    121   locale(const locale&, const char*, category);
    122 
    123 #if defined (_STLP_MEMBER_TEMPLATES) && !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
    124   template <class _Facet>
    125   locale(const locale& __loc, _Facet* __f) {
    126     if ( __f != 0 ) {
    127       this->_M_impl = _get_Locale_impl( _copy_Nameless_Locale_impl( __loc._M_impl ) );
    128       _STLP_PRIV _InsertFacet(*this, __f);
    129     } else {
    130       this->_M_impl = _get_Locale_impl( __loc._M_impl );
    131     }
    132   }
    133 #endif
    134 
    135 protected:
    136   // those are for internal use
    137   locale(_Locale_impl*);
    138 
    139 public:
    140   locale(const locale&, const locale&, category);
    141   const locale& operator=(const locale&) _STLP_NOTHROW;
    142 
    143 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
    144 protected:
    145 #endif
    146    ~locale() _STLP_NOTHROW;
    147 
    148 public:
    149 #if defined (_STLP_MEMBER_TEMPLATES) && !defined (_STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS) && \
    150    !defined(_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
    151   template <class _Facet>
    152   locale combine(const locale& __loc) const {
    153     _Facet *__facet = 0;
    154     if (!_STLP_PRIV _HasFacet(__loc, __facet))
    155       _M_throw_on_combine_error(__loc.name());
    156 
    157     return locale(*this, _STLP_PRIV _UseFacet(__loc, __facet));
    158   }
    159 #endif
    160 
    161   // locale operations:
    162   string name() const;
    163 
    164   bool operator==(const locale&) const;
    165   bool operator!=(const locale&) const;
    166 
    167 #if !defined (_STLP_MEMBER_TEMPLATES) || defined (_STLP_INLINE_MEMBER_TEMPLATES) || (defined(__MWERKS__) && __MWERKS__ <= 0x2301)
    168   bool operator()(const string& __x, const string& __y) const;
    169 #  ifndef _STLP_NO_WCHAR_T
    170   bool operator()(const wstring& __x, const wstring& __y) const;
    171 #  endif
    172 #elif !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
    173   template <class _CharT, class _Traits, class _Alloc>
    174   bool operator()(const basic_string<_CharT, _Traits, _Alloc>& __x,
    175                   const basic_string<_CharT, _Traits, _Alloc>& __y) const
    176   { return __locale_do_operator_call(*this, __x, __y); }
    177 #endif
    178 
    179   // global locale objects:
    180 #if !defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND)
    181   static locale _STLP_CALL global(const locale&);
    182 #else
    183   static _Locale_impl* _STLP_CALL global(const locale&);
    184 #endif
    185   static const locale& _STLP_CALL classic();
    186 
    187 //protected:                         // Helper functions for locale globals.
    188   facet* _M_get_facet(const id&) const;
    189   // same, but throws
    190   facet* _M_use_facet(const id&) const;
    191   static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_on_combine_error(const string& name);
    192   static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_on_null_name();
    193   static void _STLP_FUNCTION_THROWS _STLP_CALL _M_throw_on_creation_failure(int __err_code,
    194                                                                             const char* name, const char* facet);
    195 
    196 //protected:                        // More helper functions.
    197   void _M_insert(facet* __f, id& __id);
    198 
    199   // friends:
    200   friend class _Locale_impl;
    201 
    202 protected:                        // Data members
    203   _Locale_impl* _M_impl;
    204   _Locale_impl* _M_get_impl() const { return _M_impl; }
    205 };
    206 
    207 #if defined (_STLP_USE_MSVC6_MEM_T_BUG_WORKAROUND) || \
    208     defined (_STLP_SIGNAL_RUNTIME_COMPATIBILITY) || defined (_STLP_CHECK_RUNTIME_COMPATIBILITY)
    209 #  undef locale
    210 #  define _Locale _STLP_NO_MEM_T_NAME(loc)
    211 
    212 class locale : public _Locale {
    213 public:
    214 
    215   // construct/copy/destroy:
    216   locale() _STLP_NOTHROW {
    217 #if defined (_STLP_CHECK_RUNTIME_COMPATIBILITY)
    218     _STLP_CHECK_RUNTIME_COMPATIBILITY();
    219 #endif
    220   }
    221   locale(const locale& __loc) _STLP_NOTHROW : _Locale(__loc) {}
    222   explicit locale(const char *__str) : _Locale(__str) {}
    223   locale(const locale& __loc, const char* __str, category __cat)
    224     : _Locale(__loc, __str, __cat) {}
    225 
    226   template <class _Facet>
    227   locale(const locale& __loc, _Facet* __f)
    228     : _Locale(__f != 0 ? _copy_Nameless_Locale_impl(__loc._M_impl) : __loc._M_impl) {
    229     if ( __f != 0 ) {
    230       _STLP_PRIV _InsertFacet(*this, __f);
    231     }
    232   }
    233 
    234 private:
    235   // those are for internal use
    236   locale(_Locale_impl* __impl) : _Locale(__impl) {}
    237   locale(const _Locale& __loc) : _Locale(__loc) {}
    238 
    239 public:
    240 
    241   locale(const locale& __loc1, const locale& __loc2, category __cat)
    242     : _Locale(__loc1, __loc2, __cat) {}
    243 
    244   const locale& operator=(const locale& __loc) _STLP_NOTHROW {
    245     _Locale::operator=(__loc);
    246     return *this;
    247   }
    248 
    249   template <class _Facet>
    250   locale combine(const locale& __loc) const {
    251     _Facet *__facet = 0;
    252     if (!_STLP_PRIV _HasFacet(__loc, __facet))
    253       _M_throw_on_combine_error(__loc.name());
    254 
    255     return locale(*this, _STLP_PRIV _UseFacet(__loc, __facet));
    256   }
    257 
    258   // locale operations:
    259   bool operator==(const locale& __loc) const { return _Locale::operator==(__loc); }
    260   bool operator!=(const locale& __loc) const { return _Locale::operator!=(__loc); }
    261 
    262   template <class _CharT, class _Traits, class _Alloc>
    263   bool operator()(const basic_string<_CharT, _Traits, _Alloc>& __x,
    264                   const basic_string<_CharT, _Traits, _Alloc>& __y) const
    265   { return __locale_do_operator_call(*this, __x, __y); }
    266 
    267   // global locale objects:
    268   static locale _STLP_CALL global(const locale& __loc) {
    269     return _Locale::global(__loc);
    270   }
    271   static const locale& _STLP_CALL classic() {
    272     return __STATIC_CAST(const locale&, _Locale::classic());
    273   }
    274 
    275   // friends:
    276   friend class _Locale_impl;
    277 };
    278 
    279 #  undef _Locale
    280 #endif
    281 
    282 //----------------------------------------------------------------------
    283 // locale globals
    284 
    285 template <class _Facet>
    286 inline const _Facet&
    287 #ifdef _STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS
    288 _Use_facet<_Facet>::operator *() const
    289 #else
    290 use_facet(const locale& __loc)
    291 #endif
    292 {
    293   _Facet *__facet = 0;
    294   return *(_STLP_PRIV _UseFacet(__loc, __facet));
    295 }
    296 
    297 template <class _Facet>
    298 #ifdef _STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS
    299 struct has_facet {
    300   const locale& __loc;
    301   has_facet(const locale& __p_loc) : __loc(__p_loc) {}
    302   operator bool() const _STLP_NOTHROW
    303 #else
    304 inline bool has_facet(const locale& __loc) _STLP_NOTHROW
    305 #endif
    306 {
    307   _Facet *__facet = 0;
    308   return _STLP_PRIV _HasFacet(__loc, __facet);
    309 }
    310 
    311 #ifdef _STLP_NO_EXPLICIT_FUNCTION_TMPL_ARGS
    312 }; // close class definition
    313 #endif
    314 
    315 _STLP_MOVE_TO_PRIV_NAMESPACE
    316 
    317 /* _GetFacetId is a helper function that allow delaying access to
    318  * facet id static instance in the library source code to avoid
    319  * the other static instances that many compilers are generating
    320  * in all dynamic library or executable when instanciating facet
    321  * template class.
    322  */
    323 template <class _Facet>
    324 inline locale::id& _GetFacetId(const _Facet*)
    325 { return _Facet::id; }
    326 
    327 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<char, istreambuf_iterator<char, char_traits<char> > >*);
    328 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<char, ostreambuf_iterator<char, char_traits<char> > >*);
    329 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<char, istreambuf_iterator<char, char_traits<char> > >*);
    330 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<char, ostreambuf_iterator<char, char_traits<char> > >*);
    331 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<char, istreambuf_iterator<char, char_traits<char> > >*);
    332 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<char, ostreambuf_iterator<char, char_traits<char> > >*);
    333 
    334 #ifndef _STLP_NO_WCHAR_T
    335 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*);
    336 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*);
    337 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*);
    338 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*);
    339 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*);
    340 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*);
    341 #endif
    342 
    343 template <class _Facet>
    344 inline bool _HasFacet(const locale& __loc, const _Facet* __facet) _STLP_NOTHROW
    345 { return (__loc._M_get_facet(_GetFacetId(__facet)) != 0); }
    346 
    347 template <class _Facet>
    348 inline _Facet* _UseFacet(const locale& __loc, const _Facet* __facet)
    349 { return __STATIC_CAST(_Facet*, __loc._M_use_facet(_GetFacetId(__facet))); }
    350 
    351 template <class _Facet>
    352 inline void _InsertFacet(locale& __loc, _Facet* __facet)
    353 { __loc._M_insert(__facet, _GetFacetId(__facet)); }
    354 
    355 _STLP_MOVE_TO_STD_NAMESPACE
    356 
    357 _STLP_END_NAMESPACE
    358 
    359 #endif /* _STLP_INTERNAL_LOCALE_H */
    360 
    361 // Local Variables:
    362 // mode:C++
    363 // End:
    364 
    365