libstdc++
|
00001 // Locale support -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009 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 locale_classes.tcc 00026 * This is an internal header file, included by other library headers. 00027 * You should not attempt to use it directly. 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 _GLIBCXX_BEGIN_NAMESPACE(std) 00040 00041 template<typename _Facet> 00042 locale:: 00043 locale(const locale& __other, _Facet* __f) 00044 { 00045 _M_impl = new _Impl(*__other._M_impl, 1); 00046 00047 __try 00048 { _M_impl->_M_install_facet(&_Facet::id, __f); } 00049 __catch(...) 00050 { 00051 _M_impl->_M_remove_reference(); 00052 __throw_exception_again; 00053 } 00054 delete [] _M_impl->_M_names[0]; 00055 _M_impl->_M_names[0] = 0; // Unnamed. 00056 } 00057 00058 template<typename _Facet> 00059 locale 00060 locale:: 00061 combine(const locale& __other) const 00062 { 00063 _Impl* __tmp = new _Impl(*_M_impl, 1); 00064 __try 00065 { 00066 __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); 00067 } 00068 __catch(...) 00069 { 00070 __tmp->_M_remove_reference(); 00071 __throw_exception_again; 00072 } 00073 return locale(__tmp); 00074 } 00075 00076 template<typename _CharT, typename _Traits, typename _Alloc> 00077 bool 00078 locale:: 00079 operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, 00080 const basic_string<_CharT, _Traits, _Alloc>& __s2) const 00081 { 00082 typedef std::collate<_CharT> __collate_type; 00083 const __collate_type& __collate = use_facet<__collate_type>(*this); 00084 return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), 00085 __s2.data(), __s2.data() + __s2.length()) < 0); 00086 } 00087 00088 00089 template<typename _Facet> 00090 bool 00091 has_facet(const locale& __loc) throw() 00092 { 00093 const size_t __i = _Facet::id._M_id(); 00094 const locale::facet** __facets = __loc._M_impl->_M_facets; 00095 return (__i < __loc._M_impl->_M_facets_size 00096 #ifdef __GXX_RTTI 00097 && dynamic_cast<const _Facet*>(__facets[__i])); 00098 #else 00099 && static_cast<const _Facet*>(__facets[__i])); 00100 #endif 00101 } 00102 00103 template<typename _Facet> 00104 const _Facet& 00105 use_facet(const locale& __loc) 00106 { 00107 const size_t __i = _Facet::id._M_id(); 00108 const locale::facet** __facets = __loc._M_impl->_M_facets; 00109 if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i]) 00110 __throw_bad_cast(); 00111 #ifdef __GXX_RTTI 00112 return dynamic_cast<const _Facet&>(*__facets[__i]); 00113 #else 00114 return static_cast<const _Facet&>(*__facets[__i]); 00115 #endif 00116 } 00117 00118 00119 // Generic version does nothing. 00120 template<typename _CharT> 00121 int 00122 collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const 00123 { return 0; } 00124 00125 // Generic version does nothing. 00126 template<typename _CharT> 00127 size_t 00128 collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const 00129 { return 0; } 00130 00131 template<typename _CharT> 00132 int 00133 collate<_CharT>:: 00134 do_compare(const _CharT* __lo1, const _CharT* __hi1, 00135 const _CharT* __lo2, const _CharT* __hi2) const 00136 { 00137 // strcoll assumes zero-terminated strings so we make a copy 00138 // and then put a zero at the end. 00139 const string_type __one(__lo1, __hi1); 00140 const string_type __two(__lo2, __hi2); 00141 00142 const _CharT* __p = __one.c_str(); 00143 const _CharT* __pend = __one.data() + __one.length(); 00144 const _CharT* __q = __two.c_str(); 00145 const _CharT* __qend = __two.data() + __two.length(); 00146 00147 // strcoll stops when it sees a nul character so we break 00148 // the strings into zero-terminated substrings and pass those 00149 // to strcoll. 00150 for (;;) 00151 { 00152 const int __res = _M_compare(__p, __q); 00153 if (__res) 00154 return __res; 00155 00156 __p += char_traits<_CharT>::length(__p); 00157 __q += char_traits<_CharT>::length(__q); 00158 if (__p == __pend && __q == __qend) 00159 return 0; 00160 else if (__p == __pend) 00161 return -1; 00162 else if (__q == __qend) 00163 return 1; 00164 00165 __p++; 00166 __q++; 00167 } 00168 } 00169 00170 template<typename _CharT> 00171 typename collate<_CharT>::string_type 00172 collate<_CharT>:: 00173 do_transform(const _CharT* __lo, const _CharT* __hi) const 00174 { 00175 string_type __ret; 00176 00177 // strxfrm assumes zero-terminated strings so we make a copy 00178 const string_type __str(__lo, __hi); 00179 00180 const _CharT* __p = __str.c_str(); 00181 const _CharT* __pend = __str.data() + __str.length(); 00182 00183 size_t __len = (__hi - __lo) * 2; 00184 00185 _CharT* __c = new _CharT[__len]; 00186 00187 __try 00188 { 00189 // strxfrm stops when it sees a nul character so we break 00190 // the string into zero-terminated substrings and pass those 00191 // to strxfrm. 00192 for (;;) 00193 { 00194 // First try a buffer perhaps big enough. 00195 size_t __res = _M_transform(__c, __p, __len); 00196 // If the buffer was not large enough, try again with the 00197 // correct size. 00198 if (__res >= __len) 00199 { 00200 __len = __res + 1; 00201 delete [] __c, __c = 0; 00202 __c = new _CharT[__len]; 00203 __res = _M_transform(__c, __p, __len); 00204 } 00205 00206 __ret.append(__c, __res); 00207 __p += char_traits<_CharT>::length(__p); 00208 if (__p == __pend) 00209 break; 00210 00211 __p++; 00212 __ret.push_back(_CharT()); 00213 } 00214 } 00215 __catch(...) 00216 { 00217 delete [] __c; 00218 __throw_exception_again; 00219 } 00220 00221 delete [] __c; 00222 00223 return __ret; 00224 } 00225 00226 template<typename _CharT> 00227 long 00228 collate<_CharT>:: 00229 do_hash(const _CharT* __lo, const _CharT* __hi) const 00230 { 00231 unsigned long __val = 0; 00232 for (; __lo < __hi; ++__lo) 00233 __val = 00234 *__lo + ((__val << 7) 00235 | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>:: 00236 __digits - 7))); 00237 return static_cast<long>(__val); 00238 } 00239 00240 // Inhibit implicit instantiations for required instantiations, 00241 // which are defined via explicit instantiations elsewhere. 00242 // NB: This syntax is a GNU extension. 00243 #if _GLIBCXX_EXTERN_TEMPLATE 00244 extern template class collate<char>; 00245 extern template class collate_byname<char>; 00246 00247 extern template 00248 const collate<char>& 00249 use_facet<collate<char> >(const locale&); 00250 00251 extern template 00252 bool 00253 has_facet<collate<char> >(const locale&); 00254 00255 #ifdef _GLIBCXX_USE_WCHAR_T 00256 extern template class collate<wchar_t>; 00257 extern template class collate_byname<wchar_t>; 00258 00259 extern template 00260 const collate<wchar_t>& 00261 use_facet<collate<wchar_t> >(const locale&); 00262 00263 extern template 00264 bool 00265 has_facet<collate<wchar_t> >(const locale&); 00266 #endif 00267 #endif 00268 00269 _GLIBCXX_END_NAMESPACE 00270 00271 #endif