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