Home | History | Annotate | Download | only in src
      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 #include "stlport_prefix.h"
     19 
     20 #include <locale>
     21 #include <algorithm>
     22 #include <typeinfo>
     23 
     24 #include "c_locale.h"
     25 #include "aligned_buffer.h"
     26 #include "acquire_release.h"
     27 #include "locale_impl.h"
     28 
     29 _STLP_BEGIN_NAMESPACE
     30 
     31 static const string _Nameless("*");
     32 
     33 static inline bool is_C_locale_name (const char* name)
     34 { return ((name[0] == 'C') && (name[1] == 0)); }
     35 
     36 locale::facet * _STLP_CALL _get_facet(locale::facet *f)
     37 {
     38   if (f != 0)
     39     f->_M_incr();
     40   return f;
     41 }
     42 
     43 void _STLP_CALL _release_facet(locale::facet *&f)
     44 {
     45   if ((f != 0) && (f->_M_decr() == 0)) {
     46     delete f;
     47     f = 0;
     48   }
     49 }
     50 
     51 size_t locale::id::_S_max = 27;
     52 
     53 static void _Stl_loc_assign_ids();
     54 
     55 static _Stl_aligned_buffer<_Locale_impl::Init> __Loc_init_buf;
     56 
     57 _Locale_impl::Init::Init() {
     58   if (_M_count()._M_incr() == 1) {
     59     _Locale_impl::_S_initialize();
     60   }
     61 }
     62 
     63 _Locale_impl::Init::~Init() {
     64   if (_M_count()._M_decr() == 0) {
     65     _Locale_impl::_S_uninitialize();
     66   }
     67 }
     68 
     69 _Refcount_Base& _Locale_impl::Init::_M_count() const {
     70   static _Refcount_Base _S_count(0);
     71   return _S_count;
     72 }
     73 
     74 _Locale_impl::_Locale_impl(const char* s)
     75   : _Refcount_Base(0), name(s), facets_vec() {
     76   facets_vec.reserve( locale::id::_S_max );
     77   new (&__Loc_init_buf) Init();
     78 }
     79 
     80 _Locale_impl::_Locale_impl( _Locale_impl const& locimpl )
     81   : _Refcount_Base(0), name(locimpl.name), facets_vec() {
     82   for_each( locimpl.facets_vec.begin(), locimpl.facets_vec.end(), _get_facet);
     83   facets_vec = locimpl.facets_vec;
     84   new (&__Loc_init_buf) Init();
     85 }
     86 
     87 _Locale_impl::_Locale_impl( size_t n, const char* s)
     88   : _Refcount_Base(0), name(s), facets_vec(n, 0) {
     89   new (&__Loc_init_buf) Init();
     90 }
     91 
     92 _Locale_impl::~_Locale_impl() {
     93   (&__Loc_init_buf)->~Init();
     94   for_each( facets_vec.begin(), facets_vec.end(), _release_facet);
     95 }
     96 
     97 // Initialization of the locale system.  This must be called before
     98 // any locales are constructed.  (Meaning that it must be called when
     99 // the I/O library itself is initialized.)
    100 void _STLP_CALL _Locale_impl::_S_initialize() {
    101   _Stl_loc_assign_ids();
    102   make_classic_locale();
    103 }
    104 
    105 // Release of the classic locale ressources. Has to be called after the last
    106 // locale destruction and not only after the classic locale destruction as
    107 // the facets can be shared between different facets.
    108 void _STLP_CALL _Locale_impl::_S_uninitialize() {
    109   //Not necessary anymore as classic facets are now 'normal' dynamically allocated
    110   //facets with a reference counter telling to _release_facet when the facet can be
    111   //deleted.
    112   //free_classic_locale();
    113 }
    114 
    115 // _Locale_impl non-inline member functions.
    116 void _STLP_CALL _Locale_impl::_M_throw_bad_cast() {
    117   _STLP_THROW(bad_cast());
    118 }
    119 
    120 void _Locale_impl::insert(_Locale_impl *from, const locale::id& n) {
    121   if (n._M_index > 0 && n._M_index < from->size()) {
    122     this->insert(from->facets_vec[n._M_index], n);
    123   }
    124 }
    125 
    126 locale::facet* _Locale_impl::insert(locale::facet *f, const locale::id& n) {
    127   if (f == 0 || n._M_index == 0)
    128     return 0;
    129 
    130   if (n._M_index >= facets_vec.size()) {
    131     facets_vec.resize(n._M_index + 1);
    132   }
    133 
    134   if (f != facets_vec[n._M_index])
    135   {
    136     _release_facet(facets_vec[n._M_index]);
    137     facets_vec[n._M_index] = _get_facet(f);
    138   }
    139 
    140   return f;
    141 }
    142 
    143 //
    144 // <locale> content which is dependent on the name
    145 //
    146 
    147 /* Six functions, one for each category.  Each of them takes a
    148  * a name, constructs that appropriate category facets by name,
    149  * and inserts them into the locale. */
    150 _Locale_name_hint* _Locale_impl::insert_ctype_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
    151   if (name[0] == 0)
    152     name = _Locale_ctype_default(buf);
    153 
    154   if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
    155     _Locale_impl* i2 = locale::classic()._M_impl;
    156     this->insert(i2, ctype<char>::id);
    157     this->insert(i2, codecvt<char, char, mbstate_t>::id);
    158 #ifndef _STLP_NO_WCHAR_T
    159     this->insert(i2, ctype<wchar_t>::id);
    160     this->insert(i2, codecvt<wchar_t, char, mbstate_t>::id);
    161 #endif
    162   } else {
    163     locale::facet*    ct  = 0;
    164     locale::facet*    cvt = 0;
    165 #ifndef _STLP_NO_WCHAR_T
    166     locale::facet* wct    = 0;
    167     locale::facet* wcvt   = 0;
    168 #endif
    169     int __err_code;
    170     _Locale_ctype *__lct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code);
    171     if (!__lct) {
    172       locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
    173       return hint;
    174     }
    175 
    176     if (hint == 0) hint = _Locale_get_ctype_hint(__lct);
    177 
    178     _STLP_TRY {
    179       ct   = new ctype_byname<char>(__lct);
    180     }
    181     _STLP_UNWIND(_STLP_PRIV __release_ctype(__lct));
    182 
    183     _STLP_TRY {
    184       cvt  = new codecvt_byname<char, char, mbstate_t>(name);
    185     }
    186     _STLP_UNWIND(delete ct);
    187 
    188 #ifndef _STLP_NO_WCHAR_T
    189     _STLP_TRY {
    190       _Locale_ctype *__lwct = _STLP_PRIV __acquire_ctype(name, buf, hint, &__err_code);
    191       if (!__lwct) {
    192         locale::_M_throw_on_creation_failure(__err_code, name, "ctype");
    193         return hint;
    194       }
    195 
    196       _STLP_TRY {
    197         wct  = new ctype_byname<wchar_t>(__lwct);
    198       }
    199       _STLP_UNWIND(_STLP_PRIV __release_ctype(__lwct));
    200 
    201       _Locale_codecvt *__lwcvt = _STLP_PRIV __acquire_codecvt(name, buf, hint, &__err_code);
    202       if (__lwcvt) {
    203         _STLP_TRY {
    204           wcvt = new codecvt_byname<wchar_t, char, mbstate_t>(__lwcvt);
    205         }
    206         _STLP_UNWIND(_STLP_PRIV __release_codecvt(__lwcvt); delete wct);
    207       }
    208     }
    209     _STLP_UNWIND(delete cvt; delete ct);
    210 #endif
    211 
    212     this->insert(ct, ctype<char>::id);
    213     this->insert(cvt, codecvt<char, char, mbstate_t>::id);
    214 #ifndef _STLP_NO_WCHAR_T
    215     this->insert(wct, ctype<wchar_t>::id);
    216     if (wcvt) this->insert(wcvt, codecvt<wchar_t, char, mbstate_t>::id);
    217 #endif
    218   }
    219   return hint;
    220 }
    221 
    222 _Locale_name_hint* _Locale_impl::insert_numeric_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
    223   if (name[0] == 0)
    224     name = _Locale_numeric_default(buf);
    225 
    226   _Locale_impl* i2 = locale::classic()._M_impl;
    227 
    228   // We first insert name independant facets taken from the classic locale instance:
    229   this->insert(i2,
    230                num_put<char, ostreambuf_iterator<char, char_traits<char> >  >::id);
    231   this->insert(i2,
    232                num_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
    233 #ifndef _STLP_NO_WCHAR_T
    234   this->insert(i2,
    235                num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> >  >::id);
    236   this->insert(i2,
    237                num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    238 #endif
    239 
    240   if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
    241     this->insert(i2, numpunct<char>::id);
    242 #ifndef _STLP_NO_WCHAR_T
    243     this->insert(i2, numpunct<wchar_t>::id);
    244 #endif
    245   }
    246   else {
    247     locale::facet* punct  = 0;
    248 #ifndef _STLP_NO_WCHAR_T
    249     locale::facet* wpunct = 0;
    250 #endif
    251 
    252     int __err_code;
    253     _Locale_numeric *__lpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code);
    254     if (!__lpunct) {
    255       locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
    256       return hint;
    257     }
    258 
    259     if (hint == 0) hint = _Locale_get_numeric_hint(__lpunct);
    260     _STLP_TRY {
    261       punct = new numpunct_byname<char>(__lpunct);
    262     }
    263     _STLP_UNWIND(_STLP_PRIV __release_numeric(__lpunct));
    264 
    265 #ifndef _STLP_NO_WCHAR_T
    266     _Locale_numeric *__lwpunct = _STLP_PRIV __acquire_numeric(name, buf, hint, &__err_code);
    267     if (!__lwpunct) {
    268       delete punct;
    269       locale::_M_throw_on_creation_failure(__err_code, name, "numpunct");
    270       return hint;
    271     }
    272     if (__lwpunct) {
    273       _STLP_TRY {
    274         wpunct  = new numpunct_byname<wchar_t>(__lwpunct);
    275       }
    276       _STLP_UNWIND(_STLP_PRIV __release_numeric(__lwpunct); delete punct);
    277     }
    278 #endif
    279 
    280     this->insert(punct, numpunct<char>::id);
    281 #ifndef _STLP_NO_WCHAR_T
    282     this->insert(wpunct, numpunct<wchar_t>::id);
    283 #endif
    284   }
    285   return hint;
    286 }
    287 
    288 _Locale_name_hint* _Locale_impl::insert_time_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
    289   if (name[0] == 0)
    290     name = _Locale_time_default(buf);
    291 
    292   if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
    293     _Locale_impl* i2 = locale::classic()._M_impl;
    294     this->insert(i2,
    295                  time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
    296     this->insert(i2,
    297                  time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
    298 #ifndef _STLP_NO_WCHAR_T
    299     this->insert(i2,
    300                  time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    301     this->insert(i2,
    302                  time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    303 #endif
    304   } else {
    305     locale::facet *get = 0;
    306     locale::facet *put = 0;
    307 #ifndef _STLP_NO_WCHAR_T
    308     locale::facet *wget = 0;
    309     locale::facet *wput = 0;
    310 #endif
    311 
    312     int __err_code;
    313     _Locale_time *__time = _STLP_PRIV __acquire_time(name, buf, hint, &__err_code);
    314     if (!__time) {
    315       // time facets category is not mandatory for correct stream behavior so if platform
    316       // do not support it we do not generate a runtime_error exception.
    317       if (__err_code == _STLP_LOC_NO_MEMORY) {
    318         _STLP_THROW_BAD_ALLOC;
    319       }
    320       return hint;
    321     }
    322 
    323     if (!hint) hint = _Locale_get_time_hint(__time);
    324     _STLP_TRY {
    325       get = new time_get_byname<char, istreambuf_iterator<char, char_traits<char> > >(__time);
    326       put = new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(__time);
    327 #ifndef _STLP_NO_WCHAR_T
    328       wget = new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(__time);
    329       wput = new time_put_byname<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(__time);
    330 #endif
    331     }
    332 #ifndef _STLP_NO_WCHAR_T
    333     _STLP_UNWIND(delete wget; delete put; delete get; _STLP_PRIV __release_time(__time));
    334 #else
    335     _STLP_UNWIND(delete get; _STLP_PRIV __release_time(__time));
    336 #endif
    337 
    338     _STLP_PRIV __release_time(__time);
    339 
    340     this->insert(get, time_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
    341     this->insert(put, time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
    342 #ifndef _STLP_NO_WCHAR_T
    343     this->insert(wget, time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    344     this->insert(wput, time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    345 #endif
    346   }
    347   return hint;
    348 }
    349 
    350 _Locale_name_hint* _Locale_impl::insert_collate_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
    351   if (name[0] == 0)
    352     name = _Locale_collate_default(buf);
    353 
    354   if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
    355     _Locale_impl* i2 = locale::classic()._M_impl;
    356     this->insert(i2, collate<char>::id);
    357 #ifndef _STLP_NO_WCHAR_T
    358     this->insert(i2, collate<wchar_t>::id);
    359 #endif
    360   }
    361   else {
    362     locale::facet *col = 0;
    363 #ifndef _STLP_NO_WCHAR_T
    364     locale::facet *wcol = 0;
    365 #endif
    366 
    367     int __err_code;
    368     _Locale_collate *__coll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code);
    369     if (!__coll) {
    370       if (__err_code == _STLP_LOC_NO_MEMORY) {
    371         _STLP_THROW_BAD_ALLOC;
    372       }
    373       return hint;
    374     }
    375 
    376     if (hint == 0) hint = _Locale_get_collate_hint(__coll);
    377     _STLP_TRY {
    378       col = new collate_byname<char>(__coll);
    379     }
    380     _STLP_UNWIND(_STLP_PRIV __release_collate(__coll));
    381 
    382 #ifndef _STLP_NO_WCHAR_T
    383     _Locale_collate *__wcoll = _STLP_PRIV __acquire_collate(name, buf, hint, &__err_code);
    384     if (!__wcoll) {
    385       if (__err_code == _STLP_LOC_NO_MEMORY) {
    386         delete col;
    387         _STLP_THROW_BAD_ALLOC;
    388       }
    389     }
    390     if (__wcoll) {
    391       _STLP_TRY {
    392         wcol  = new collate_byname<wchar_t>(__wcoll);
    393       }
    394       _STLP_UNWIND(_STLP_PRIV __release_collate(__wcoll); delete col);
    395     }
    396 #endif
    397 
    398     this->insert(col, collate<char>::id);
    399 #ifndef _STLP_NO_WCHAR_T
    400     if (wcol) this->insert(wcol, collate<wchar_t>::id);
    401 #endif
    402   }
    403   return hint;
    404 }
    405 
    406 _Locale_name_hint* _Locale_impl::insert_monetary_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
    407   if (name[0] == 0)
    408     name = _Locale_monetary_default(buf);
    409 
    410   _Locale_impl* i2 = locale::classic()._M_impl;
    411 
    412   // We first insert name independant facets taken from the classic locale instance:
    413   this->insert(i2, money_get<char, istreambuf_iterator<char, char_traits<char> > >::id);
    414   this->insert(i2, money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id);
    415 #ifndef _STLP_NO_WCHAR_T
    416   this->insert(i2, money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    417   this->insert(i2, money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id);
    418 #endif
    419 
    420   if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
    421     this->insert(i2, moneypunct<char, false>::id);
    422     this->insert(i2, moneypunct<char, true>::id);
    423 #ifndef _STLP_NO_WCHAR_T
    424     this->insert(i2, moneypunct<wchar_t, false>::id);
    425     this->insert(i2, moneypunct<wchar_t, true>::id);
    426 #endif
    427   }
    428   else {
    429     locale::facet *punct   = 0;
    430     locale::facet *ipunct  = 0;
    431 
    432 #ifndef _STLP_NO_WCHAR_T
    433     locale::facet* wpunct  = 0;
    434     locale::facet* wipunct = 0;
    435 #endif
    436 
    437     int __err_code;
    438     _Locale_monetary *__mon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
    439     if (!__mon) {
    440       if (__err_code == _STLP_LOC_NO_MEMORY) {
    441         _STLP_THROW_BAD_ALLOC;
    442       }
    443       return hint;
    444     }
    445 
    446     if (hint == 0) hint = _Locale_get_monetary_hint(__mon);
    447 
    448     _STLP_TRY {
    449       punct   = new moneypunct_byname<char, false>(__mon);
    450     }
    451     _STLP_UNWIND(_STLP_PRIV __release_monetary(__mon));
    452 
    453     _Locale_monetary *__imon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
    454     if (!__imon) {
    455       delete punct;
    456       if (__err_code == _STLP_LOC_NO_MEMORY) {
    457         _STLP_THROW_BAD_ALLOC;
    458       }
    459       return hint;
    460     }
    461 
    462     _STLP_TRY {
    463       ipunct  = new moneypunct_byname<char, true>(__imon);
    464     }
    465     _STLP_UNWIND(_STLP_PRIV __release_monetary(__imon); delete punct);
    466 
    467 #ifndef _STLP_NO_WCHAR_T
    468     _STLP_TRY {
    469       _Locale_monetary *__wmon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
    470       if (!__wmon) {
    471         if (__err_code == _STLP_LOC_NO_MEMORY) {
    472           _STLP_THROW_BAD_ALLOC;
    473         }
    474       }
    475 
    476       if (__wmon) {
    477         _STLP_TRY {
    478           wpunct  = new moneypunct_byname<wchar_t, false>(__wmon);
    479         }
    480         _STLP_UNWIND(_STLP_PRIV __release_monetary(__wmon));
    481 
    482         _Locale_monetary *__wimon = _STLP_PRIV __acquire_monetary(name, buf, hint, &__err_code);
    483         if (!__wimon) {
    484           delete wpunct;
    485           if (__err_code == _STLP_LOC_NO_MEMORY) {
    486             _STLP_THROW_BAD_ALLOC;
    487           }
    488           wpunct = 0;
    489         }
    490         else {
    491           _STLP_TRY {
    492             wipunct = new moneypunct_byname<wchar_t, true>(__wimon);
    493           }
    494           _STLP_UNWIND(_STLP_PRIV __release_monetary(__wimon); delete wpunct);
    495         }
    496       }
    497     }
    498     _STLP_UNWIND(delete ipunct; delete punct);
    499 #endif
    500 
    501     this->insert(punct, moneypunct<char, false>::id);
    502     this->insert(ipunct, moneypunct<char, true>::id);
    503 #ifndef _STLP_NO_WCHAR_T
    504     if (wpunct) this->insert(wpunct, moneypunct<wchar_t, false>::id);
    505     if (wipunct) this->insert(wipunct, moneypunct<wchar_t, true>::id);
    506 #endif
    507   }
    508   return hint;
    509 }
    510 
    511 _Locale_name_hint* _Locale_impl::insert_messages_facets(const char* &name, char *buf, _Locale_name_hint* hint) {
    512   if (name[0] == 0)
    513     name = _Locale_messages_default(buf);
    514 
    515   if (name == 0 || name[0] == 0 || is_C_locale_name(name)) {
    516     _Locale_impl* i2 = locale::classic()._M_impl;
    517     this->insert(i2, messages<char>::id);
    518 #ifndef _STLP_NO_WCHAR_T
    519     this->insert(i2, messages<wchar_t>::id);
    520 #endif
    521   }
    522   else {
    523     locale::facet *msg  = 0;
    524 #ifndef _STLP_NO_WCHAR_T
    525     locale::facet *wmsg = 0;
    526 #endif
    527 
    528     int __err_code;
    529     _Locale_messages *__msg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code);
    530     if (!__msg) {
    531       if (__err_code == _STLP_LOC_NO_MEMORY) {
    532         _STLP_THROW_BAD_ALLOC;
    533       }
    534       return hint;
    535     }
    536 
    537     _STLP_TRY {
    538       msg  = new messages_byname<char>(__msg);
    539     }
    540     _STLP_UNWIND(_STLP_PRIV __release_messages(__msg));
    541 
    542 #ifndef _STLP_NO_WCHAR_T
    543     _STLP_TRY {
    544       _Locale_messages *__wmsg = _STLP_PRIV __acquire_messages(name, buf, hint, &__err_code);
    545       if (!__wmsg) {
    546         if (__err_code == _STLP_LOC_NO_MEMORY) {
    547           _STLP_THROW_BAD_ALLOC;
    548         }
    549       }
    550 
    551       if (__wmsg) {
    552         _STLP_TRY {
    553           wmsg = new messages_byname<wchar_t>(__wmsg);
    554         }
    555         _STLP_UNWIND(_STLP_PRIV __release_messages(__wmsg));
    556       }
    557     }
    558     _STLP_UNWIND(delete msg);
    559 #endif
    560 
    561     this->insert(msg, messages<char>::id);
    562 #ifndef _STLP_NO_WCHAR_T
    563     if (wmsg) this->insert(wmsg, messages<wchar_t>::id);
    564 #endif
    565   }
    566   return hint;
    567 }
    568 
    569 static void _Stl_loc_assign_ids() {
    570   // This assigns ids to every facet that is a member of a category,
    571   // and also to money_get/put, num_get/put, and time_get/put
    572   // instantiated using ordinary pointers as the input/output
    573   // iterators.  (The default is [io]streambuf_iterator.)
    574 
    575   money_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index          = 8;
    576   money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index          = 9;
    577   num_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index            = 10;
    578   num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index            = 11;
    579   time_get<char, istreambuf_iterator<char, char_traits<char> > >::id._M_index           = 12;
    580   time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id._M_index           = 13;
    581 
    582 #ifndef _STLP_NO_WCHAR_T
    583   money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 21;
    584   money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index = 22;
    585   num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index   = 23;
    586   num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > > ::id._M_index  = 24;
    587   time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index  = 25;
    588   time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id._M_index  = 26;
    589 #endif
    590   //  locale::id::_S_max                               = 27;
    591 }
    592 
    593 // To access those static instance use the getter below, they guaranty
    594 // a correct initialization.
    595 static locale *_Stl_classic_locale = 0;
    596 static locale *_Stl_global_locale = 0;
    597 
    598 locale* _Stl_get_classic_locale() {
    599   static _Locale_impl::Init init;
    600   return _Stl_classic_locale;
    601 }
    602 
    603 locale* _Stl_get_global_locale() {
    604   static _Locale_impl::Init init;
    605   return _Stl_global_locale;
    606 }
    607 
    608 #if defined (_STLP_MSVC) || defined (__ICL) || defined (__ISCPP__) || defined (__DMC__)
    609 /*
    610  * The following static variable needs to be initialized before STLport
    611  * users static variable in order for him to be able to use Standard
    612  * streams in its variable initialization.
    613  * This variable is here because MSVC do not allow to change the initialization
    614  * segment in a given translation unit, iostream.cpp already contains an
    615  * initialization segment specification.
    616  */
    617 #  pragma warning (disable : 4073)
    618 #  pragma init_seg(lib)
    619 #endif
    620 
    621 static ios_base::Init _IosInit;
    622 
    623 void _Locale_impl::make_classic_locale() {
    624   // This funcion will be called once: during build classic _Locale_impl
    625 
    626   // The classic locale contains every facet that belongs to a category.
    627   static _Stl_aligned_buffer<_Locale_impl> _Locale_classic_impl_buf;
    628   _Locale_impl *classic = new(&_Locale_classic_impl_buf) _Locale_impl("C");
    629 
    630   locale::facet* classic_facets[] = {
    631     0,
    632     new collate<char>(1),
    633     new ctype<char>(0, false, 1),
    634     new codecvt<char, char, mbstate_t>(1),
    635     new moneypunct<char, true>(1),
    636     new moneypunct<char, false>(1),
    637     new numpunct<char>(1),
    638     new messages<char>(1),
    639     new money_get<char, istreambuf_iterator<char, char_traits<char> > >(1),
    640     new money_put<char, ostreambuf_iterator<char, char_traits<char> > >(1),
    641     new num_get<char, istreambuf_iterator<char, char_traits<char> > >(1),
    642     new num_put<char, ostreambuf_iterator<char, char_traits<char> > >(1),
    643     new time_get<char, istreambuf_iterator<char, char_traits<char> > >(1),
    644     new time_put<char, ostreambuf_iterator<char, char_traits<char> > >(1),
    645 #ifndef _STLP_NO_WCHAR_T
    646     new collate<wchar_t>(1),
    647     new ctype<wchar_t>(1),
    648     new codecvt<wchar_t, char, mbstate_t>(1),
    649     new moneypunct<wchar_t, true>(1),
    650     new moneypunct<wchar_t, false>(1),
    651     new numpunct<wchar_t>(1),
    652     new messages<wchar_t>(1),
    653     new money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
    654     new money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
    655     new num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
    656     new num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
    657     new time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
    658     new time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1),
    659 #endif
    660     0
    661   };
    662 
    663   const size_t nb_classic_facets = sizeof(classic_facets) / sizeof(locale::facet *);
    664   classic->facets_vec.reserve(nb_classic_facets);
    665   classic->facets_vec.assign(&classic_facets[0], &classic_facets[0] + nb_classic_facets);
    666 
    667   static locale _Locale_classic(classic);
    668   _Stl_classic_locale = &_Locale_classic;
    669 
    670   static locale _Locale_global(classic);
    671   _Stl_global_locale = &_Locale_global;
    672 }
    673 
    674 // Declarations of (non-template) facets' static data members
    675 // size_t locale::id::_S_max = 27; // made before
    676 
    677 locale::id collate<char>::id = { 1 };
    678 locale::id ctype<char>::id = { 2 };
    679 locale::id codecvt<char, char, mbstate_t>::id = { 3 };
    680 locale::id moneypunct<char, true>::id = { 4 };
    681 locale::id moneypunct<char, false>::id = { 5 };
    682 locale::id numpunct<char>::id = { 6 } ;
    683 locale::id messages<char>::id = { 7 };
    684 
    685 #ifndef _STLP_NO_WCHAR_T
    686 locale::id collate<wchar_t>::id = { 14 };
    687 locale::id ctype<wchar_t>::id = { 15 };
    688 locale::id codecvt<wchar_t, char, mbstate_t>::id = { 16 };
    689 locale::id moneypunct<wchar_t, true>::id = { 17 } ;
    690 locale::id moneypunct<wchar_t, false>::id = { 18 } ;
    691 locale::id numpunct<wchar_t>::id = { 19 };
    692 locale::id messages<wchar_t>::id = { 20 };
    693 #endif
    694 
    695 _STLP_DECLSPEC _Locale_impl* _STLP_CALL _get_Locale_impl(_Locale_impl *loc)
    696 {
    697   _STLP_ASSERT( loc != 0 );
    698   loc->_M_incr();
    699   return loc;
    700 }
    701 
    702 void _STLP_CALL _release_Locale_impl(_Locale_impl *& loc)
    703 {
    704   _STLP_ASSERT( loc != 0 );
    705   if (loc->_M_decr() == 0) {
    706     if (*loc != *_Stl_classic_locale)
    707       delete loc;
    708     else
    709       loc->~_Locale_impl();
    710     loc = 0;
    711   }
    712 }
    713 
    714 _STLP_DECLSPEC _Locale_impl* _STLP_CALL _copy_Nameless_Locale_impl(_Locale_impl *loc)
    715 {
    716   _STLP_ASSERT( loc != 0 );
    717   _Locale_impl *loc_new = new _Locale_impl(*loc);
    718   loc_new->name = _Nameless;
    719   return loc_new;
    720 }
    721 
    722 /* _GetFacetId implementation have to be here in order to be in the same translation unit
    723  * as where id are initialize (in _Stl_loc_assign_ids) */
    724 _STLP_MOVE_TO_PRIV_NAMESPACE
    725 
    726 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<char, istreambuf_iterator<char, char_traits<char> > >*)
    727 { return money_get<char, istreambuf_iterator<char, char_traits<char> > >::id; }
    728 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<char, ostreambuf_iterator<char, char_traits<char> > >*)
    729 { return money_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; }
    730 #ifndef _STLP_NO_WCHAR_T
    731 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
    732 { return money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
    733 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
    734 { return money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
    735 #endif
    736 
    737 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<char, istreambuf_iterator<char, char_traits<char> > >*)
    738 { return num_get<char, istreambuf_iterator<char, char_traits<char> > >::id; }
    739 #ifndef _STLP_NO_WCHAR_T
    740 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
    741 { return num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
    742 #endif
    743 
    744 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<char, ostreambuf_iterator<char, char_traits<char> > >*)
    745 { return num_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; }
    746 #ifndef _STLP_NO_WCHAR_T
    747 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
    748 { return num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
    749 #endif
    750 
    751 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<char, istreambuf_iterator<char, char_traits<char> > >*)
    752 { return time_get<char, istreambuf_iterator<char, char_traits<char> > >::id; }
    753 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<char, ostreambuf_iterator<char, char_traits<char> > >*)
    754 { return time_put<char, ostreambuf_iterator<char, char_traits<char> > >::id; }
    755 #ifndef _STLP_NO_WCHAR_T
    756 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
    757 { return time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
    758 _STLP_DECLSPEC locale::id& _STLP_CALL _GetFacetId(const time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >*)
    759 { return time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >::id; }
    760 #endif
    761 
    762 _STLP_MOVE_TO_STD_NAMESPACE
    763 
    764 _STLP_END_NAMESPACE
    765 
    766