libstdc++
|
00001 // Locale support -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/locale_classes.tcc 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{locale} 00028 */ 00029 00030 // 00031 // ISO C++ 14882: 22.1 Locales 00032 // 00033 00034 #ifndef _LOCALE_CLASSES_TCC 00035 #define _LOCALE_CLASSES_TCC 1 00036 00037 #pragma GCC system_header 00038 00039 namespace std _GLIBCXX_VISIBILITY(default) 00040 { 00041 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00042 00043 template<typename _Facet> 00044 locale:: 00045 locale(const locale& __other, _Facet* __f) 00046 { 00047 _M_impl = new _Impl(*__other._M_impl, 1); 00048 00049 __try 00050 { _M_impl->_M_install_facet(&_Facet::id, __f); } 00051 __catch(...) 00052 { 00053 _M_impl->_M_remove_reference(); 00054 __throw_exception_again; 00055 } 00056 delete [] _M_impl->_M_names[0]; 00057 _M_impl->_M_names[0] = 0; // Unnamed. 00058 } 00059 00060 template<typename _Facet> 00061 locale 00062 locale:: 00063 combine(const locale& __other) const 00064 { 00065 _Impl* __tmp = new _Impl(*_M_impl, 1); 00066 __try 00067 { 00068 __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); 00069 } 00070 __catch(...) 00071 { 00072 __tmp->_M_remove_reference(); 00073 __throw_exception_again; 00074 } 00075 return locale(__tmp); 00076 } 00077 00078 template<typename _CharT, typename _Traits, typename _Alloc> 00079 bool 00080 locale:: 00081 operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, 00082 const basic_string<_CharT, _Traits, _Alloc>& __s2) const 00083 { 00084 typedef std::collate<_CharT> __collate_type; 00085 const __collate_type& __collate = use_facet<__collate_type>(*this); 00086 return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), 00087 __s2.data(), __s2.data() + __s2.length()) < 0); 00088 } 00089 00090 00091 template<typename _Facet> 00092 bool 00093 has_facet(const locale& __loc) throw() 00094 { 00095 const size_t __i = _Facet::id._M_id(); 00096 const locale::facet** __facets = __loc._M_impl->_M_facets; 00097 return (__i < __loc._M_impl->_M_facets_size 00098 #ifdef __GXX_RTTI 00099 && dynamic_cast<const _Facet*>(__facets[__i])); 00100 #else 00101 && static_cast<const _Facet*>(__facets[__i])); 00102 #endif 00103 } 00104 00105 template<typename _Facet> 00106 const _Facet& 00107 use_facet(const locale& __loc) 00108 { 00109 const size_t __i = _Facet::id._M_id(); 00110 const locale::facet** __facets = __loc._M_impl->_M_facets; 00111 if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i]) 00112 __throw_bad_cast(); 00113 #ifdef __GXX_RTTI 00114 return dynamic_cast<const _Facet&>(*__facets[__i]); 00115 #else 00116 return static_cast<const _Facet&>(*__facets[__i]); 00117 #endif 00118 } 00119 00120 00121 // Generic version does nothing. 00122 template<typename _CharT> 00123 int 00124 collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw () 00125 { return 0; } 00126 00127 // Generic version does nothing. 00128 template<typename _CharT> 00129 size_t 00130 collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw () 00131 { return 0; } 00132 00133 template<typename _CharT> 00134 int 00135 collate<_CharT>:: 00136 do_compare(const _CharT* __lo1, const _CharT* __hi1, 00137 const _CharT* __lo2, const _CharT* __hi2) const 00138 { 00139 // strcoll assumes zero-terminated strings so we make a copy 00140 // and then put a zero at the end. 00141 const string_type __one(__lo1, __hi1); 00142 const string_type __two(__lo2, __hi2); 00143 00144 const _CharT* __p = __one.c_str(); 00145 const _CharT* __pend = __one.data() + __one.length(); 00146 const _CharT* __q = __two.c_str(); 00147 const _CharT* __qend = __two.data() + __two.length(); 00148 00149 // strcoll stops when it sees a nul character so we break 00150 // the strings into zero-terminated substrings and pass those 00151 // to strcoll. 00152 for (;;) 00153 { 00154 const int __res = _M_compare(__p, __q); 00155 if (__res) 00156 return __res; 00157 00158 __p += char_traits<_CharT>::length(__p); 00159 __q += char_traits<_CharT>::length(__q); 00160 if (__p == __pend && __q == __qend) 00161 return 0; 00162 else if (__p == __pend) 00163 return -1; 00164 else if (__q == __qend) 00165 return 1; 00166 00167 __p++; 00168 __q++; 00169 } 00170 } 00171 00172 template<typename _CharT> 00173 typename collate<_CharT>::string_type 00174 collate<_CharT>:: 00175 do_transform(const _CharT* __lo, const _CharT* __hi) const 00176 { 00177 string_type __ret; 00178 00179 // strxfrm assumes zero-terminated strings so we make a copy 00180 const string_type __str(__lo, __hi); 00181 00182 const _CharT* __p = __str.c_str(); 00183 const _CharT* __pend = __str.data() + __str.length(); 00184 00185 size_t __len = (__hi - __lo) * 2; 00186 00187 _CharT* __c = new _CharT[__len]; 00188 00189 __try 00190 { 00191 // strxfrm stops when it sees a nul character so we break 00192 // the string into zero-terminated substrings and pass those 00193 // to strxfrm. 00194 for (;;) 00195 { 00196 // First try a buffer perhaps big enough. 00197 size_t __res = _M_transform(__c, __p, __len); 00198 // If the buffer was not large enough, try again with the 00199 // correct size. 00200 if (__res >= __len) 00201 { 00202 __len = __res + 1; 00203 delete [] __c, __c = 0; 00204 __c = new _CharT[__len]; 00205 __res = _M_transform(__c, __p, __len); 00206 } 00207 00208 __ret.append(__c, __res); 00209 __p += char_traits<_CharT>::length(__p); 00210 if (__p == __pend) 00211 break; 00212 00213 __p++; 00214 __ret.push_back(_CharT()); 00215 } 00216 } 00217 __catch(...) 00218 { 00219 delete [] __c; 00220 __throw_exception_again; 00221 } 00222 00223 delete [] __c; 00224 00225 return __ret; 00226 } 00227 00228 template<typename _CharT> 00229 long 00230 collate<_CharT>:: 00231 do_hash(const _CharT* __lo, const _CharT* __hi) const 00232 { 00233 unsigned long __val = 0; 00234 for (; __lo < __hi; ++__lo) 00235 __val = 00236 *__lo + ((__val << 7) 00237 | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>:: 00238 __digits - 7))); 00239 return static_cast<long>(__val); 00240 } 00241 00242 // Inhibit implicit instantiations for required instantiations, 00243 // which are defined via explicit instantiations elsewhere. 00244 #if _GLIBCXX_EXTERN_TEMPLATE 00245 extern template class collate<char>; 00246 extern template class collate_byname<char>; 00247 00248 extern template 00249 const collate<char>& 00250 use_facet<collate<char> >(const locale&); 00251 00252 extern template 00253 bool 00254 has_facet<collate<char> >(const locale&); 00255 00256 #ifdef _GLIBCXX_USE_WCHAR_T 00257 extern template class collate<wchar_t>; 00258 extern template class collate_byname<wchar_t>; 00259 00260 extern template 00261 const collate<wchar_t>& 00262 use_facet<collate<wchar_t> >(const locale&); 00263 00264 extern template 00265 bool 00266 has_facet<collate<wchar_t> >(const locale&); 00267 #endif 00268 #endif 00269 00270 _GLIBCXX_END_NAMESPACE_VERSION 00271 } // namespace std 00272 00273 #endif