1*38fd1498Szrj // Locale support -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2007-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 /** @file bits/locale_classes.tcc 26*38fd1498Szrj * This is an internal header file, included by other library headers. 27*38fd1498Szrj * Do not attempt to use it directly. @headername{locale} 28*38fd1498Szrj */ 29*38fd1498Szrj 30*38fd1498Szrj // 31*38fd1498Szrj // ISO C++ 14882: 22.1 Locales 32*38fd1498Szrj // 33*38fd1498Szrj 34*38fd1498Szrj #ifndef _LOCALE_CLASSES_TCC 35*38fd1498Szrj #define _LOCALE_CLASSES_TCC 1 36*38fd1498Szrj 37*38fd1498Szrj #pragma GCC system_header 38*38fd1498Szrj 39*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 40*38fd1498Szrj { 41*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 42*38fd1498Szrj 43*38fd1498Szrj template<typename _Facet> 44*38fd1498Szrj locale:: locale(const locale & __other,_Facet * __f)45*38fd1498Szrj locale(const locale& __other, _Facet* __f) 46*38fd1498Szrj { 47*38fd1498Szrj _M_impl = new _Impl(*__other._M_impl, 1); 48*38fd1498Szrj 49*38fd1498Szrj __try 50*38fd1498Szrj { _M_impl->_M_install_facet(&_Facet::id, __f); } 51*38fd1498Szrj __catch(...) 52*38fd1498Szrj { 53*38fd1498Szrj _M_impl->_M_remove_reference(); 54*38fd1498Szrj __throw_exception_again; 55*38fd1498Szrj } 56*38fd1498Szrj delete [] _M_impl->_M_names[0]; 57*38fd1498Szrj _M_impl->_M_names[0] = 0; // Unnamed. 58*38fd1498Szrj } 59*38fd1498Szrj 60*38fd1498Szrj template<typename _Facet> 61*38fd1498Szrj locale 62*38fd1498Szrj locale:: combine(const locale & __other) const63*38fd1498Szrj combine(const locale& __other) const 64*38fd1498Szrj { 65*38fd1498Szrj _Impl* __tmp = new _Impl(*_M_impl, 1); 66*38fd1498Szrj __try 67*38fd1498Szrj { 68*38fd1498Szrj __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); 69*38fd1498Szrj } 70*38fd1498Szrj __catch(...) 71*38fd1498Szrj { 72*38fd1498Szrj __tmp->_M_remove_reference(); 73*38fd1498Szrj __throw_exception_again; 74*38fd1498Szrj } 75*38fd1498Szrj return locale(__tmp); 76*38fd1498Szrj } 77*38fd1498Szrj 78*38fd1498Szrj template<typename _CharT, typename _Traits, typename _Alloc> 79*38fd1498Szrj bool 80*38fd1498Szrj locale:: operator ()(const basic_string<_CharT,_Traits,_Alloc> & __s1,const basic_string<_CharT,_Traits,_Alloc> & __s2) const81*38fd1498Szrj operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, 82*38fd1498Szrj const basic_string<_CharT, _Traits, _Alloc>& __s2) const 83*38fd1498Szrj { 84*38fd1498Szrj typedef std::collate<_CharT> __collate_type; 85*38fd1498Szrj const __collate_type& __collate = use_facet<__collate_type>(*this); 86*38fd1498Szrj return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), 87*38fd1498Szrj __s2.data(), __s2.data() + __s2.length()) < 0); 88*38fd1498Szrj } 89*38fd1498Szrj 90*38fd1498Szrj /** 91*38fd1498Szrj * @brief Test for the presence of a facet. 92*38fd1498Szrj * @ingroup locales 93*38fd1498Szrj * 94*38fd1498Szrj * has_facet tests the locale argument for the presence of the facet type 95*38fd1498Szrj * provided as the template parameter. Facets derived from the facet 96*38fd1498Szrj * parameter will also return true. 97*38fd1498Szrj * 98*38fd1498Szrj * @tparam _Facet The facet type to test the presence of. 99*38fd1498Szrj * @param __loc The locale to test. 100*38fd1498Szrj * @return true if @p __loc contains a facet of type _Facet, else false. 101*38fd1498Szrj */ 102*38fd1498Szrj template<typename _Facet> 103*38fd1498Szrj bool has_facet(const locale & __loc)104*38fd1498Szrj has_facet(const locale& __loc) throw() 105*38fd1498Szrj { 106*38fd1498Szrj const size_t __i = _Facet::id._M_id(); 107*38fd1498Szrj const locale::facet** __facets = __loc._M_impl->_M_facets; 108*38fd1498Szrj return (__i < __loc._M_impl->_M_facets_size 109*38fd1498Szrj #if __cpp_rtti 110*38fd1498Szrj && dynamic_cast<const _Facet*>(__facets[__i])); 111*38fd1498Szrj #else 112*38fd1498Szrj && static_cast<const _Facet*>(__facets[__i])); 113*38fd1498Szrj #endif 114*38fd1498Szrj } 115*38fd1498Szrj 116*38fd1498Szrj /** 117*38fd1498Szrj * @brief Return a facet. 118*38fd1498Szrj * @ingroup locales 119*38fd1498Szrj * 120*38fd1498Szrj * use_facet looks for and returns a reference to a facet of type Facet 121*38fd1498Szrj * where Facet is the template parameter. If has_facet(locale) is true, 122*38fd1498Szrj * there is a suitable facet to return. It throws std::bad_cast if the 123*38fd1498Szrj * locale doesn't contain a facet of type Facet. 124*38fd1498Szrj * 125*38fd1498Szrj * @tparam _Facet The facet type to access. 126*38fd1498Szrj * @param __loc The locale to use. 127*38fd1498Szrj * @return Reference to facet of type Facet. 128*38fd1498Szrj * @throw std::bad_cast if @p __loc doesn't contain a facet of type _Facet. 129*38fd1498Szrj */ 130*38fd1498Szrj template<typename _Facet> 131*38fd1498Szrj const _Facet& use_facet(const locale & __loc)132*38fd1498Szrj use_facet(const locale& __loc) 133*38fd1498Szrj { 134*38fd1498Szrj const size_t __i = _Facet::id._M_id(); 135*38fd1498Szrj const locale::facet** __facets = __loc._M_impl->_M_facets; 136*38fd1498Szrj if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i]) 137*38fd1498Szrj __throw_bad_cast(); 138*38fd1498Szrj #if __cpp_rtti 139*38fd1498Szrj return dynamic_cast<const _Facet&>(*__facets[__i]); 140*38fd1498Szrj #else 141*38fd1498Szrj return static_cast<const _Facet&>(*__facets[__i]); 142*38fd1498Szrj #endif 143*38fd1498Szrj } 144*38fd1498Szrj 145*38fd1498Szrj 146*38fd1498Szrj // Generic version does nothing. 147*38fd1498Szrj template<typename _CharT> 148*38fd1498Szrj int _M_compare(const _CharT *,const _CharT *) const149*38fd1498Szrj collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw () 150*38fd1498Szrj { return 0; } 151*38fd1498Szrj 152*38fd1498Szrj // Generic version does nothing. 153*38fd1498Szrj template<typename _CharT> 154*38fd1498Szrj size_t _M_transform(_CharT *,const _CharT *,size_t) const155*38fd1498Szrj collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw () 156*38fd1498Szrj { return 0; } 157*38fd1498Szrj 158*38fd1498Szrj template<typename _CharT> 159*38fd1498Szrj int 160*38fd1498Szrj collate<_CharT>:: do_compare(const _CharT * __lo1,const _CharT * __hi1,const _CharT * __lo2,const _CharT * __hi2) const161*38fd1498Szrj do_compare(const _CharT* __lo1, const _CharT* __hi1, 162*38fd1498Szrj const _CharT* __lo2, const _CharT* __hi2) const 163*38fd1498Szrj { 164*38fd1498Szrj // strcoll assumes zero-terminated strings so we make a copy 165*38fd1498Szrj // and then put a zero at the end. 166*38fd1498Szrj const string_type __one(__lo1, __hi1); 167*38fd1498Szrj const string_type __two(__lo2, __hi2); 168*38fd1498Szrj 169*38fd1498Szrj const _CharT* __p = __one.c_str(); 170*38fd1498Szrj const _CharT* __pend = __one.data() + __one.length(); 171*38fd1498Szrj const _CharT* __q = __two.c_str(); 172*38fd1498Szrj const _CharT* __qend = __two.data() + __two.length(); 173*38fd1498Szrj 174*38fd1498Szrj // strcoll stops when it sees a nul character so we break 175*38fd1498Szrj // the strings into zero-terminated substrings and pass those 176*38fd1498Szrj // to strcoll. 177*38fd1498Szrj for (;;) 178*38fd1498Szrj { 179*38fd1498Szrj const int __res = _M_compare(__p, __q); 180*38fd1498Szrj if (__res) 181*38fd1498Szrj return __res; 182*38fd1498Szrj 183*38fd1498Szrj __p += char_traits<_CharT>::length(__p); 184*38fd1498Szrj __q += char_traits<_CharT>::length(__q); 185*38fd1498Szrj if (__p == __pend && __q == __qend) 186*38fd1498Szrj return 0; 187*38fd1498Szrj else if (__p == __pend) 188*38fd1498Szrj return -1; 189*38fd1498Szrj else if (__q == __qend) 190*38fd1498Szrj return 1; 191*38fd1498Szrj 192*38fd1498Szrj __p++; 193*38fd1498Szrj __q++; 194*38fd1498Szrj } 195*38fd1498Szrj } 196*38fd1498Szrj 197*38fd1498Szrj template<typename _CharT> 198*38fd1498Szrj typename collate<_CharT>::string_type 199*38fd1498Szrj collate<_CharT>:: do_transform(const _CharT * __lo,const _CharT * __hi) const200*38fd1498Szrj do_transform(const _CharT* __lo, const _CharT* __hi) const 201*38fd1498Szrj { 202*38fd1498Szrj string_type __ret; 203*38fd1498Szrj 204*38fd1498Szrj // strxfrm assumes zero-terminated strings so we make a copy 205*38fd1498Szrj const string_type __str(__lo, __hi); 206*38fd1498Szrj 207*38fd1498Szrj const _CharT* __p = __str.c_str(); 208*38fd1498Szrj const _CharT* __pend = __str.data() + __str.length(); 209*38fd1498Szrj 210*38fd1498Szrj size_t __len = (__hi - __lo) * 2; 211*38fd1498Szrj 212*38fd1498Szrj _CharT* __c = new _CharT[__len]; 213*38fd1498Szrj 214*38fd1498Szrj __try 215*38fd1498Szrj { 216*38fd1498Szrj // strxfrm stops when it sees a nul character so we break 217*38fd1498Szrj // the string into zero-terminated substrings and pass those 218*38fd1498Szrj // to strxfrm. 219*38fd1498Szrj for (;;) 220*38fd1498Szrj { 221*38fd1498Szrj // First try a buffer perhaps big enough. 222*38fd1498Szrj size_t __res = _M_transform(__c, __p, __len); 223*38fd1498Szrj // If the buffer was not large enough, try again with the 224*38fd1498Szrj // correct size. 225*38fd1498Szrj if (__res >= __len) 226*38fd1498Szrj { 227*38fd1498Szrj __len = __res + 1; 228*38fd1498Szrj delete [] __c, __c = 0; 229*38fd1498Szrj __c = new _CharT[__len]; 230*38fd1498Szrj __res = _M_transform(__c, __p, __len); 231*38fd1498Szrj } 232*38fd1498Szrj 233*38fd1498Szrj __ret.append(__c, __res); 234*38fd1498Szrj __p += char_traits<_CharT>::length(__p); 235*38fd1498Szrj if (__p == __pend) 236*38fd1498Szrj break; 237*38fd1498Szrj 238*38fd1498Szrj __p++; 239*38fd1498Szrj __ret.push_back(_CharT()); 240*38fd1498Szrj } 241*38fd1498Szrj } 242*38fd1498Szrj __catch(...) 243*38fd1498Szrj { 244*38fd1498Szrj delete [] __c; 245*38fd1498Szrj __throw_exception_again; 246*38fd1498Szrj } 247*38fd1498Szrj 248*38fd1498Szrj delete [] __c; 249*38fd1498Szrj 250*38fd1498Szrj return __ret; 251*38fd1498Szrj } 252*38fd1498Szrj 253*38fd1498Szrj template<typename _CharT> 254*38fd1498Szrj long 255*38fd1498Szrj collate<_CharT>:: do_hash(const _CharT * __lo,const _CharT * __hi) const256*38fd1498Szrj do_hash(const _CharT* __lo, const _CharT* __hi) const 257*38fd1498Szrj { 258*38fd1498Szrj unsigned long __val = 0; 259*38fd1498Szrj for (; __lo < __hi; ++__lo) 260*38fd1498Szrj __val = 261*38fd1498Szrj *__lo + ((__val << 7) 262*38fd1498Szrj | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>:: 263*38fd1498Szrj __digits - 7))); 264*38fd1498Szrj return static_cast<long>(__val); 265*38fd1498Szrj } 266*38fd1498Szrj 267*38fd1498Szrj // Inhibit implicit instantiations for required instantiations, 268*38fd1498Szrj // which are defined via explicit instantiations elsewhere. 269*38fd1498Szrj #if _GLIBCXX_EXTERN_TEMPLATE 270*38fd1498Szrj extern template class collate<char>; 271*38fd1498Szrj extern template class collate_byname<char>; 272*38fd1498Szrj 273*38fd1498Szrj extern template 274*38fd1498Szrj const collate<char>& 275*38fd1498Szrj use_facet<collate<char> >(const locale&); 276*38fd1498Szrj 277*38fd1498Szrj extern template 278*38fd1498Szrj bool 279*38fd1498Szrj has_facet<collate<char> >(const locale&); 280*38fd1498Szrj 281*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 282*38fd1498Szrj extern template class collate<wchar_t>; 283*38fd1498Szrj extern template class collate_byname<wchar_t>; 284*38fd1498Szrj 285*38fd1498Szrj extern template 286*38fd1498Szrj const collate<wchar_t>& 287*38fd1498Szrj use_facet<collate<wchar_t> >(const locale&); 288*38fd1498Szrj 289*38fd1498Szrj extern template 290*38fd1498Szrj bool 291*38fd1498Szrj has_facet<collate<wchar_t> >(const locale&); 292*38fd1498Szrj #endif 293*38fd1498Szrj #endif 294*38fd1498Szrj 295*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 296*38fd1498Szrj } // namespace std 297*38fd1498Szrj 298*38fd1498Szrj #endif 299