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