1*e4b17023SJohn Marino // Locale support -*- C++ -*- 2*e4b17023SJohn Marino 3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4*e4b17023SJohn Marino // 5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 9*e4b17023SJohn Marino // any later version. 10*e4b17023SJohn Marino 11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino // GNU General Public License for more details. 15*e4b17023SJohn Marino 16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 24*e4b17023SJohn Marino 25*e4b17023SJohn Marino /** @file bits/locale_classes.tcc 26*e4b17023SJohn Marino * This is an internal header file, included by other library headers. 27*e4b17023SJohn Marino * Do not attempt to use it directly. @headername{locale} 28*e4b17023SJohn Marino */ 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino // 31*e4b17023SJohn Marino // ISO C++ 14882: 22.1 Locales 32*e4b17023SJohn Marino // 33*e4b17023SJohn Marino 34*e4b17023SJohn Marino #ifndef _LOCALE_CLASSES_TCC 35*e4b17023SJohn Marino #define _LOCALE_CLASSES_TCC 1 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino #pragma GCC system_header 38*e4b17023SJohn Marino 39*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 40*e4b17023SJohn Marino { 41*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 42*e4b17023SJohn Marino 43*e4b17023SJohn Marino template<typename _Facet> 44*e4b17023SJohn Marino locale:: locale(const locale & __other,_Facet * __f)45*e4b17023SJohn Marino locale(const locale& __other, _Facet* __f) 46*e4b17023SJohn Marino { 47*e4b17023SJohn Marino _M_impl = new _Impl(*__other._M_impl, 1); 48*e4b17023SJohn Marino 49*e4b17023SJohn Marino __try 50*e4b17023SJohn Marino { _M_impl->_M_install_facet(&_Facet::id, __f); } 51*e4b17023SJohn Marino __catch(...) 52*e4b17023SJohn Marino { 53*e4b17023SJohn Marino _M_impl->_M_remove_reference(); 54*e4b17023SJohn Marino __throw_exception_again; 55*e4b17023SJohn Marino } 56*e4b17023SJohn Marino delete [] _M_impl->_M_names[0]; 57*e4b17023SJohn Marino _M_impl->_M_names[0] = 0; // Unnamed. 58*e4b17023SJohn Marino } 59*e4b17023SJohn Marino 60*e4b17023SJohn Marino template<typename _Facet> 61*e4b17023SJohn Marino locale 62*e4b17023SJohn Marino locale:: combine(const locale & __other) const63*e4b17023SJohn Marino combine(const locale& __other) const 64*e4b17023SJohn Marino { 65*e4b17023SJohn Marino _Impl* __tmp = new _Impl(*_M_impl, 1); 66*e4b17023SJohn Marino __try 67*e4b17023SJohn Marino { 68*e4b17023SJohn Marino __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); 69*e4b17023SJohn Marino } 70*e4b17023SJohn Marino __catch(...) 71*e4b17023SJohn Marino { 72*e4b17023SJohn Marino __tmp->_M_remove_reference(); 73*e4b17023SJohn Marino __throw_exception_again; 74*e4b17023SJohn Marino } 75*e4b17023SJohn Marino return locale(__tmp); 76*e4b17023SJohn Marino } 77*e4b17023SJohn Marino 78*e4b17023SJohn Marino template<typename _CharT, typename _Traits, typename _Alloc> 79*e4b17023SJohn Marino bool 80*e4b17023SJohn Marino locale:: operator ()(const basic_string<_CharT,_Traits,_Alloc> & __s1,const basic_string<_CharT,_Traits,_Alloc> & __s2) const81*e4b17023SJohn Marino operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, 82*e4b17023SJohn Marino const basic_string<_CharT, _Traits, _Alloc>& __s2) const 83*e4b17023SJohn Marino { 84*e4b17023SJohn Marino typedef std::collate<_CharT> __collate_type; 85*e4b17023SJohn Marino const __collate_type& __collate = use_facet<__collate_type>(*this); 86*e4b17023SJohn Marino return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), 87*e4b17023SJohn Marino __s2.data(), __s2.data() + __s2.length()) < 0); 88*e4b17023SJohn Marino } 89*e4b17023SJohn Marino 90*e4b17023SJohn Marino /** 91*e4b17023SJohn Marino * @brief Test for the presence of a facet. 92*e4b17023SJohn Marino * 93*e4b17023SJohn Marino * has_facet tests the locale argument for the presence of the facet type 94*e4b17023SJohn Marino * provided as the template parameter. Facets derived from the facet 95*e4b17023SJohn Marino * parameter will also return true. 96*e4b17023SJohn Marino * 97*e4b17023SJohn Marino * @tparam _Facet The facet type to test the presence of. 98*e4b17023SJohn Marino * @param __loc The locale to test. 99*e4b17023SJohn Marino * @return true if @p __loc contains a facet of type _Facet, else false. 100*e4b17023SJohn Marino */ 101*e4b17023SJohn Marino template<typename _Facet> 102*e4b17023SJohn Marino bool has_facet(const locale & __loc)103*e4b17023SJohn Marino has_facet(const locale& __loc) throw() 104*e4b17023SJohn Marino { 105*e4b17023SJohn Marino const size_t __i = _Facet::id._M_id(); 106*e4b17023SJohn Marino const locale::facet** __facets = __loc._M_impl->_M_facets; 107*e4b17023SJohn Marino return (__i < __loc._M_impl->_M_facets_size 108*e4b17023SJohn Marino #ifdef __GXX_RTTI 109*e4b17023SJohn Marino && dynamic_cast<const _Facet*>(__facets[__i])); 110*e4b17023SJohn Marino #else 111*e4b17023SJohn Marino && static_cast<const _Facet*>(__facets[__i])); 112*e4b17023SJohn Marino #endif 113*e4b17023SJohn Marino } 114*e4b17023SJohn Marino 115*e4b17023SJohn Marino /** 116*e4b17023SJohn Marino * @brief Return a facet. 117*e4b17023SJohn Marino * 118*e4b17023SJohn Marino * use_facet looks for and returns a reference to a facet of type Facet 119*e4b17023SJohn Marino * where Facet is the template parameter. If has_facet(locale) is true, 120*e4b17023SJohn Marino * there is a suitable facet to return. It throws std::bad_cast if the 121*e4b17023SJohn Marino * locale doesn't contain a facet of type Facet. 122*e4b17023SJohn Marino * 123*e4b17023SJohn Marino * @tparam _Facet The facet type to access. 124*e4b17023SJohn Marino * @param __loc The locale to use. 125*e4b17023SJohn Marino * @return Reference to facet of type Facet. 126*e4b17023SJohn Marino * @throw std::bad_cast if @p __loc doesn't contain a facet of type _Facet. 127*e4b17023SJohn Marino */ 128*e4b17023SJohn Marino template<typename _Facet> 129*e4b17023SJohn Marino const _Facet& use_facet(const locale & __loc)130*e4b17023SJohn Marino use_facet(const locale& __loc) 131*e4b17023SJohn Marino { 132*e4b17023SJohn Marino const size_t __i = _Facet::id._M_id(); 133*e4b17023SJohn Marino const locale::facet** __facets = __loc._M_impl->_M_facets; 134*e4b17023SJohn Marino if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i]) 135*e4b17023SJohn Marino __throw_bad_cast(); 136*e4b17023SJohn Marino #ifdef __GXX_RTTI 137*e4b17023SJohn Marino return dynamic_cast<const _Facet&>(*__facets[__i]); 138*e4b17023SJohn Marino #else 139*e4b17023SJohn Marino return static_cast<const _Facet&>(*__facets[__i]); 140*e4b17023SJohn Marino #endif 141*e4b17023SJohn Marino } 142*e4b17023SJohn Marino 143*e4b17023SJohn Marino 144*e4b17023SJohn Marino // Generic version does nothing. 145*e4b17023SJohn Marino template<typename _CharT> 146*e4b17023SJohn Marino int _M_compare(const _CharT *,const _CharT *) const147*e4b17023SJohn Marino collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw () 148*e4b17023SJohn Marino { return 0; } 149*e4b17023SJohn Marino 150*e4b17023SJohn Marino // Generic version does nothing. 151*e4b17023SJohn Marino template<typename _CharT> 152*e4b17023SJohn Marino size_t _M_transform(_CharT *,const _CharT *,size_t) const153*e4b17023SJohn Marino collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw () 154*e4b17023SJohn Marino { return 0; } 155*e4b17023SJohn Marino 156*e4b17023SJohn Marino template<typename _CharT> 157*e4b17023SJohn Marino int 158*e4b17023SJohn Marino collate<_CharT>:: do_compare(const _CharT * __lo1,const _CharT * __hi1,const _CharT * __lo2,const _CharT * __hi2) const159*e4b17023SJohn Marino do_compare(const _CharT* __lo1, const _CharT* __hi1, 160*e4b17023SJohn Marino const _CharT* __lo2, const _CharT* __hi2) const 161*e4b17023SJohn Marino { 162*e4b17023SJohn Marino // strcoll assumes zero-terminated strings so we make a copy 163*e4b17023SJohn Marino // and then put a zero at the end. 164*e4b17023SJohn Marino const string_type __one(__lo1, __hi1); 165*e4b17023SJohn Marino const string_type __two(__lo2, __hi2); 166*e4b17023SJohn Marino 167*e4b17023SJohn Marino const _CharT* __p = __one.c_str(); 168*e4b17023SJohn Marino const _CharT* __pend = __one.data() + __one.length(); 169*e4b17023SJohn Marino const _CharT* __q = __two.c_str(); 170*e4b17023SJohn Marino const _CharT* __qend = __two.data() + __two.length(); 171*e4b17023SJohn Marino 172*e4b17023SJohn Marino // strcoll stops when it sees a nul character so we break 173*e4b17023SJohn Marino // the strings into zero-terminated substrings and pass those 174*e4b17023SJohn Marino // to strcoll. 175*e4b17023SJohn Marino for (;;) 176*e4b17023SJohn Marino { 177*e4b17023SJohn Marino const int __res = _M_compare(__p, __q); 178*e4b17023SJohn Marino if (__res) 179*e4b17023SJohn Marino return __res; 180*e4b17023SJohn Marino 181*e4b17023SJohn Marino __p += char_traits<_CharT>::length(__p); 182*e4b17023SJohn Marino __q += char_traits<_CharT>::length(__q); 183*e4b17023SJohn Marino if (__p == __pend && __q == __qend) 184*e4b17023SJohn Marino return 0; 185*e4b17023SJohn Marino else if (__p == __pend) 186*e4b17023SJohn Marino return -1; 187*e4b17023SJohn Marino else if (__q == __qend) 188*e4b17023SJohn Marino return 1; 189*e4b17023SJohn Marino 190*e4b17023SJohn Marino __p++; 191*e4b17023SJohn Marino __q++; 192*e4b17023SJohn Marino } 193*e4b17023SJohn Marino } 194*e4b17023SJohn Marino 195*e4b17023SJohn Marino template<typename _CharT> 196*e4b17023SJohn Marino typename collate<_CharT>::string_type 197*e4b17023SJohn Marino collate<_CharT>:: do_transform(const _CharT * __lo,const _CharT * __hi) const198*e4b17023SJohn Marino do_transform(const _CharT* __lo, const _CharT* __hi) const 199*e4b17023SJohn Marino { 200*e4b17023SJohn Marino string_type __ret; 201*e4b17023SJohn Marino 202*e4b17023SJohn Marino // strxfrm assumes zero-terminated strings so we make a copy 203*e4b17023SJohn Marino const string_type __str(__lo, __hi); 204*e4b17023SJohn Marino 205*e4b17023SJohn Marino const _CharT* __p = __str.c_str(); 206*e4b17023SJohn Marino const _CharT* __pend = __str.data() + __str.length(); 207*e4b17023SJohn Marino 208*e4b17023SJohn Marino size_t __len = (__hi - __lo) * 2; 209*e4b17023SJohn Marino 210*e4b17023SJohn Marino _CharT* __c = new _CharT[__len]; 211*e4b17023SJohn Marino 212*e4b17023SJohn Marino __try 213*e4b17023SJohn Marino { 214*e4b17023SJohn Marino // strxfrm stops when it sees a nul character so we break 215*e4b17023SJohn Marino // the string into zero-terminated substrings and pass those 216*e4b17023SJohn Marino // to strxfrm. 217*e4b17023SJohn Marino for (;;) 218*e4b17023SJohn Marino { 219*e4b17023SJohn Marino // First try a buffer perhaps big enough. 220*e4b17023SJohn Marino size_t __res = _M_transform(__c, __p, __len); 221*e4b17023SJohn Marino // If the buffer was not large enough, try again with the 222*e4b17023SJohn Marino // correct size. 223*e4b17023SJohn Marino if (__res >= __len) 224*e4b17023SJohn Marino { 225*e4b17023SJohn Marino __len = __res + 1; 226*e4b17023SJohn Marino delete [] __c, __c = 0; 227*e4b17023SJohn Marino __c = new _CharT[__len]; 228*e4b17023SJohn Marino __res = _M_transform(__c, __p, __len); 229*e4b17023SJohn Marino } 230*e4b17023SJohn Marino 231*e4b17023SJohn Marino __ret.append(__c, __res); 232*e4b17023SJohn Marino __p += char_traits<_CharT>::length(__p); 233*e4b17023SJohn Marino if (__p == __pend) 234*e4b17023SJohn Marino break; 235*e4b17023SJohn Marino 236*e4b17023SJohn Marino __p++; 237*e4b17023SJohn Marino __ret.push_back(_CharT()); 238*e4b17023SJohn Marino } 239*e4b17023SJohn Marino } 240*e4b17023SJohn Marino __catch(...) 241*e4b17023SJohn Marino { 242*e4b17023SJohn Marino delete [] __c; 243*e4b17023SJohn Marino __throw_exception_again; 244*e4b17023SJohn Marino } 245*e4b17023SJohn Marino 246*e4b17023SJohn Marino delete [] __c; 247*e4b17023SJohn Marino 248*e4b17023SJohn Marino return __ret; 249*e4b17023SJohn Marino } 250*e4b17023SJohn Marino 251*e4b17023SJohn Marino template<typename _CharT> 252*e4b17023SJohn Marino long 253*e4b17023SJohn Marino collate<_CharT>:: do_hash(const _CharT * __lo,const _CharT * __hi) const254*e4b17023SJohn Marino do_hash(const _CharT* __lo, const _CharT* __hi) const 255*e4b17023SJohn Marino { 256*e4b17023SJohn Marino unsigned long __val = 0; 257*e4b17023SJohn Marino for (; __lo < __hi; ++__lo) 258*e4b17023SJohn Marino __val = 259*e4b17023SJohn Marino *__lo + ((__val << 7) 260*e4b17023SJohn Marino | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>:: 261*e4b17023SJohn Marino __digits - 7))); 262*e4b17023SJohn Marino return static_cast<long>(__val); 263*e4b17023SJohn Marino } 264*e4b17023SJohn Marino 265*e4b17023SJohn Marino // Inhibit implicit instantiations for required instantiations, 266*e4b17023SJohn Marino // which are defined via explicit instantiations elsewhere. 267*e4b17023SJohn Marino #if _GLIBCXX_EXTERN_TEMPLATE 268*e4b17023SJohn Marino extern template class collate<char>; 269*e4b17023SJohn Marino extern template class collate_byname<char>; 270*e4b17023SJohn Marino 271*e4b17023SJohn Marino extern template 272*e4b17023SJohn Marino const collate<char>& 273*e4b17023SJohn Marino use_facet<collate<char> >(const locale&); 274*e4b17023SJohn Marino 275*e4b17023SJohn Marino extern template 276*e4b17023SJohn Marino bool 277*e4b17023SJohn Marino has_facet<collate<char> >(const locale&); 278*e4b17023SJohn Marino 279*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_WCHAR_T 280*e4b17023SJohn Marino extern template class collate<wchar_t>; 281*e4b17023SJohn Marino extern template class collate_byname<wchar_t>; 282*e4b17023SJohn Marino 283*e4b17023SJohn Marino extern template 284*e4b17023SJohn Marino const collate<wchar_t>& 285*e4b17023SJohn Marino use_facet<collate<wchar_t> >(const locale&); 286*e4b17023SJohn Marino 287*e4b17023SJohn Marino extern template 288*e4b17023SJohn Marino bool 289*e4b17023SJohn Marino has_facet<collate<wchar_t> >(const locale&); 290*e4b17023SJohn Marino #endif 291*e4b17023SJohn Marino #endif 292*e4b17023SJohn Marino 293*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 294*e4b17023SJohn Marino } // namespace std 295*e4b17023SJohn Marino 296*e4b17023SJohn Marino #endif 297