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 31static const string _Nameless("*"); 32 33static inline bool is_C_locale_name (const char* name) 34{ return ((name[0] == 'C') && (name[1] == 0)); } 35 36locale::facet * _STLP_CALL _get_facet(locale::facet *f) 37{ 38 if (f != 0) 39 f->_M_incr(); 40 return f; 41} 42 43void _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 51size_t locale::id::_S_max = 27; 52 53static void _Stl_loc_assign_ids(); 54 55static _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.) 100void _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. 108void _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. 116void _STLP_CALL _Locale_impl::_M_throw_bad_cast() { 117 _STLP_THROW(bad_cast()); 118} 119 120void _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 126locale::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 569static 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. 595static locale *_Stl_classic_locale = 0; 596static locale *_Stl_global_locale = 0; 597 598locale* _Stl_get_classic_locale() { 599 static _Locale_impl::Init init; 600 return _Stl_classic_locale; 601} 602 603locale* _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 621static ios_base::Init _IosInit; 622 623void _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 677locale::id collate<char>::id = { 1 }; 678locale::id ctype<char>::id = { 2 }; 679locale::id codecvt<char, char, mbstate_t>::id = { 3 }; 680locale::id moneypunct<char, true>::id = { 4 }; 681locale::id moneypunct<char, false>::id = { 5 }; 682locale::id numpunct<char>::id = { 6 } ; 683locale::id messages<char>::id = { 7 }; 684 685#ifndef _STLP_NO_WCHAR_T 686locale::id collate<wchar_t>::id = { 14 }; 687locale::id ctype<wchar_t>::id = { 15 }; 688locale::id codecvt<wchar_t, char, mbstate_t>::id = { 16 }; 689locale::id moneypunct<wchar_t, true>::id = { 17 } ; 690locale::id moneypunct<wchar_t, false>::id = { 18 } ; 691locale::id numpunct<wchar_t>::id = { 19 }; 692locale::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 702void _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