1*38fd1498Szrj // Copyright (C) 1997-2018 Free Software Foundation, Inc. 2*38fd1498Szrj // 3*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 4*38fd1498Szrj // software; you can redistribute it and/or modify it under the 5*38fd1498Szrj // terms of the GNU General Public License as published by the 6*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 7*38fd1498Szrj // any later version. 8*38fd1498Szrj 9*38fd1498Szrj // This library is distributed in the hope that it will be useful, 10*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 11*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*38fd1498Szrj // GNU General Public License for more details. 13*38fd1498Szrj 14*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 15*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 16*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 17*38fd1498Szrj 18*38fd1498Szrj // You should have received a copy of the GNU General Public License and 19*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 20*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 21*38fd1498Szrj // <http://www.gnu.org/licenses/>. 22*38fd1498Szrj 23*38fd1498Szrj #define _GLIBCXX_USE_CXX11_ABI 1 24*38fd1498Szrj #include <clocale> 25*38fd1498Szrj #include <cstring> 26*38fd1498Szrj #include <cstdlib> // For free. 27*38fd1498Szrj #include <cctype> 28*38fd1498Szrj #include <cwctype> // For towupper, etc. 29*38fd1498Szrj #include <locale> 30*38fd1498Szrj #include <ext/concurrence.h> 31*38fd1498Szrj 32*38fd1498Szrj #if _GLIBCXX_USE_DUAL_ABI 33*38fd1498Szrj // This file is compiled with the new std::string ABI so std::numpunct<char> 34*38fd1498Szrj // refers to std::__cxx11::numpunct<char>. These declarations let us refer 35*38fd1498Szrj // to the other facets instantiated with the old ABI. 36*38fd1498Szrj # define _GLIBCXX_LOC_ID(mangled) extern std::locale::id mangled 37*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt8numpunctIcE2idE); 38*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt7collateIcE2idE); 39*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE); 40*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE); 41*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE); 42*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt10moneypunctIcLb0EE2idE); 43*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt10moneypunctIcLb1EE2idE); 44*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt8messagesIcE2idE); 45*38fd1498Szrj # ifdef _GLIBCXX_USE_WCHAR_T 46*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt8numpunctIwE2idE); 47*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt7collateIwE2idE); 48*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE); 49*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE); 50*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE); 51*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt10moneypunctIwLb0EE2idE); 52*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt10moneypunctIwLb1EE2idE); 53*38fd1498Szrj _GLIBCXX_LOC_ID(_ZNSt8messagesIwE2idE); 54*38fd1498Szrj # endif 55*38fd1498Szrj #endif 56*38fd1498Szrj 57*38fd1498Szrj 58*38fd1498Szrj namespace 59*38fd1498Szrj { 60*38fd1498Szrj const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS 61*38fd1498Szrj + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0); 62*38fd1498Szrj 63*38fd1498Szrj __gnu_cxx::__mutex& get_locale_mutex()64*38fd1498Szrj get_locale_mutex() 65*38fd1498Szrj { 66*38fd1498Szrj static __gnu_cxx::__mutex locale_mutex; 67*38fd1498Szrj return locale_mutex; 68*38fd1498Szrj } 69*38fd1498Szrj 70*38fd1498Szrj using namespace std; 71*38fd1498Szrj 72*38fd1498Szrj typedef char fake_locale_Impl[sizeof(locale::_Impl)] 73*38fd1498Szrj __attribute__ ((aligned(__alignof__(locale::_Impl)))); 74*38fd1498Szrj fake_locale_Impl c_locale_impl; 75*38fd1498Szrj 76*38fd1498Szrj typedef char fake_locale[sizeof(locale)] 77*38fd1498Szrj __attribute__ ((aligned(__alignof__(locale)))); 78*38fd1498Szrj fake_locale c_locale; 79*38fd1498Szrj 80*38fd1498Szrj typedef char fake_name_vec[sizeof(char*)] 81*38fd1498Szrj __attribute__ ((aligned(__alignof__(char*)))); 82*38fd1498Szrj fake_name_vec name_vec[6 + _GLIBCXX_NUM_CATEGORIES]; 83*38fd1498Szrj 84*38fd1498Szrj typedef char fake_names[sizeof(char[2])] 85*38fd1498Szrj __attribute__ ((aligned(__alignof__(char[2])))); 86*38fd1498Szrj fake_names name_c[6 + _GLIBCXX_NUM_CATEGORIES]; 87*38fd1498Szrj 88*38fd1498Szrj typedef char fake_facet_vec[sizeof(locale::facet*)] 89*38fd1498Szrj __attribute__ ((aligned(__alignof__(locale::facet*)))); 90*38fd1498Szrj fake_facet_vec facet_vec[num_facets]; 91*38fd1498Szrj 92*38fd1498Szrj typedef char fake_cache_vec[sizeof(locale::facet*)] 93*38fd1498Szrj __attribute__ ((aligned(__alignof__(locale::facet*)))); 94*38fd1498Szrj fake_cache_vec cache_vec[num_facets]; 95*38fd1498Szrj 96*38fd1498Szrj typedef char fake_ctype_c[sizeof(std::ctype<char>)] 97*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::ctype<char>)))); 98*38fd1498Szrj fake_ctype_c ctype_c; 99*38fd1498Szrj 100*38fd1498Szrj typedef char fake_collate_c[sizeof(std::collate<char>)] 101*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::collate<char>)))); 102*38fd1498Szrj fake_collate_c collate_c; 103*38fd1498Szrj 104*38fd1498Szrj typedef char fake_numpunct_c[sizeof(numpunct<char>)] 105*38fd1498Szrj __attribute__ ((aligned(__alignof__(numpunct<char>)))); 106*38fd1498Szrj fake_numpunct_c numpunct_c; 107*38fd1498Szrj 108*38fd1498Szrj typedef char fake_num_get_c[sizeof(num_get<char>)] 109*38fd1498Szrj __attribute__ ((aligned(__alignof__(num_get<char>)))); 110*38fd1498Szrj fake_num_get_c num_get_c; 111*38fd1498Szrj 112*38fd1498Szrj typedef char fake_num_put_c[sizeof(num_put<char>)] 113*38fd1498Szrj __attribute__ ((aligned(__alignof__(num_put<char>)))); 114*38fd1498Szrj fake_num_put_c num_put_c; 115*38fd1498Szrj 116*38fd1498Szrj typedef char fake_codecvt_c[sizeof(codecvt<char, char, mbstate_t>)] 117*38fd1498Szrj __attribute__ ((aligned(__alignof__(codecvt<char, char, mbstate_t>)))); 118*38fd1498Szrj fake_codecvt_c codecvt_c; 119*38fd1498Szrj 120*38fd1498Szrj typedef char fake_moneypunct_c[sizeof(moneypunct<char, true>)] 121*38fd1498Szrj __attribute__ ((aligned(__alignof__(moneypunct<char, true>)))); 122*38fd1498Szrj fake_moneypunct_c moneypunct_ct; 123*38fd1498Szrj fake_moneypunct_c moneypunct_cf; 124*38fd1498Szrj 125*38fd1498Szrj typedef char fake_money_get_c[sizeof(money_get<char>)] 126*38fd1498Szrj __attribute__ ((aligned(__alignof__(money_get<char>)))); 127*38fd1498Szrj fake_money_get_c money_get_c; 128*38fd1498Szrj 129*38fd1498Szrj typedef char fake_money_put_c[sizeof(money_put<char>)] 130*38fd1498Szrj __attribute__ ((aligned(__alignof__(money_put<char>)))); 131*38fd1498Szrj fake_money_put_c money_put_c; 132*38fd1498Szrj 133*38fd1498Szrj typedef char fake_timepunct_c[sizeof(__timepunct<char>)] 134*38fd1498Szrj __attribute__ ((aligned(__alignof__(__timepunct<char>)))); 135*38fd1498Szrj fake_timepunct_c timepunct_c; 136*38fd1498Szrj 137*38fd1498Szrj typedef char fake_time_get_c[sizeof(time_get<char>)] 138*38fd1498Szrj __attribute__ ((aligned(__alignof__(time_get<char>)))); 139*38fd1498Szrj fake_time_get_c time_get_c; 140*38fd1498Szrj 141*38fd1498Szrj typedef char fake_time_put_c[sizeof(time_put<char>)] 142*38fd1498Szrj __attribute__ ((aligned(__alignof__(time_put<char>)))); 143*38fd1498Szrj fake_time_put_c time_put_c; 144*38fd1498Szrj 145*38fd1498Szrj typedef char fake_messages_c[sizeof(messages<char>)] 146*38fd1498Szrj __attribute__ ((aligned(__alignof__(messages<char>)))); 147*38fd1498Szrj fake_messages_c messages_c; 148*38fd1498Szrj 149*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 150*38fd1498Szrj typedef char fake_wtype_w[sizeof(std::ctype<wchar_t>)] 151*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::ctype<wchar_t>)))); 152*38fd1498Szrj fake_wtype_w ctype_w; 153*38fd1498Szrj 154*38fd1498Szrj typedef char fake_wollate_w[sizeof(std::collate<wchar_t>)] 155*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::collate<wchar_t>)))); 156*38fd1498Szrj fake_wollate_w collate_w; 157*38fd1498Szrj 158*38fd1498Szrj typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)] 159*38fd1498Szrj __attribute__ ((aligned(__alignof__(numpunct<wchar_t>)))); 160*38fd1498Szrj fake_numpunct_w numpunct_w; 161*38fd1498Szrj 162*38fd1498Szrj typedef char fake_num_get_w[sizeof(num_get<wchar_t>)] 163*38fd1498Szrj __attribute__ ((aligned(__alignof__(num_get<wchar_t>)))); 164*38fd1498Szrj fake_num_get_w num_get_w; 165*38fd1498Szrj 166*38fd1498Szrj typedef char fake_num_put_w[sizeof(num_put<wchar_t>)] 167*38fd1498Szrj __attribute__ ((aligned(__alignof__(num_put<wchar_t>)))); 168*38fd1498Szrj fake_num_put_w num_put_w; 169*38fd1498Szrj 170*38fd1498Szrj typedef char fake_wodecvt_w[sizeof(codecvt<wchar_t, char, mbstate_t>)] 171*38fd1498Szrj __attribute__ ((aligned(__alignof__(codecvt<wchar_t, char, mbstate_t>)))); 172*38fd1498Szrj fake_wodecvt_w codecvt_w; 173*38fd1498Szrj 174*38fd1498Szrj typedef char fake_moneypunct_w[sizeof(moneypunct<wchar_t, true>)] 175*38fd1498Szrj __attribute__ ((aligned(__alignof__(moneypunct<wchar_t, true>)))); 176*38fd1498Szrj fake_moneypunct_w moneypunct_wt; 177*38fd1498Szrj fake_moneypunct_w moneypunct_wf; 178*38fd1498Szrj 179*38fd1498Szrj typedef char fake_money_get_w[sizeof(money_get<wchar_t>)] 180*38fd1498Szrj __attribute__ ((aligned(__alignof__(money_get<wchar_t>)))); 181*38fd1498Szrj fake_money_get_w money_get_w; 182*38fd1498Szrj 183*38fd1498Szrj typedef char fake_money_put_w[sizeof(money_put<wchar_t>)] 184*38fd1498Szrj __attribute__ ((aligned(__alignof__(money_put<wchar_t>)))); 185*38fd1498Szrj fake_money_put_w money_put_w; 186*38fd1498Szrj 187*38fd1498Szrj typedef char fake_timepunct_w[sizeof(__timepunct<wchar_t>)] 188*38fd1498Szrj __attribute__ ((aligned(__alignof__(__timepunct<wchar_t>)))); 189*38fd1498Szrj fake_timepunct_w timepunct_w; 190*38fd1498Szrj 191*38fd1498Szrj typedef char fake_time_get_w[sizeof(time_get<wchar_t>)] 192*38fd1498Szrj __attribute__ ((aligned(__alignof__(time_get<wchar_t>)))); 193*38fd1498Szrj fake_time_get_w time_get_w; 194*38fd1498Szrj 195*38fd1498Szrj typedef char fake_time_put_w[sizeof(time_put<wchar_t>)] 196*38fd1498Szrj __attribute__ ((aligned(__alignof__(time_put<wchar_t>)))); 197*38fd1498Szrj fake_time_put_w time_put_w; 198*38fd1498Szrj 199*38fd1498Szrj typedef char fake_messages_w[sizeof(messages<wchar_t>)] 200*38fd1498Szrj __attribute__ ((aligned(__alignof__(messages<wchar_t>)))); 201*38fd1498Szrj fake_messages_w messages_w; 202*38fd1498Szrj #endif 203*38fd1498Szrj 204*38fd1498Szrj #ifdef _GLIBCXX_USE_C99_STDINT_TR1 205*38fd1498Szrj typedef char fake_codecvt_c16[sizeof(codecvt<char16_t, char, mbstate_t>)] 206*38fd1498Szrj __attribute__ ((aligned(__alignof__(codecvt<char16_t, char, mbstate_t>)))); 207*38fd1498Szrj fake_codecvt_c16 codecvt_c16; 208*38fd1498Szrj 209*38fd1498Szrj typedef char fake_codecvt_c32[sizeof(codecvt<char32_t, char, mbstate_t>)] 210*38fd1498Szrj __attribute__ ((aligned(__alignof__(codecvt<char32_t, char, mbstate_t>)))); 211*38fd1498Szrj fake_codecvt_c32 codecvt_c32; 212*38fd1498Szrj #endif 213*38fd1498Szrj 214*38fd1498Szrj // Storage for "C" locale caches. 215*38fd1498Szrj typedef char fake_num_cache_c[sizeof(std::__numpunct_cache<char>)] 216*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::__numpunct_cache<char>)))); 217*38fd1498Szrj fake_num_cache_c numpunct_cache_c; 218*38fd1498Szrj 219*38fd1498Szrj typedef char fake_money_cache_c[sizeof(std::__moneypunct_cache<char, true>)] 220*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::__moneypunct_cache<char, true>)))); 221*38fd1498Szrj fake_money_cache_c moneypunct_cache_ct; 222*38fd1498Szrj fake_money_cache_c moneypunct_cache_cf; 223*38fd1498Szrj 224*38fd1498Szrj typedef char fake_time_cache_c[sizeof(std::__timepunct_cache<char>)] 225*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::__timepunct_cache<char>)))); 226*38fd1498Szrj fake_time_cache_c timepunct_cache_c; 227*38fd1498Szrj 228*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 229*38fd1498Szrj typedef char fake_num_cache_w[sizeof(std::__numpunct_cache<wchar_t>)] 230*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::__numpunct_cache<wchar_t>)))); 231*38fd1498Szrj fake_num_cache_w numpunct_cache_w; 232*38fd1498Szrj 233*38fd1498Szrj typedef char fake_money_cache_w[sizeof(std::__moneypunct_cache<wchar_t,true>)] 234*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::__moneypunct_cache<wchar_t,true>)))); 235*38fd1498Szrj fake_money_cache_w moneypunct_cache_wt; 236*38fd1498Szrj fake_money_cache_w moneypunct_cache_wf; 237*38fd1498Szrj 238*38fd1498Szrj typedef char fake_time_cache_w[sizeof(std::__timepunct_cache<wchar_t>)] 239*38fd1498Szrj __attribute__ ((aligned(__alignof__(std::__timepunct_cache<wchar_t>)))); 240*38fd1498Szrj fake_time_cache_w timepunct_cache_w; 241*38fd1498Szrj #endif 242*38fd1498Szrj } // anonymous namespace 243*38fd1498Szrj 244*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 245*38fd1498Szrj { 246*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 247*38fd1498Szrj locale()248*38fd1498Szrj locale::locale() throw() : _M_impl(0) 249*38fd1498Szrj { 250*38fd1498Szrj _S_initialize(); 251*38fd1498Szrj 252*38fd1498Szrj // Checked locking to optimize the common case where _S_global 253*38fd1498Szrj // still points to _S_classic (locale::_S_initialize_once()): 254*38fd1498Szrj // - If they are the same, just increment the reference count and 255*38fd1498Szrj // we are done. This effectively constructs a C locale object 256*38fd1498Szrj // identical to the static c_locale. 257*38fd1498Szrj // - Otherwise, _S_global can and may be destroyed due to 258*38fd1498Szrj // locale::global() call on another thread, in which case we 259*38fd1498Szrj // fall back to lock protected access to both _S_global and 260*38fd1498Szrj // its reference count. 261*38fd1498Szrj _M_impl = _S_global; 262*38fd1498Szrj if (_M_impl == _S_classic) 263*38fd1498Szrj _M_impl->_M_add_reference(); 264*38fd1498Szrj else 265*38fd1498Szrj { 266*38fd1498Szrj __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); 267*38fd1498Szrj _S_global->_M_add_reference(); 268*38fd1498Szrj _M_impl = _S_global; 269*38fd1498Szrj } 270*38fd1498Szrj } 271*38fd1498Szrj 272*38fd1498Szrj locale global(const locale & __other)273*38fd1498Szrj locale::global(const locale& __other) 274*38fd1498Szrj { 275*38fd1498Szrj _S_initialize(); 276*38fd1498Szrj _Impl* __old; 277*38fd1498Szrj { 278*38fd1498Szrj __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); 279*38fd1498Szrj __old = _S_global; 280*38fd1498Szrj __other._M_impl->_M_add_reference(); 281*38fd1498Szrj _S_global = __other._M_impl; 282*38fd1498Szrj const string __other_name = __other.name(); 283*38fd1498Szrj if (__other_name != "*") 284*38fd1498Szrj setlocale(LC_ALL, __other_name.c_str()); 285*38fd1498Szrj } 286*38fd1498Szrj 287*38fd1498Szrj // Reference count sanity check: one reference removed for the 288*38fd1498Szrj // subsition of __other locale, one added by return-by-value. Net 289*38fd1498Szrj // difference: zero. When the returned locale object's destrutor 290*38fd1498Szrj // is called, then the reference count is decremented and possibly 291*38fd1498Szrj // destroyed. 292*38fd1498Szrj return locale(__old); 293*38fd1498Szrj } 294*38fd1498Szrj 295*38fd1498Szrj const locale& classic()296*38fd1498Szrj locale::classic() 297*38fd1498Szrj { 298*38fd1498Szrj _S_initialize(); 299*38fd1498Szrj return *(new (&c_locale) locale(_S_classic)); 300*38fd1498Szrj } 301*38fd1498Szrj 302*38fd1498Szrj void _S_initialize_once()303*38fd1498Szrj locale::_S_initialize_once() throw() 304*38fd1498Szrj { 305*38fd1498Szrj // 2 references. 306*38fd1498Szrj // One reference for _S_classic, one for _S_global 307*38fd1498Szrj _S_classic = new (&c_locale_impl) _Impl(2); 308*38fd1498Szrj _S_global = _S_classic; 309*38fd1498Szrj } 310*38fd1498Szrj 311*38fd1498Szrj void _S_initialize()312*38fd1498Szrj locale::_S_initialize() 313*38fd1498Szrj { 314*38fd1498Szrj #ifdef __GTHREADS 315*38fd1498Szrj if (__gthread_active_p()) 316*38fd1498Szrj __gthread_once(&_S_once, _S_initialize_once); 317*38fd1498Szrj #endif 318*38fd1498Szrj if (!_S_classic) 319*38fd1498Szrj _S_initialize_once(); 320*38fd1498Szrj } 321*38fd1498Szrj 322*38fd1498Szrj // Definitions for static const data members of locale::_Impl 323*38fd1498Szrj const locale::id* const 324*38fd1498Szrj locale::_Impl::_S_id_ctype[] = 325*38fd1498Szrj { 326*38fd1498Szrj &std::ctype<char>::id, 327*38fd1498Szrj &codecvt<char, char, mbstate_t>::id, 328*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 329*38fd1498Szrj &std::ctype<wchar_t>::id, 330*38fd1498Szrj &codecvt<wchar_t, char, mbstate_t>::id, 331*38fd1498Szrj #endif 332*38fd1498Szrj #ifdef _GLIBCXX_USE_C99_STDINT_TR1 333*38fd1498Szrj &codecvt<char16_t, char, mbstate_t>::id, 334*38fd1498Szrj &codecvt<char32_t, char, mbstate_t>::id, 335*38fd1498Szrj #endif 336*38fd1498Szrj 0 337*38fd1498Szrj }; 338*38fd1498Szrj 339*38fd1498Szrj const locale::id* const 340*38fd1498Szrj locale::_Impl::_S_id_numeric[] = 341*38fd1498Szrj { 342*38fd1498Szrj &num_get<char>::id, 343*38fd1498Szrj &num_put<char>::id, 344*38fd1498Szrj &numpunct<char>::id, 345*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 346*38fd1498Szrj &num_get<wchar_t>::id, 347*38fd1498Szrj &num_put<wchar_t>::id, 348*38fd1498Szrj &numpunct<wchar_t>::id, 349*38fd1498Szrj #endif 350*38fd1498Szrj 0 351*38fd1498Szrj }; 352*38fd1498Szrj 353*38fd1498Szrj const locale::id* const 354*38fd1498Szrj locale::_Impl::_S_id_collate[] = 355*38fd1498Szrj { 356*38fd1498Szrj &std::collate<char>::id, 357*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 358*38fd1498Szrj &std::collate<wchar_t>::id, 359*38fd1498Szrj #endif 360*38fd1498Szrj 0 361*38fd1498Szrj }; 362*38fd1498Szrj 363*38fd1498Szrj const locale::id* const 364*38fd1498Szrj locale::_Impl::_S_id_time[] = 365*38fd1498Szrj { 366*38fd1498Szrj &__timepunct<char>::id, 367*38fd1498Szrj &time_get<char>::id, 368*38fd1498Szrj &time_put<char>::id, 369*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 370*38fd1498Szrj &__timepunct<wchar_t>::id, 371*38fd1498Szrj &time_get<wchar_t>::id, 372*38fd1498Szrj &time_put<wchar_t>::id, 373*38fd1498Szrj #endif 374*38fd1498Szrj 0 375*38fd1498Szrj }; 376*38fd1498Szrj 377*38fd1498Szrj const locale::id* const 378*38fd1498Szrj locale::_Impl::_S_id_monetary[] = 379*38fd1498Szrj { 380*38fd1498Szrj &money_get<char>::id, 381*38fd1498Szrj &money_put<char>::id, 382*38fd1498Szrj &moneypunct<char, false>::id, 383*38fd1498Szrj &moneypunct<char, true >::id, 384*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 385*38fd1498Szrj &money_get<wchar_t>::id, 386*38fd1498Szrj &money_put<wchar_t>::id, 387*38fd1498Szrj &moneypunct<wchar_t, false>::id, 388*38fd1498Szrj &moneypunct<wchar_t, true >::id, 389*38fd1498Szrj #endif 390*38fd1498Szrj 0 391*38fd1498Szrj }; 392*38fd1498Szrj 393*38fd1498Szrj const locale::id* const 394*38fd1498Szrj locale::_Impl::_S_id_messages[] = 395*38fd1498Szrj { 396*38fd1498Szrj &std::messages<char>::id, 397*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 398*38fd1498Szrj &std::messages<wchar_t>::id, 399*38fd1498Szrj #endif 400*38fd1498Szrj 0 401*38fd1498Szrj }; 402*38fd1498Szrj 403*38fd1498Szrj const locale::id* const* const 404*38fd1498Szrj locale::_Impl::_S_facet_categories[] = 405*38fd1498Szrj { 406*38fd1498Szrj // Order must match the decl order in class locale. 407*38fd1498Szrj locale::_Impl::_S_id_ctype, 408*38fd1498Szrj locale::_Impl::_S_id_numeric, 409*38fd1498Szrj locale::_Impl::_S_id_collate, 410*38fd1498Szrj locale::_Impl::_S_id_time, 411*38fd1498Szrj locale::_Impl::_S_id_monetary, 412*38fd1498Szrj locale::_Impl::_S_id_messages, 413*38fd1498Szrj 0 414*38fd1498Szrj }; 415*38fd1498Szrj 416*38fd1498Szrj #if _GLIBCXX_USE_DUAL_ABI 417*38fd1498Szrj // Facets that are instantiated for both the COW and SSO std::string ABIs. 418*38fd1498Szrj // The COW ABI version must come first, followed by its SSO twin. 419*38fd1498Szrj const locale::id* const locale::_S_twinned_facets[] = { 420*38fd1498Szrj &::_ZNSt8numpunctIcE2idE, 421*38fd1498Szrj &numpunct<char>::id, 422*38fd1498Szrj &::_ZNSt7collateIcE2idE, 423*38fd1498Szrj &std::collate<char>::id, 424*38fd1498Szrj &::_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE, 425*38fd1498Szrj &time_get<char>::id, 426*38fd1498Szrj &::_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE, 427*38fd1498Szrj &money_get<char>::id, 428*38fd1498Szrj &::_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE, 429*38fd1498Szrj &money_put<char>::id, 430*38fd1498Szrj &::_ZNSt10moneypunctIcLb0EE2idE, 431*38fd1498Szrj &moneypunct<char, false>::id, 432*38fd1498Szrj &::_ZNSt10moneypunctIcLb1EE2idE, 433*38fd1498Szrj &moneypunct<char, true >::id, 434*38fd1498Szrj &::_ZNSt8messagesIcE2idE, 435*38fd1498Szrj &std::messages<char>::id, 436*38fd1498Szrj # ifdef _GLIBCXX_USE_WCHAR_T 437*38fd1498Szrj &::_ZNSt8numpunctIwE2idE, 438*38fd1498Szrj &numpunct<wchar_t>::id, 439*38fd1498Szrj &::_ZNSt7collateIwE2idE, 440*38fd1498Szrj &std::collate<wchar_t>::id, 441*38fd1498Szrj &::_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE, 442*38fd1498Szrj &time_get<wchar_t>::id, 443*38fd1498Szrj &::_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE, 444*38fd1498Szrj &money_get<wchar_t>::id, 445*38fd1498Szrj &::_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE, 446*38fd1498Szrj &money_put<wchar_t>::id, 447*38fd1498Szrj &::_ZNSt10moneypunctIwLb0EE2idE, 448*38fd1498Szrj &moneypunct<wchar_t, false>::id, 449*38fd1498Szrj &::_ZNSt10moneypunctIwLb1EE2idE, 450*38fd1498Szrj &moneypunct<wchar_t, true >::id, 451*38fd1498Szrj &::_ZNSt8messagesIwE2idE, 452*38fd1498Szrj &std::messages<wchar_t>::id, 453*38fd1498Szrj # endif 454*38fd1498Szrj 0, 0 455*38fd1498Szrj }; 456*38fd1498Szrj #endif 457*38fd1498Szrj 458*38fd1498Szrj // Construct "C" _Impl. 459*38fd1498Szrj locale::_Impl:: _Impl(size_t __refs)460*38fd1498Szrj _Impl(size_t __refs) throw() 461*38fd1498Szrj : _M_refcount(__refs), _M_facets(0), _M_facets_size(num_facets), 462*38fd1498Szrj _M_caches(0), _M_names(0) 463*38fd1498Szrj { 464*38fd1498Szrj _M_facets = new (&facet_vec) const facet*[_M_facets_size](); 465*38fd1498Szrj _M_caches = new (&cache_vec) const facet*[_M_facets_size](); 466*38fd1498Szrj 467*38fd1498Szrj // Name the categories. 468*38fd1498Szrj _M_names = new (&name_vec) char*[_S_categories_size](); 469*38fd1498Szrj _M_names[0] = new (&name_c[0]) char[2]; 470*38fd1498Szrj std::memcpy(_M_names[0], locale::facet::_S_get_c_name(), 2); 471*38fd1498Szrj 472*38fd1498Szrj // This is needed as presently the C++ version of "C" locales 473*38fd1498Szrj // != data in the underlying locale model for __timepunct, 474*38fd1498Szrj // numpunct, and moneypunct. Also, the "C" locales must be 475*38fd1498Szrj // constructed in a way such that they are pre-allocated. 476*38fd1498Szrj // NB: Set locale::facets(ref) count to one so that each individual 477*38fd1498Szrj // facet is not destroyed when the locale (and thus locale::_Impl) is 478*38fd1498Szrj // destroyed. 479*38fd1498Szrj _M_init_facet(new (&ctype_c) std::ctype<char>(0, false, 1)); 480*38fd1498Szrj _M_init_facet(new (&codecvt_c) codecvt<char, char, mbstate_t>(1)); 481*38fd1498Szrj 482*38fd1498Szrj typedef __numpunct_cache<char> num_cache_c; 483*38fd1498Szrj num_cache_c* __npc = new (&numpunct_cache_c) num_cache_c(2); 484*38fd1498Szrj _M_init_facet(new (&numpunct_c) numpunct<char>(__npc, 1)); 485*38fd1498Szrj 486*38fd1498Szrj _M_init_facet(new (&num_get_c) num_get<char>(1)); 487*38fd1498Szrj _M_init_facet(new (&num_put_c) num_put<char>(1)); 488*38fd1498Szrj _M_init_facet(new (&collate_c) std::collate<char>(1)); 489*38fd1498Szrj 490*38fd1498Szrj typedef __moneypunct_cache<char, false> money_cache_cf; 491*38fd1498Szrj typedef __moneypunct_cache<char, true> money_cache_ct; 492*38fd1498Szrj money_cache_cf* __mpcf = new (&moneypunct_cache_cf) money_cache_cf(2); 493*38fd1498Szrj _M_init_facet(new (&moneypunct_cf) moneypunct<char, false>(__mpcf, 1)); 494*38fd1498Szrj money_cache_ct* __mpct = new (&moneypunct_cache_ct) money_cache_ct(2); 495*38fd1498Szrj _M_init_facet(new (&moneypunct_ct) moneypunct<char, true>(__mpct, 1)); 496*38fd1498Szrj 497*38fd1498Szrj _M_init_facet(new (&money_get_c) money_get<char>(1)); 498*38fd1498Szrj _M_init_facet(new (&money_put_c) money_put<char>(1)); 499*38fd1498Szrj 500*38fd1498Szrj typedef __timepunct_cache<char> time_cache_c; 501*38fd1498Szrj time_cache_c* __tpc = new (&timepunct_cache_c) time_cache_c(2); 502*38fd1498Szrj _M_init_facet(new (&timepunct_c) __timepunct<char>(__tpc, 1)); 503*38fd1498Szrj 504*38fd1498Szrj _M_init_facet(new (&time_get_c) time_get<char>(1)); 505*38fd1498Szrj _M_init_facet(new (&time_put_c) time_put<char>(1)); 506*38fd1498Szrj _M_init_facet(new (&messages_c) std::messages<char>(1)); 507*38fd1498Szrj 508*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 509*38fd1498Szrj _M_init_facet(new (&ctype_w) std::ctype<wchar_t>(1)); 510*38fd1498Szrj _M_init_facet(new (&codecvt_w) codecvt<wchar_t, char, mbstate_t>(1)); 511*38fd1498Szrj 512*38fd1498Szrj typedef __numpunct_cache<wchar_t> num_cache_w; 513*38fd1498Szrj num_cache_w* __npw = new (&numpunct_cache_w) num_cache_w(2); 514*38fd1498Szrj _M_init_facet(new (&numpunct_w) numpunct<wchar_t>(__npw, 1)); 515*38fd1498Szrj 516*38fd1498Szrj _M_init_facet(new (&num_get_w) num_get<wchar_t>(1)); 517*38fd1498Szrj _M_init_facet(new (&num_put_w) num_put<wchar_t>(1)); 518*38fd1498Szrj _M_init_facet(new (&collate_w) std::collate<wchar_t>(1)); 519*38fd1498Szrj 520*38fd1498Szrj typedef __moneypunct_cache<wchar_t, false> money_cache_wf; 521*38fd1498Szrj typedef __moneypunct_cache<wchar_t, true> money_cache_wt; 522*38fd1498Szrj money_cache_wf* __mpwf = new (&moneypunct_cache_wf) money_cache_wf(2); 523*38fd1498Szrj _M_init_facet(new (&moneypunct_wf) moneypunct<wchar_t, false>(__mpwf, 1)); 524*38fd1498Szrj money_cache_wt* __mpwt = new (&moneypunct_cache_wt) money_cache_wt(2); 525*38fd1498Szrj _M_init_facet(new (&moneypunct_wt) moneypunct<wchar_t, true>(__mpwt, 1)); 526*38fd1498Szrj 527*38fd1498Szrj _M_init_facet(new (&money_get_w) money_get<wchar_t>(1)); 528*38fd1498Szrj _M_init_facet(new (&money_put_w) money_put<wchar_t>(1)); 529*38fd1498Szrj 530*38fd1498Szrj typedef __timepunct_cache<wchar_t> time_cache_w; 531*38fd1498Szrj time_cache_w* __tpw = new (&timepunct_cache_w) time_cache_w(2); 532*38fd1498Szrj _M_init_facet(new (&timepunct_w) __timepunct<wchar_t>(__tpw, 1)); 533*38fd1498Szrj 534*38fd1498Szrj _M_init_facet(new (&time_get_w) time_get<wchar_t>(1)); 535*38fd1498Szrj _M_init_facet(new (&time_put_w) time_put<wchar_t>(1)); 536*38fd1498Szrj _M_init_facet(new (&messages_w) std::messages<wchar_t>(1)); 537*38fd1498Szrj #endif 538*38fd1498Szrj 539*38fd1498Szrj #ifdef _GLIBCXX_USE_C99_STDINT_TR1 540*38fd1498Szrj _M_init_facet(new (&codecvt_c16) codecvt<char16_t, char, mbstate_t>(1)); 541*38fd1498Szrj _M_init_facet(new (&codecvt_c32) codecvt<char32_t, char, mbstate_t>(1)); 542*38fd1498Szrj #endif 543*38fd1498Szrj 544*38fd1498Szrj #if _GLIBCXX_USE_DUAL_ABI 545*38fd1498Szrj facet* extra[] = { __npc, __mpcf, __mpct 546*38fd1498Szrj # ifdef _GLIBCXX_USE_WCHAR_T 547*38fd1498Szrj , __npw, __mpwf, __mpwt 548*38fd1498Szrj # endif 549*38fd1498Szrj }; 550*38fd1498Szrj 551*38fd1498Szrj _M_init_extra(extra); 552*38fd1498Szrj #endif 553*38fd1498Szrj 554*38fd1498Szrj // This locale is safe to pre-cache, after all the facets have 555*38fd1498Szrj // been created and installed. 556*38fd1498Szrj _M_caches[numpunct<char>::id._M_id()] = __npc; 557*38fd1498Szrj _M_caches[moneypunct<char, false>::id._M_id()] = __mpcf; 558*38fd1498Szrj _M_caches[moneypunct<char, true>::id._M_id()] = __mpct; 559*38fd1498Szrj _M_caches[__timepunct<char>::id._M_id()] = __tpc; 560*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 561*38fd1498Szrj _M_caches[numpunct<wchar_t>::id._M_id()] = __npw; 562*38fd1498Szrj _M_caches[moneypunct<wchar_t, false>::id._M_id()] = __mpwf; 563*38fd1498Szrj _M_caches[moneypunct<wchar_t, true>::id._M_id()] = __mpwt; 564*38fd1498Szrj _M_caches[__timepunct<wchar_t>::id._M_id()] = __tpw; 565*38fd1498Szrj #endif 566*38fd1498Szrj } 567*38fd1498Szrj 568*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 569*38fd1498Szrj } // namespace 570