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
is_C_locale_name(const char * name)34 static inline bool is_C_locale_name (const char* name)
35 { return ((name[0] == 'C') && (name[1] == 0)); }
36
_copy_Locale_impl(_Locale_impl * loc)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 = _CHECK_PTR(new _Locale_impl(*loc));
42 loc->_M_decr();
43 return loc_new;
44 }
45
_get_facet(locale::facet * f)46 locale::facet * _STLP_CALL _get_facet(locale::facet *f)
47 {
48 if (f != 0)
49 f->_M_incr();
50 return f;
51 }
52
_release_facet(locale::facet * & f)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
Init()67 _Locale_impl::Init::Init() {
68 if (_M_count()._M_incr() == 1) {
69 _Locale_impl::_S_initialize();
70 }
71 }
72
~Init()73 _Locale_impl::Init::~Init() {
74 if (_M_count()._M_decr() == 0) {
75 _Locale_impl::_S_uninitialize();
76 }
77 }
78
_M_count() const79 _Refcount_Base& _Locale_impl::Init::_M_count() const {
80 static _Refcount_Base _S_count(0);
81 return _S_count;
82 }
83
_Locale_impl(const char * s)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
_Locale_impl(_Locale_impl const & locimpl)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
_Locale_impl(size_t n,const char * s)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
~_Locale_impl()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.)
_S_initialize()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.
_S_uninitialize()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.
_M_throw_bad_cast()126 void _STLP_CALL _Locale_impl::_M_throw_bad_cast() {
127 _STLP_THROW(bad_cast());
128 }
129
insert(_Locale_impl * from,const locale::id & n)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
insert(locale::facet * f,size_t index)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__)
_Locale_extract_hint(ctype_byname<char> * ct)155 _Locale_name_hint* _Locale_extract_hint(ctype_byname<char>* ct)
156 { return _Locale_get_ctype_hint(ct->_M_ctype); }
_Locale_extract_hint(numpunct_byname<char> * punct)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>
_Locale_time_extract_hint(time_get_byname<_Ch,_InIt> * tget)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); }
_Locale_extract_hint(collate_byname<char> * coll)166 _Locale_name_hint* _Locale_extract_hint(collate_byname<char>* coll)
167 { return _Locale_get_collate_hint(coll->_M_collate); }
_Locale_extract_hint(moneypunct_byname<char,false> * money)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>
_Locale_insert(_Locale_impl * __that,Facet * f)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 */
insert_ctype_facets(const char * pname,_Locale_name_hint * hint)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 = _CHECK_PTR(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 = _CHECK_PTR(new codecvt_byname<char, char, mbstate_t>(pname));
220 #endif
221 #ifndef _STLP_NO_WCHAR_T
222 wct = _CHECK_PTR(new ctype_byname<wchar_t>(pname, 0, hint));
223 wcvt = _CHECK_PTR(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
insert_numeric_facets(const char * pname,_Locale_name_hint * hint)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 = _CHECK_PTR(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 = _CHECK_PTR(new num_get<char, istreambuf_iterator<char, char_traits<char> > >);
290 put = _CHECK_PTR(new num_put<char, ostreambuf_iterator<char, char_traits<char> > >);
291 #ifndef _STLP_NO_WCHAR_T
292 wpunct = _CHECK_PTR(new numpunct_byname<wchar_t>(pname, 0, hint));
293 wget = _CHECK_PTR(new num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >);
294 wput = _CHECK_PTR(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
insert_time_facets(const char * pname,_Locale_name_hint * hint)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 _CHECK_PTR(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 = _CHECK_PTR(new time_put_byname<char, ostreambuf_iterator<char, char_traits<char> > >(pname, 0, hint));
350 #ifndef _STLP_NO_WCHAR_T
351 wget = _CHECK_PTR(new time_get_byname<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(pname, 0, hint));
352 wput = _CHECK_PTR(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
insert_collate_facets(const char * nam,_Locale_name_hint * hint)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 = _CHECK_PTR(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 = _CHECK_PTR(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
insert_monetary_facets(const char * pname,_Locale_name_hint * hint)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 = _CHECK_PTR(new moneypunct_byname<char, true>(pname, 0, hint));
451 get = _CHECK_PTR(new money_get<char, istreambuf_iterator<char, char_traits<char> > >);
452 put = _CHECK_PTR(new money_put<char, ostreambuf_iterator<char, char_traits<char> > >);
453 #ifndef _STLP_NO_WCHAR_T
454 wpunct = _CHECK_PTR(new moneypunct_byname<wchar_t, false>(pname, 0, hint));
455 wipunct = _CHECK_PTR(new moneypunct_byname<wchar_t, true>(pname, 0, hint));
456 wget = _CHECK_PTR(new money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >);
457 wput = _CHECK_PTR(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
insert_messages_facets(const char * pname,_Locale_name_hint * hint)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 = _CHECK_PTR(new messages_byname<char>(pname, 0, hint));
499 #ifndef _STLP_NO_WCHAR_T
500 wmsg = _CHECK_PTR(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
_Stl_loc_assign_ids()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
_Stl_get_classic_locale()559 static locale* _Stl_get_classic_locale() {
560 static _Locale_impl::Init init;
561 return _Stl_classic_locale;
562 }
563
_Stl_get_global_locale()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
make_classic_locale()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 _CHECK_PTR(new collate<char>(1)),
594 _CHECK_PTR(new ctype<char>(0, false, 1)),
595 #ifndef _STLP_NO_MBSTATE_T
596 _CHECK_PTR(new codecvt<char, char, mbstate_t>(1)),
597 #else
598 0,
599 #endif
600 _CHECK_PTR(new moneypunct<char, true>(1)),
601 _CHECK_PTR(new moneypunct<char, false>(1)),
602 _CHECK_PTR(new numpunct<char>(1)),
603 _CHECK_PTR(new messages<char>(new _STLP_PRIV _Messages())),
604 _CHECK_PTR(new money_get<char, istreambuf_iterator<char, char_traits<char> > >(1)),
605 0,
606 _CHECK_PTR(new money_put<char, ostreambuf_iterator<char, char_traits<char> > >(1)),
607 0,
608 _CHECK_PTR(new num_get<char, istreambuf_iterator<char, char_traits<char> > >(1)),
609 0,
610 _CHECK_PTR(new num_put<char, ostreambuf_iterator<char, char_traits<char> > >(1)),
611 0,
612 _CHECK_PTR(new time_get<char, istreambuf_iterator<char, char_traits<char> > >(1)),
613 0,
614 _CHECK_PTR(new time_put<char, ostreambuf_iterator<char, char_traits<char> > >(1)),
615 0,
616 #ifndef _STLP_NO_WCHAR_T
617 _CHECK_PTR(new collate<wchar_t>(1)),
618 _CHECK_PTR(new ctype<wchar_t>(1)),
619
620 # ifndef _STLP_NO_MBSTATE_T
621 _CHECK_PTR(new codecvt<wchar_t, char, mbstate_t>(1)),
622 # else
623 0,
624 # endif
625 _CHECK_PTR(new moneypunct<wchar_t, true>(1)),
626 _CHECK_PTR(new moneypunct<wchar_t, false>(1)),
627 _CHECK_PTR(new numpunct<wchar_t>(1)),
628 _CHECK_PTR(new messages<wchar_t>(new _STLP_PRIV _Messages())),
629
630 _CHECK_PTR(new money_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1)),
631 0,
632 _CHECK_PTR(new money_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1)),
633 0,
634
635 _CHECK_PTR(new num_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1)),
636 0,
637 _CHECK_PTR(new num_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1)),
638 0,
639 _CHECK_PTR(new time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >(1)),
640 0,
641 _CHECK_PTR(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
_get_Locale_impl(_Locale_impl * loc)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
_release_Locale_impl(_Locale_impl * & loc)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
_copy_Nameless_Locale_impl(_Locale_impl * loc)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 = _CHECK_PTR(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
852