1*38fd1498Szrj // Locale support -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2014-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj // 26*38fd1498Szrj // ISO C++ 14882: 22.1 Locales 27*38fd1498Szrj // 28*38fd1498Szrj 29*38fd1498Szrj // This file defines classes that behave like the standard predefined locale 30*38fd1498Szrj // facets (collate, money_get etc.) except that they forward all virtual 31*38fd1498Szrj // functions to another facet which uses a different std::string ABI, 32*38fd1498Szrj // converting between string types as needed. 33*38fd1498Szrj // When a user replaces one of the relevant facets the corresponding shim in 34*38fd1498Szrj // this file is used so that the replacement facet can be used (via the shim) 35*38fd1498Szrj // in code that uses the other std::string ABI from the replacing code. 36*38fd1498Szrj 37*38fd1498Szrj #ifndef _GLIBCXX_USE_CXX11_ABI 38*38fd1498Szrj # define _GLIBCXX_USE_CXX11_ABI 1 39*38fd1498Szrj #endif 40*38fd1498Szrj #include <locale> 41*38fd1498Szrj 42*38fd1498Szrj #if ! _GLIBCXX_USE_DUAL_ABI 43*38fd1498Szrj # error This file should not be compiled for this configuration. 44*38fd1498Szrj #endif 45*38fd1498Szrj 46*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 47*38fd1498Szrj { 48*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 49*38fd1498Szrj 50*38fd1498Szrj // Base class of facet shims, holds a reference to the underlying facet 51*38fd1498Szrj // that the shim forwards to. 52*38fd1498Szrj class locale::facet::__shim 53*38fd1498Szrj { 54*38fd1498Szrj public: _M_get() const55*38fd1498Szrj const facet* _M_get() const { return _M_facet; } 56*38fd1498Szrj 57*38fd1498Szrj __shim(const __shim&) = delete; 58*38fd1498Szrj __shim& operator=(const __shim&) = delete; 59*38fd1498Szrj 60*38fd1498Szrj protected: 61*38fd1498Szrj explicit __shim(const facet * __f)62*38fd1498Szrj __shim(const facet* __f) : _M_facet(__f) { __f->_M_add_reference(); } 63*38fd1498Szrj ~__shim()64*38fd1498Szrj ~__shim() { _M_facet->_M_remove_reference(); } 65*38fd1498Szrj 66*38fd1498Szrj private: 67*38fd1498Szrj const facet* _M_facet; 68*38fd1498Szrj }; 69*38fd1498Szrj 70*38fd1498Szrj namespace __facet_shims 71*38fd1498Szrj { 72*38fd1498Szrj namespace // unnamed 73*38fd1498Szrj { 74*38fd1498Szrj template<typename C> __destroy_string(void * p)75*38fd1498Szrj void __destroy_string(void* p) 76*38fd1498Szrj { 77*38fd1498Szrj static_cast<std::basic_string<C>*>(p)->~basic_string(); 78*38fd1498Szrj } 79*38fd1498Szrj } // namespace 80*38fd1498Szrj 81*38fd1498Szrj // Manages a buffer of uninitialized memory that can store a std::string 82*38fd1498Szrj // or std::wstring, using either ABI, and convert to the other ABI. 83*38fd1498Szrj class __any_string 84*38fd1498Szrj { 85*38fd1498Szrj struct __attribute__((may_alias)) __str_rep 86*38fd1498Szrj { 87*38fd1498Szrj union { 88*38fd1498Szrj const void* _M_p; 89*38fd1498Szrj char* _M_pc; 90*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 91*38fd1498Szrj wchar_t* _M_pwc; 92*38fd1498Szrj #endif 93*38fd1498Szrj }; 94*38fd1498Szrj size_t _M_len; 95*38fd1498Szrj char _M_unused[16]; 96*38fd1498Szrj operator const char*std::__facet_shims::__any_string::__str_rep97*38fd1498Szrj operator const char*() const { return _M_pc; } 98*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T operator const wchar_t*std::__facet_shims::__any_string::__str_rep99*38fd1498Szrj operator const wchar_t*() const { return _M_pwc; } 100*38fd1498Szrj #endif 101*38fd1498Szrj }; 102*38fd1498Szrj union { 103*38fd1498Szrj __str_rep _M_str; 104*38fd1498Szrj char _M_bytes[sizeof(__str_rep)]; 105*38fd1498Szrj }; 106*38fd1498Szrj using __dtor_func = void(*)(void*); 107*38fd1498Szrj __dtor_func _M_dtor = nullptr; 108*38fd1498Szrj 109*38fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI 110*38fd1498Szrj // SSO strings overlay the entire __str_rep structure. 111*38fd1498Szrj static_assert(sizeof(std::string) == sizeof(__str_rep), 112*38fd1498Szrj "std::string changed size!"); 113*38fd1498Szrj #else 114*38fd1498Szrj // COW strings overlay just the pointer, the length is stored manually. 115*38fd1498Szrj static_assert(sizeof(std::string) == sizeof(__str_rep::_M_p), 116*38fd1498Szrj "std::string changed size!"); 117*38fd1498Szrj #endif 118*38fd1498Szrj # ifdef _GLIBCXX_USE_WCHAR_T 119*38fd1498Szrj static_assert(sizeof(std::wstring) == sizeof(std::string), 120*38fd1498Szrj "std::wstring and std::string are different sizes!"); 121*38fd1498Szrj # endif 122*38fd1498Szrj 123*38fd1498Szrj public: 124*38fd1498Szrj __any_string() = default; ~__any_string()125*38fd1498Szrj ~__any_string() { if (_M_dtor) _M_dtor(_M_bytes); } 126*38fd1498Szrj 127*38fd1498Szrj __any_string(const __any_string&) = delete; 128*38fd1498Szrj __any_string& operator=(const __any_string&) = delete; 129*38fd1498Szrj 130*38fd1498Szrj // Store a string (and its length if needed) in the buffer and 131*38fd1498Szrj // set _M_dtor to the function that runs the right destructor. 132*38fd1498Szrj template<typename C> 133*38fd1498Szrj __any_string& operator =(const basic_string<C> & s)134*38fd1498Szrj operator=(const basic_string<C>& s) 135*38fd1498Szrj { 136*38fd1498Szrj if (_M_dtor) 137*38fd1498Szrj _M_dtor(_M_bytes); 138*38fd1498Szrj ::new(_M_bytes) basic_string<C>(s); 139*38fd1498Szrj #if ! _GLIBCXX_USE_CXX11_ABI 140*38fd1498Szrj _M_str._M_len = s.length(); 141*38fd1498Szrj #endif 142*38fd1498Szrj _M_dtor = __destroy_string<C>; 143*38fd1498Szrj return *this; 144*38fd1498Szrj } 145*38fd1498Szrj 146*38fd1498Szrj // Create a new string with a copy of the characters in the stored string. 147*38fd1498Szrj // The returned object will match the caller's string ABI, even when the 148*38fd1498Szrj // stored string doesn't. 149*38fd1498Szrj template<typename C> 150*38fd1498Szrj _GLIBCXX_DEFAULT_ABI_TAG operator basic_string<C>() const151*38fd1498Szrj operator basic_string<C>() const 152*38fd1498Szrj { 153*38fd1498Szrj if (!_M_dtor) 154*38fd1498Szrj __throw_logic_error("uninitialized __any_string"); 155*38fd1498Szrj return basic_string<C>(static_cast<const C*>(_M_str), _M_str._M_len); 156*38fd1498Szrj } 157*38fd1498Szrj }; 158*38fd1498Szrj 159*38fd1498Szrj // This file is compiled twice, with and without this macro defined. 160*38fd1498Szrj // Define tag types to distinguish between the two cases and to allow 161*38fd1498Szrj // overloading on the tag. 162*38fd1498Szrj using current_abi = __bool_constant<_GLIBCXX_USE_CXX11_ABI>; 163*38fd1498Szrj using other_abi = __bool_constant<!_GLIBCXX_USE_CXX11_ABI>; 164*38fd1498Szrj 165*38fd1498Szrj using facet = locale::facet; 166*38fd1498Szrj 167*38fd1498Szrj // Declare the functions that shims defined in this file will call to 168*38fd1498Szrj // perform work in the context of the other ABI. 169*38fd1498Szrj // These will be defined when this file is recompiled for the other ABI 170*38fd1498Szrj // (at which point what is now "current_abi" will become "other_abi"). 171*38fd1498Szrj 172*38fd1498Szrj template<typename C> 173*38fd1498Szrj void 174*38fd1498Szrj __numpunct_fill_cache(other_abi, const facet*, __numpunct_cache<C>*); 175*38fd1498Szrj 176*38fd1498Szrj template<typename C> 177*38fd1498Szrj int 178*38fd1498Szrj __collate_compare(other_abi, const facet*, const C*, const C*, 179*38fd1498Szrj const C*, const C*); 180*38fd1498Szrj 181*38fd1498Szrj template<typename C> 182*38fd1498Szrj void 183*38fd1498Szrj __collate_transform(other_abi, const facet*, __any_string&, 184*38fd1498Szrj const C*, const C*); 185*38fd1498Szrj 186*38fd1498Szrj template<typename C> 187*38fd1498Szrj time_base::dateorder 188*38fd1498Szrj __time_get_dateorder(other_abi, const facet* f); 189*38fd1498Szrj 190*38fd1498Szrj template<typename C> 191*38fd1498Szrj istreambuf_iterator<C> 192*38fd1498Szrj __time_get(other_abi, const facet* f, 193*38fd1498Szrj istreambuf_iterator<C> beg, istreambuf_iterator<C> end, 194*38fd1498Szrj ios_base& io, ios_base::iostate& err, tm* t, char which); 195*38fd1498Szrj 196*38fd1498Szrj template<typename C, bool Intl> 197*38fd1498Szrj void 198*38fd1498Szrj __moneypunct_fill_cache(other_abi, const facet*, 199*38fd1498Szrj __moneypunct_cache<C, Intl>*); 200*38fd1498Szrj 201*38fd1498Szrj template<typename C> 202*38fd1498Szrj istreambuf_iterator<C> 203*38fd1498Szrj __money_get(other_abi, const facet*, 204*38fd1498Szrj istreambuf_iterator<C>, istreambuf_iterator<C>, 205*38fd1498Szrj bool, ios_base&, ios_base::iostate&, 206*38fd1498Szrj long double*, __any_string*); 207*38fd1498Szrj 208*38fd1498Szrj template<typename C> 209*38fd1498Szrj ostreambuf_iterator<C> 210*38fd1498Szrj __money_put(other_abi, const facet*, ostreambuf_iterator<C>, bool, 211*38fd1498Szrj ios_base&, C, long double, const __any_string*); 212*38fd1498Szrj 213*38fd1498Szrj template<typename C> 214*38fd1498Szrj messages_base::catalog 215*38fd1498Szrj __messages_open(other_abi, const facet*, const char*, size_t, 216*38fd1498Szrj const locale&); 217*38fd1498Szrj 218*38fd1498Szrj template<typename C> 219*38fd1498Szrj void 220*38fd1498Szrj __messages_get(other_abi, const facet*, __any_string&, 221*38fd1498Szrj messages_base::catalog, int, int, const C*, size_t); 222*38fd1498Szrj 223*38fd1498Szrj template<typename C> 224*38fd1498Szrj void 225*38fd1498Szrj __messages_close(other_abi, const facet*, messages_base::catalog); 226*38fd1498Szrj 227*38fd1498Szrj namespace // unnamed 228*38fd1498Szrj { 229*38fd1498Szrj struct __shim_accessor : facet 230*38fd1498Szrj { 231*38fd1498Szrj using facet::__shim; // Redeclare protected member as public. 232*38fd1498Szrj }; 233*38fd1498Szrj using __shim = __shim_accessor::__shim; 234*38fd1498Szrj 235*38fd1498Szrj template<typename _CharT> 236*38fd1498Szrj struct numpunct_shim : std::numpunct<_CharT>, __shim 237*38fd1498Szrj { 238*38fd1498Szrj typedef typename numpunct<_CharT>::__cache_type __cache_type; 239*38fd1498Szrj 240*38fd1498Szrj // f must point to a type derived from numpunct<C>[abi:other] numpunct_shimstd::__facet_shims::__anonc8a7b0500411::numpunct_shim241*38fd1498Szrj numpunct_shim(const facet* f, __cache_type* c = new __cache_type) 242*38fd1498Szrj : std::numpunct<_CharT>(c), __shim(f), _M_cache(c) 243*38fd1498Szrj { 244*38fd1498Szrj __numpunct_fill_cache(other_abi{}, f, c); 245*38fd1498Szrj } 246*38fd1498Szrj ~numpunct_shimstd::__facet_shims::__anonc8a7b0500411::numpunct_shim247*38fd1498Szrj ~numpunct_shim() 248*38fd1498Szrj { 249*38fd1498Szrj // Stop GNU locale's ~numpunct() from freeing the cached string. 250*38fd1498Szrj _M_cache->_M_grouping_size = 0; 251*38fd1498Szrj } 252*38fd1498Szrj 253*38fd1498Szrj // No need to override any virtual functions, the base definitions 254*38fd1498Szrj // will return the cached data. 255*38fd1498Szrj 256*38fd1498Szrj __cache_type* _M_cache; 257*38fd1498Szrj }; 258*38fd1498Szrj 259*38fd1498Szrj template<typename _CharT> 260*38fd1498Szrj struct collate_shim : std::collate<_CharT>, __shim 261*38fd1498Szrj { 262*38fd1498Szrj typedef basic_string<_CharT> string_type; 263*38fd1498Szrj 264*38fd1498Szrj // f must point to a type derived from collate<C>[abi:other] collate_shimstd::__facet_shims::__anonc8a7b0500411::collate_shim265*38fd1498Szrj collate_shim(const facet* f) : __shim(f) { } 266*38fd1498Szrj 267*38fd1498Szrj virtual int do_comparestd::__facet_shims::__anonc8a7b0500411::collate_shim268*38fd1498Szrj do_compare(const _CharT* lo1, const _CharT* hi1, 269*38fd1498Szrj const _CharT* lo2, const _CharT* hi2) const 270*38fd1498Szrj { 271*38fd1498Szrj return __collate_compare(other_abi{}, _M_get(), 272*38fd1498Szrj lo1, hi1, lo2, hi2); 273*38fd1498Szrj } 274*38fd1498Szrj 275*38fd1498Szrj virtual string_type do_transformstd::__facet_shims::__anonc8a7b0500411::collate_shim276*38fd1498Szrj do_transform(const _CharT* lo, const _CharT* hi) const 277*38fd1498Szrj { 278*38fd1498Szrj __any_string st; 279*38fd1498Szrj __collate_transform(other_abi{}, _M_get(), st, lo, hi); 280*38fd1498Szrj return st; 281*38fd1498Szrj } 282*38fd1498Szrj }; 283*38fd1498Szrj 284*38fd1498Szrj template<typename _CharT> 285*38fd1498Szrj struct time_get_shim : std::time_get<_CharT>, __shim 286*38fd1498Szrj { 287*38fd1498Szrj typedef typename std::time_get<_CharT>::iter_type iter_type; 288*38fd1498Szrj typedef typename std::time_get<_CharT>::char_type char_type; 289*38fd1498Szrj 290*38fd1498Szrj // f must point to a type derived from time_get<C>[abi:other] time_get_shimstd::__facet_shims::__anonc8a7b0500411::time_get_shim291*38fd1498Szrj time_get_shim(const facet* f) : __shim(f) { } 292*38fd1498Szrj 293*38fd1498Szrj virtual time_base::dateorder do_date_orderstd::__facet_shims::__anonc8a7b0500411::time_get_shim294*38fd1498Szrj do_date_order() const 295*38fd1498Szrj { return __time_get_dateorder<_CharT>(other_abi{}, _M_get()); } 296*38fd1498Szrj 297*38fd1498Szrj virtual iter_type do_get_timestd::__facet_shims::__anonc8a7b0500411::time_get_shim298*38fd1498Szrj do_get_time(iter_type beg, iter_type end, ios_base& io, 299*38fd1498Szrj ios_base::iostate& err, tm* t) const 300*38fd1498Szrj { 301*38fd1498Szrj return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, 302*38fd1498Szrj 't'); 303*38fd1498Szrj } 304*38fd1498Szrj 305*38fd1498Szrj virtual iter_type do_get_datestd::__facet_shims::__anonc8a7b0500411::time_get_shim306*38fd1498Szrj do_get_date(iter_type beg, iter_type end, ios_base& io, 307*38fd1498Szrj ios_base::iostate& err, tm* t) const 308*38fd1498Szrj { 309*38fd1498Szrj return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, 310*38fd1498Szrj 'd'); 311*38fd1498Szrj } 312*38fd1498Szrj 313*38fd1498Szrj virtual iter_type do_get_weekdaystd::__facet_shims::__anonc8a7b0500411::time_get_shim314*38fd1498Szrj do_get_weekday(iter_type beg, iter_type end, ios_base& io, 315*38fd1498Szrj ios_base::iostate& err, tm* t) const 316*38fd1498Szrj { 317*38fd1498Szrj return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, 318*38fd1498Szrj 'w'); 319*38fd1498Szrj } 320*38fd1498Szrj 321*38fd1498Szrj virtual iter_type do_get_monthnamestd::__facet_shims::__anonc8a7b0500411::time_get_shim322*38fd1498Szrj do_get_monthname(iter_type beg, iter_type end, ios_base& io, 323*38fd1498Szrj ios_base::iostate& err, tm* t) const 324*38fd1498Szrj { 325*38fd1498Szrj return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, 326*38fd1498Szrj 'm'); 327*38fd1498Szrj } 328*38fd1498Szrj 329*38fd1498Szrj virtual iter_type do_get_yearstd::__facet_shims::__anonc8a7b0500411::time_get_shim330*38fd1498Szrj do_get_year(iter_type beg, iter_type end, ios_base& io, 331*38fd1498Szrj ios_base::iostate& err, tm* t) const 332*38fd1498Szrj { 333*38fd1498Szrj return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, 334*38fd1498Szrj 'y'); 335*38fd1498Szrj } 336*38fd1498Szrj }; 337*38fd1498Szrj 338*38fd1498Szrj template<typename _CharT, bool _Intl> 339*38fd1498Szrj struct moneypunct_shim : std::moneypunct<_CharT, _Intl>, __shim 340*38fd1498Szrj { 341*38fd1498Szrj typedef typename moneypunct<_CharT, _Intl>::__cache_type __cache_type; 342*38fd1498Szrj 343*38fd1498Szrj // f must point to a type derived from moneypunct<C>[abi:other] moneypunct_shimstd::__facet_shims::__anonc8a7b0500411::moneypunct_shim344*38fd1498Szrj moneypunct_shim(const facet* f, __cache_type* c = new __cache_type) 345*38fd1498Szrj : std::moneypunct<_CharT, _Intl>(c), __shim(f), _M_cache(c) 346*38fd1498Szrj { 347*38fd1498Szrj __moneypunct_fill_cache(other_abi{}, f, c); 348*38fd1498Szrj } 349*38fd1498Szrj ~moneypunct_shimstd::__facet_shims::__anonc8a7b0500411::moneypunct_shim350*38fd1498Szrj ~moneypunct_shim() 351*38fd1498Szrj { 352*38fd1498Szrj // Stop GNU locale's ~moneypunct() from freeing the cached strings. 353*38fd1498Szrj _M_cache->_M_grouping_size = 0; 354*38fd1498Szrj _M_cache->_M_curr_symbol_size = 0; 355*38fd1498Szrj _M_cache->_M_positive_sign_size = 0; 356*38fd1498Szrj _M_cache->_M_negative_sign_size = 0; 357*38fd1498Szrj } 358*38fd1498Szrj 359*38fd1498Szrj // No need to override any virtual functions, the base definitions 360*38fd1498Szrj // will return the cached data. 361*38fd1498Szrj 362*38fd1498Szrj __cache_type* _M_cache; 363*38fd1498Szrj }; 364*38fd1498Szrj 365*38fd1498Szrj template<typename _CharT> 366*38fd1498Szrj struct money_get_shim : std::money_get<_CharT>, __shim 367*38fd1498Szrj { 368*38fd1498Szrj typedef typename std::money_get<_CharT>::iter_type iter_type; 369*38fd1498Szrj typedef typename std::money_get<_CharT>::char_type char_type; 370*38fd1498Szrj typedef typename std::money_get<_CharT>::string_type string_type; 371*38fd1498Szrj 372*38fd1498Szrj // f must point to a type derived from money_get<C>[abi:other] money_get_shimstd::__facet_shims::__anonc8a7b0500411::money_get_shim373*38fd1498Szrj money_get_shim(const facet* f) : __shim(f) { } 374*38fd1498Szrj 375*38fd1498Szrj virtual iter_type do_getstd::__facet_shims::__anonc8a7b0500411::money_get_shim376*38fd1498Szrj do_get(iter_type s, iter_type end, bool intl, ios_base& io, 377*38fd1498Szrj ios_base::iostate& err, long double& units) const 378*38fd1498Szrj { 379*38fd1498Szrj ios_base::iostate err2 = ios_base::goodbit; 380*38fd1498Szrj long double units2; 381*38fd1498Szrj s = __money_get(other_abi{}, _M_get(), s, end, intl, io, err2, 382*38fd1498Szrj &units2, nullptr); 383*38fd1498Szrj if (err2 == ios_base::goodbit) 384*38fd1498Szrj units = units2; 385*38fd1498Szrj else 386*38fd1498Szrj err = err2; 387*38fd1498Szrj return s; 388*38fd1498Szrj } 389*38fd1498Szrj 390*38fd1498Szrj virtual iter_type do_getstd::__facet_shims::__anonc8a7b0500411::money_get_shim391*38fd1498Szrj do_get(iter_type s, iter_type end, bool intl, ios_base& io, 392*38fd1498Szrj ios_base::iostate& err, string_type& digits) const 393*38fd1498Szrj { 394*38fd1498Szrj __any_string st; 395*38fd1498Szrj ios_base::iostate err2 = ios_base::goodbit; 396*38fd1498Szrj s = __money_get(other_abi{}, _M_get(), s, end, intl, io, err2, 397*38fd1498Szrj nullptr, &st); 398*38fd1498Szrj if (err2 == ios_base::goodbit) 399*38fd1498Szrj digits = st; 400*38fd1498Szrj else 401*38fd1498Szrj err = err2; 402*38fd1498Szrj return s; 403*38fd1498Szrj } 404*38fd1498Szrj }; 405*38fd1498Szrj 406*38fd1498Szrj template<typename _CharT> 407*38fd1498Szrj struct money_put_shim : std::money_put<_CharT>, __shim 408*38fd1498Szrj { 409*38fd1498Szrj typedef typename std::money_put<_CharT>::iter_type iter_type; 410*38fd1498Szrj typedef typename std::money_put<_CharT>::char_type char_type; 411*38fd1498Szrj typedef typename std::money_put<_CharT>::string_type string_type; 412*38fd1498Szrj 413*38fd1498Szrj // f must point to a type derived from money_put<C>[abi:other] money_put_shimstd::__facet_shims::__anonc8a7b0500411::money_put_shim414*38fd1498Szrj money_put_shim(const facet* f) : __shim(f) { } 415*38fd1498Szrj 416*38fd1498Szrj virtual iter_type do_putstd::__facet_shims::__anonc8a7b0500411::money_put_shim417*38fd1498Szrj do_put(iter_type s, bool intl, ios_base& io, 418*38fd1498Szrj char_type fill, long double units) const 419*38fd1498Szrj { 420*38fd1498Szrj return __money_put(other_abi{}, _M_get(), s, intl, io, fill, units, 421*38fd1498Szrj nullptr); 422*38fd1498Szrj } 423*38fd1498Szrj 424*38fd1498Szrj virtual iter_type do_putstd::__facet_shims::__anonc8a7b0500411::money_put_shim425*38fd1498Szrj do_put(iter_type s, bool intl, ios_base& io, 426*38fd1498Szrj char_type fill, const string_type& digits) const 427*38fd1498Szrj { 428*38fd1498Szrj __any_string st; 429*38fd1498Szrj st = digits; 430*38fd1498Szrj return __money_put(other_abi{}, _M_get(), s, intl, io, fill, 0.L, 431*38fd1498Szrj &st); 432*38fd1498Szrj } 433*38fd1498Szrj }; 434*38fd1498Szrj 435*38fd1498Szrj template<typename _CharT> 436*38fd1498Szrj struct messages_shim : std::messages<_CharT>, __shim 437*38fd1498Szrj { 438*38fd1498Szrj typedef messages_base::catalog catalog; 439*38fd1498Szrj typedef basic_string<_CharT> string_type; 440*38fd1498Szrj 441*38fd1498Szrj // f must point to a type derived from messages<C>[abi:other] messages_shimstd::__facet_shims::__anonc8a7b0500411::messages_shim442*38fd1498Szrj messages_shim(const facet* f) : __shim(f) { } 443*38fd1498Szrj 444*38fd1498Szrj virtual catalog do_openstd::__facet_shims::__anonc8a7b0500411::messages_shim445*38fd1498Szrj do_open(const basic_string<char>& s, const locale& l) const 446*38fd1498Szrj { 447*38fd1498Szrj return __messages_open<_CharT>(other_abi{}, _M_get(), 448*38fd1498Szrj s.c_str(), s.size(), l); 449*38fd1498Szrj } 450*38fd1498Szrj 451*38fd1498Szrj virtual string_type do_getstd::__facet_shims::__anonc8a7b0500411::messages_shim452*38fd1498Szrj do_get(catalog c, int set, int msgid, const string_type& dfault) const 453*38fd1498Szrj { 454*38fd1498Szrj __any_string st; 455*38fd1498Szrj __messages_get(other_abi{}, _M_get(), st, c, set, msgid, 456*38fd1498Szrj dfault.c_str(), dfault.size()); 457*38fd1498Szrj return st; 458*38fd1498Szrj } 459*38fd1498Szrj 460*38fd1498Szrj virtual void do_closestd::__facet_shims::__anonc8a7b0500411::messages_shim461*38fd1498Szrj do_close(catalog c) const 462*38fd1498Szrj { 463*38fd1498Szrj __messages_close<_CharT>(other_abi{}, _M_get(), c); 464*38fd1498Szrj } 465*38fd1498Szrj }; 466*38fd1498Szrj 467*38fd1498Szrj template class numpunct_shim<char>; 468*38fd1498Szrj template class collate_shim<char>; 469*38fd1498Szrj template class moneypunct_shim<char, true>; 470*38fd1498Szrj template class moneypunct_shim<char, false>; 471*38fd1498Szrj template class money_get_shim<char>; 472*38fd1498Szrj template class money_put_shim<char>; 473*38fd1498Szrj template class messages_shim<char>; 474*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 475*38fd1498Szrj template class numpunct_shim<wchar_t>; 476*38fd1498Szrj template class collate_shim<wchar_t>; 477*38fd1498Szrj template class moneypunct_shim<wchar_t, true>; 478*38fd1498Szrj template class moneypunct_shim<wchar_t, false>; 479*38fd1498Szrj template class money_get_shim<wchar_t>; 480*38fd1498Szrj template class money_put_shim<wchar_t>; 481*38fd1498Szrj template class messages_shim<wchar_t>; 482*38fd1498Szrj #endif 483*38fd1498Szrj 484*38fd1498Szrj template<typename C> 485*38fd1498Szrj inline size_t __copy(const C * & dest,const basic_string<C> & s)486*38fd1498Szrj __copy(const C*& dest, const basic_string<C>& s) 487*38fd1498Szrj { 488*38fd1498Szrj auto len = s.length(); 489*38fd1498Szrj C* p = new C[len+1]; 490*38fd1498Szrj s.copy(p, len); 491*38fd1498Szrj p[len] = '\0'; 492*38fd1498Szrj dest = p; 493*38fd1498Szrj return len; 494*38fd1498Szrj } 495*38fd1498Szrj 496*38fd1498Szrj } // namespace 497*38fd1498Szrj 498*38fd1498Szrj // Now define and instantiate the functions that will be called by the 499*38fd1498Szrj // shim facets defined when this file is recompiled for the other ABI. 500*38fd1498Szrj 501*38fd1498Szrj // Cache the values returned by the numpunct facet f. 502*38fd1498Szrj // Sets c->_M_allocated so that the __numpunct_cache destructor will 503*38fd1498Szrj // delete[] the strings allocated by this function. 504*38fd1498Szrj template<typename C> 505*38fd1498Szrj void __numpunct_fill_cache(current_abi,const facet * f,__numpunct_cache<C> * c)506*38fd1498Szrj __numpunct_fill_cache(current_abi, const facet* f, __numpunct_cache<C>* c) 507*38fd1498Szrj { 508*38fd1498Szrj auto* m = static_cast<const numpunct<C>*>(f); 509*38fd1498Szrj 510*38fd1498Szrj c->_M_decimal_point = m->decimal_point(); 511*38fd1498Szrj c->_M_thousands_sep = m->thousands_sep(); 512*38fd1498Szrj 513*38fd1498Szrj c->_M_grouping = nullptr; 514*38fd1498Szrj c->_M_truename = nullptr; 515*38fd1498Szrj c->_M_falsename = nullptr; 516*38fd1498Szrj // set _M_allocated so that if any allocation fails the previously 517*38fd1498Szrj // allocated strings will be deleted in ~__numpunct_cache() 518*38fd1498Szrj c->_M_allocated = true; 519*38fd1498Szrj 520*38fd1498Szrj c->_M_grouping_size = __copy(c->_M_grouping, m->grouping()); 521*38fd1498Szrj c->_M_truename_size = __copy(c->_M_truename, m->truename()); 522*38fd1498Szrj c->_M_falsename_size = __copy(c->_M_falsename, m->falsename()); 523*38fd1498Szrj } 524*38fd1498Szrj 525*38fd1498Szrj template void 526*38fd1498Szrj __numpunct_fill_cache(current_abi, const facet*, __numpunct_cache<char>*); 527*38fd1498Szrj 528*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 529*38fd1498Szrj template void 530*38fd1498Szrj __numpunct_fill_cache(current_abi, const facet*, __numpunct_cache<wchar_t>*); 531*38fd1498Szrj #endif 532*38fd1498Szrj 533*38fd1498Szrj template<typename C> 534*38fd1498Szrj int __collate_compare(current_abi,const facet * f,const C * lo1,const C * hi1,const C * lo2,const C * hi2)535*38fd1498Szrj __collate_compare(current_abi, const facet* f, const C* lo1, const C* hi1, 536*38fd1498Szrj const C* lo2, const C* hi2) 537*38fd1498Szrj { 538*38fd1498Szrj return static_cast<const collate<C>*>(f)->compare(lo1, hi1, lo2, hi2); 539*38fd1498Szrj } 540*38fd1498Szrj 541*38fd1498Szrj template int 542*38fd1498Szrj __collate_compare(current_abi, const facet*, const char*, const char*, 543*38fd1498Szrj const char*, const char*); 544*38fd1498Szrj 545*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 546*38fd1498Szrj template int 547*38fd1498Szrj __collate_compare(current_abi, const facet*, const wchar_t*, const wchar_t*, 548*38fd1498Szrj const wchar_t*, const wchar_t*); 549*38fd1498Szrj #endif 550*38fd1498Szrj 551*38fd1498Szrj template<typename C> 552*38fd1498Szrj void __collate_transform(current_abi,const facet * f,__any_string & st,const C * __lo,const C * __hi)553*38fd1498Szrj __collate_transform(current_abi, const facet* f, __any_string& st, 554*38fd1498Szrj const C* __lo, const C* __hi) 555*38fd1498Szrj { 556*38fd1498Szrj auto* c = static_cast<const collate<C>*>(f); 557*38fd1498Szrj st = c->transform(__lo, __hi); 558*38fd1498Szrj } 559*38fd1498Szrj 560*38fd1498Szrj template void 561*38fd1498Szrj __collate_transform(current_abi, const facet*, __any_string&, 562*38fd1498Szrj const char*, const char*); 563*38fd1498Szrj 564*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 565*38fd1498Szrj template void 566*38fd1498Szrj __collate_transform(current_abi, const facet*, __any_string&, 567*38fd1498Szrj const wchar_t*, const wchar_t*); 568*38fd1498Szrj #endif 569*38fd1498Szrj 570*38fd1498Szrj // Cache the values returned by the moneypunct facet, f. 571*38fd1498Szrj // Sets c->_M_allocated so that the __moneypunct_cache destructor will 572*38fd1498Szrj // delete[] the strings allocated by this function. 573*38fd1498Szrj template<typename C, bool Intl> 574*38fd1498Szrj void __moneypunct_fill_cache(current_abi,const facet * f,__moneypunct_cache<C,Intl> * c)575*38fd1498Szrj __moneypunct_fill_cache(current_abi, const facet* f, 576*38fd1498Szrj __moneypunct_cache<C, Intl>* c) 577*38fd1498Szrj { 578*38fd1498Szrj auto* m = static_cast<const moneypunct<C, Intl>*>(f); 579*38fd1498Szrj 580*38fd1498Szrj c->_M_decimal_point = m->decimal_point(); 581*38fd1498Szrj c->_M_thousands_sep = m->thousands_sep(); 582*38fd1498Szrj c->_M_frac_digits = m->frac_digits(); 583*38fd1498Szrj 584*38fd1498Szrj c->_M_grouping = nullptr; 585*38fd1498Szrj c->_M_curr_symbol = nullptr; 586*38fd1498Szrj c->_M_positive_sign = nullptr; 587*38fd1498Szrj c->_M_negative_sign = nullptr; 588*38fd1498Szrj // Set _M_allocated so that if any allocation fails the previously 589*38fd1498Szrj // allocated strings will be deleted in ~__moneypunct_cache(). 590*38fd1498Szrj c->_M_allocated = true; 591*38fd1498Szrj 592*38fd1498Szrj c->_M_grouping_size = __copy(c->_M_grouping, m->grouping()); 593*38fd1498Szrj c->_M_curr_symbol_size = __copy(c->_M_curr_symbol, m->curr_symbol()); 594*38fd1498Szrj c->_M_positive_sign_size 595*38fd1498Szrj = __copy(c->_M_positive_sign, m->positive_sign()); 596*38fd1498Szrj c->_M_negative_sign_size 597*38fd1498Szrj = __copy(c->_M_negative_sign, m->negative_sign()); 598*38fd1498Szrj 599*38fd1498Szrj c->_M_pos_format = m->pos_format(); 600*38fd1498Szrj c->_M_neg_format = m->neg_format(); 601*38fd1498Szrj } 602*38fd1498Szrj 603*38fd1498Szrj template void 604*38fd1498Szrj __moneypunct_fill_cache(current_abi, const facet*, 605*38fd1498Szrj __moneypunct_cache<char, true>*); 606*38fd1498Szrj 607*38fd1498Szrj template void 608*38fd1498Szrj __moneypunct_fill_cache(current_abi, const facet*, 609*38fd1498Szrj __moneypunct_cache<char, false>*); 610*38fd1498Szrj 611*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 612*38fd1498Szrj template void 613*38fd1498Szrj __moneypunct_fill_cache(current_abi, const facet*, 614*38fd1498Szrj __moneypunct_cache<wchar_t, true>*); 615*38fd1498Szrj 616*38fd1498Szrj template void 617*38fd1498Szrj __moneypunct_fill_cache(current_abi, const facet*, 618*38fd1498Szrj __moneypunct_cache<wchar_t, false>*); 619*38fd1498Szrj #endif 620*38fd1498Szrj 621*38fd1498Szrj template<typename C> 622*38fd1498Szrj messages_base::catalog __messages_open(current_abi,const facet * f,const char * s,size_t n,const locale & l)623*38fd1498Szrj __messages_open(current_abi, const facet* f, const char* s, size_t n, 624*38fd1498Szrj const locale& l) 625*38fd1498Szrj { 626*38fd1498Szrj auto* m = static_cast<const messages<C>*>(f); 627*38fd1498Szrj string str(s, n); 628*38fd1498Szrj return m->open(str, l); 629*38fd1498Szrj } 630*38fd1498Szrj 631*38fd1498Szrj template messages_base::catalog 632*38fd1498Szrj __messages_open<char>(current_abi, const facet*, const char*, size_t, 633*38fd1498Szrj const locale&); 634*38fd1498Szrj 635*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 636*38fd1498Szrj template messages_base::catalog 637*38fd1498Szrj __messages_open<wchar_t>(current_abi, const facet*, const char*, size_t, 638*38fd1498Szrj const locale&); 639*38fd1498Szrj #endif 640*38fd1498Szrj 641*38fd1498Szrj template<typename C> 642*38fd1498Szrj void __messages_get(current_abi,const facet * f,__any_string & st,messages_base::catalog c,int set,int msgid,const C * s,size_t n)643*38fd1498Szrj __messages_get(current_abi, const facet* f, __any_string& st, 644*38fd1498Szrj messages_base::catalog c, int set, int msgid, 645*38fd1498Szrj const C* s, size_t n) 646*38fd1498Szrj { 647*38fd1498Szrj auto* m = static_cast<const messages<C>*>(f); 648*38fd1498Szrj st = m->get(c, set, msgid, basic_string<C>(s, n)); 649*38fd1498Szrj } 650*38fd1498Szrj 651*38fd1498Szrj template void 652*38fd1498Szrj __messages_get(current_abi, const facet*, __any_string&, 653*38fd1498Szrj messages_base::catalog, int, int, const char*, size_t); 654*38fd1498Szrj 655*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 656*38fd1498Szrj template void 657*38fd1498Szrj __messages_get(current_abi, const facet*, __any_string&, 658*38fd1498Szrj messages_base::catalog, int, int, const wchar_t*, size_t); 659*38fd1498Szrj #endif 660*38fd1498Szrj 661*38fd1498Szrj template<typename C> 662*38fd1498Szrj void __messages_close(current_abi,const facet * f,messages_base::catalog c)663*38fd1498Szrj __messages_close(current_abi, const facet* f, messages_base::catalog c) 664*38fd1498Szrj { 665*38fd1498Szrj static_cast<const messages<C>*>(f)->close(c); 666*38fd1498Szrj } 667*38fd1498Szrj 668*38fd1498Szrj template void 669*38fd1498Szrj __messages_close<char>(current_abi, const facet*, messages_base::catalog c); 670*38fd1498Szrj 671*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 672*38fd1498Szrj template void 673*38fd1498Szrj __messages_close<wchar_t>(current_abi, const facet*, 674*38fd1498Szrj messages_base::catalog c); 675*38fd1498Szrj #endif 676*38fd1498Szrj 677*38fd1498Szrj template<typename C> 678*38fd1498Szrj time_base::dateorder __time_get_dateorder(current_abi,const facet * f)679*38fd1498Szrj __time_get_dateorder(current_abi, const facet* f) 680*38fd1498Szrj { return static_cast<const time_get<C>*>(f)->date_order(); } 681*38fd1498Szrj 682*38fd1498Szrj template time_base::dateorder 683*38fd1498Szrj __time_get_dateorder<char>(current_abi, const facet*); 684*38fd1498Szrj 685*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 686*38fd1498Szrj template time_base::dateorder 687*38fd1498Szrj __time_get_dateorder<wchar_t>(current_abi, const facet*); 688*38fd1498Szrj #endif 689*38fd1498Szrj 690*38fd1498Szrj template<typename C> 691*38fd1498Szrj istreambuf_iterator<C> __time_get(current_abi,const facet * f,istreambuf_iterator<C> beg,istreambuf_iterator<C> end,ios_base & io,ios_base::iostate & err,tm * t,char which)692*38fd1498Szrj __time_get(current_abi, const facet* f, 693*38fd1498Szrj istreambuf_iterator<C> beg, istreambuf_iterator<C> end, 694*38fd1498Szrj ios_base& io, ios_base::iostate& err, tm* t, char which) 695*38fd1498Szrj { 696*38fd1498Szrj auto* g = static_cast<const time_get<C>*>(f); 697*38fd1498Szrj switch(which) 698*38fd1498Szrj { 699*38fd1498Szrj case 't': 700*38fd1498Szrj return g->get_time(beg, end, io, err, t); 701*38fd1498Szrj case 'd': 702*38fd1498Szrj return g->get_date(beg, end, io, err, t); 703*38fd1498Szrj case 'w': 704*38fd1498Szrj return g->get_weekday(beg, end, io, err, t); 705*38fd1498Szrj case 'm': 706*38fd1498Szrj return g->get_monthname(beg, end, io, err, t); 707*38fd1498Szrj case 'y': 708*38fd1498Szrj return g->get_year(beg, end, io, err, t); 709*38fd1498Szrj default: 710*38fd1498Szrj __builtin_unreachable(); 711*38fd1498Szrj } 712*38fd1498Szrj } 713*38fd1498Szrj 714*38fd1498Szrj template istreambuf_iterator<char> 715*38fd1498Szrj __time_get(current_abi, const facet*, 716*38fd1498Szrj istreambuf_iterator<char>, istreambuf_iterator<char>, 717*38fd1498Szrj ios_base&, ios_base::iostate&, tm*, char); 718*38fd1498Szrj 719*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 720*38fd1498Szrj template istreambuf_iterator<wchar_t> 721*38fd1498Szrj __time_get(current_abi, const facet*, 722*38fd1498Szrj istreambuf_iterator<wchar_t>, istreambuf_iterator<wchar_t>, 723*38fd1498Szrj ios_base&, ios_base::iostate&, tm*, char); 724*38fd1498Szrj #endif 725*38fd1498Szrj 726*38fd1498Szrj template<typename C> 727*38fd1498Szrj istreambuf_iterator<C> __money_get(current_abi,const facet * f,istreambuf_iterator<C> s,istreambuf_iterator<C> end,bool intl,ios_base & str,ios_base::iostate & err,long double * units,__any_string * digits)728*38fd1498Szrj __money_get(current_abi, const facet* f, 729*38fd1498Szrj istreambuf_iterator<C> s, istreambuf_iterator<C> end, 730*38fd1498Szrj bool intl, ios_base& str, ios_base::iostate& err, 731*38fd1498Szrj long double* units, __any_string* digits) 732*38fd1498Szrj { 733*38fd1498Szrj auto* m = static_cast<const money_get<C>*>(f); 734*38fd1498Szrj if (units) 735*38fd1498Szrj return m->get(s, end, intl, str, err, *units); 736*38fd1498Szrj basic_string<C> digits2; 737*38fd1498Szrj s = m->get(s, end, intl, str, err, digits2); 738*38fd1498Szrj if (err == ios_base::goodbit) 739*38fd1498Szrj *digits = digits2; 740*38fd1498Szrj return s; 741*38fd1498Szrj } 742*38fd1498Szrj 743*38fd1498Szrj template istreambuf_iterator<char> 744*38fd1498Szrj __money_get(current_abi, const facet*, 745*38fd1498Szrj istreambuf_iterator<char>, istreambuf_iterator<char>, 746*38fd1498Szrj bool, ios_base&, ios_base::iostate&, 747*38fd1498Szrj long double*, __any_string*); 748*38fd1498Szrj 749*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 750*38fd1498Szrj template istreambuf_iterator<wchar_t> 751*38fd1498Szrj __money_get(current_abi, const facet*, 752*38fd1498Szrj istreambuf_iterator<wchar_t>, istreambuf_iterator<wchar_t>, 753*38fd1498Szrj bool, ios_base&, ios_base::iostate&, 754*38fd1498Szrj long double*, __any_string*); 755*38fd1498Szrj #endif 756*38fd1498Szrj 757*38fd1498Szrj template<typename C> 758*38fd1498Szrj ostreambuf_iterator<C> __money_put(current_abi,const facet * f,ostreambuf_iterator<C> s,bool intl,ios_base & io,C fill,long double units,const __any_string * digits)759*38fd1498Szrj __money_put(current_abi, const facet* f, ostreambuf_iterator<C> s, 760*38fd1498Szrj bool intl, ios_base& io, C fill, long double units, 761*38fd1498Szrj const __any_string* digits) 762*38fd1498Szrj { 763*38fd1498Szrj auto* m = static_cast<const money_put<C>*>(f); 764*38fd1498Szrj if (digits) 765*38fd1498Szrj return m->put(s, intl, io, fill, *digits); 766*38fd1498Szrj else 767*38fd1498Szrj return m->put(s, intl, io, fill, units); 768*38fd1498Szrj } 769*38fd1498Szrj 770*38fd1498Szrj template ostreambuf_iterator<char> 771*38fd1498Szrj __money_put(current_abi, const facet*, ostreambuf_iterator<char>, 772*38fd1498Szrj bool, ios_base&, char, long double, const __any_string*); 773*38fd1498Szrj 774*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 775*38fd1498Szrj template ostreambuf_iterator<wchar_t> 776*38fd1498Szrj __money_put(current_abi, const facet*, ostreambuf_iterator<wchar_t>, 777*38fd1498Szrj bool, ios_base&, wchar_t, long double, const __any_string*); 778*38fd1498Szrj #endif 779*38fd1498Szrj 780*38fd1498Szrj } // namespace __facet_shims 781*38fd1498Szrj 782*38fd1498Szrj // Create a new shim facet of type WHICH that forwards calls to F. 783*38fd1498Szrj // F is the replacement facet provided by the user, WHICH is the ID of 784*38fd1498Szrj // F's "other ABI twin" which we are replacing with a shim. 785*38fd1498Szrj const locale::facet* 786*38fd1498Szrj #if _GLIBCXX_USE_CXX11_ABI _M_sso_shim(const locale::id * which) const787*38fd1498Szrj locale::facet::_M_sso_shim(const locale::id* which) const 788*38fd1498Szrj #else 789*38fd1498Szrj locale::facet::_M_cow_shim(const locale::id* which) const 790*38fd1498Szrj #endif 791*38fd1498Szrj { 792*38fd1498Szrj using namespace __facet_shims; 793*38fd1498Szrj 794*38fd1498Szrj #if __cpp_rtti 795*38fd1498Szrj // If this is already a shim just use its underlying facet. 796*38fd1498Szrj if (auto* p = dynamic_cast<const __shim*>(this)) 797*38fd1498Szrj return p->_M_get(); 798*38fd1498Szrj #endif 799*38fd1498Szrj 800*38fd1498Szrj if (which == &numpunct<char>::id) 801*38fd1498Szrj return new numpunct_shim<char>{this}; 802*38fd1498Szrj if (which == &std::collate<char>::id) 803*38fd1498Szrj return new collate_shim<char>{this}; 804*38fd1498Szrj if (which == &time_get<char>::id) 805*38fd1498Szrj return new time_get_shim<char>{this}; 806*38fd1498Szrj if (which == &money_get<char>::id) 807*38fd1498Szrj return new money_get_shim<char>{this}; 808*38fd1498Szrj if (which == &money_put<char>::id) 809*38fd1498Szrj return new money_put_shim<char>{this}; 810*38fd1498Szrj if (which == &moneypunct<char, true>::id) 811*38fd1498Szrj return new moneypunct_shim<char, true>{this}; 812*38fd1498Szrj if (which == &moneypunct<char, false>::id) 813*38fd1498Szrj return new moneypunct_shim<char, false>{this}; 814*38fd1498Szrj if (which == &std::messages<char>::id) 815*38fd1498Szrj return new messages_shim<char>{this}; 816*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 817*38fd1498Szrj if (which == &numpunct<wchar_t>::id) 818*38fd1498Szrj return new numpunct_shim<wchar_t>{this}; 819*38fd1498Szrj if (which == &std::collate<wchar_t>::id) 820*38fd1498Szrj return new collate_shim<wchar_t>{this}; 821*38fd1498Szrj if (which == &time_get<wchar_t>::id) 822*38fd1498Szrj return new time_get_shim<wchar_t>{this}; 823*38fd1498Szrj if (which == &money_get<wchar_t>::id) 824*38fd1498Szrj return new money_get_shim<wchar_t>{this}; 825*38fd1498Szrj if (which == &money_put<wchar_t>::id) 826*38fd1498Szrj return new money_put_shim<wchar_t>{this}; 827*38fd1498Szrj if (which == &moneypunct<wchar_t, true>::id) 828*38fd1498Szrj return new moneypunct_shim<wchar_t, true>{this}; 829*38fd1498Szrj if (which == &moneypunct<wchar_t, false>::id) 830*38fd1498Szrj return new moneypunct_shim<wchar_t, false>{this}; 831*38fd1498Szrj if (which == &std::messages<wchar_t>::id) 832*38fd1498Szrj return new messages_shim<wchar_t>{this}; 833*38fd1498Szrj #endif 834*38fd1498Szrj __throw_logic_error("cannot create shim for unknown locale::facet"); 835*38fd1498Szrj } 836*38fd1498Szrj 837*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 838*38fd1498Szrj } // namespace std 839