Branch data Line data Source code
1 : : // Locale support -*- C++ -*-
2 : :
3 : : // Copyright (C) 2007, 2008 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 2, 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 : : // You should have received a copy of the GNU General Public License along
17 : : // with this library; see the file COPYING. If not, write to the Free
18 : : // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 : : // USA.
20 : :
21 : : // As a special exception, you may use this file as part of a free software
22 : : // library without restriction. Specifically, if other files instantiate
23 : : // templates or use macros or inline functions from this file, or you compile
24 : : // this file and link it with other files to produce an executable, this
25 : : // file does not by itself cause the resulting executable to be covered by
26 : : // the GNU General Public License. This exception does not however
27 : : // invalidate any other reasons why the executable file might be covered by
28 : : // the GNU General Public License.
29 : :
30 : : /** @file locale_classes.tcc
31 : : * This is an internal header file, included by other library headers.
32 : : * You should not attempt to use it directly.
33 : : */
34 : :
35 : : //
36 : : // ISO C++ 14882: 22.1 Locales
37 : : //
38 : :
39 : : #ifndef _LOCALE_CLASSES_TCC
40 : : #define _LOCALE_CLASSES_TCC 1
41 : :
42 : : #pragma GCC system_header
43 : :
44 : : _GLIBCXX_BEGIN_NAMESPACE(std)
45 : :
46 : : template<typename _Facet>
47 : : locale::
48 : : locale(const locale& __other, _Facet* __f)
49 : : {
50 : : _M_impl = new _Impl(*__other._M_impl, 1);
51 : :
52 : : try
53 : : { _M_impl->_M_install_facet(&_Facet::id, __f); }
54 : : catch(...)
55 : : {
56 : : _M_impl->_M_remove_reference();
57 : : __throw_exception_again;
58 : : }
59 : : delete [] _M_impl->_M_names[0];
60 : : _M_impl->_M_names[0] = 0; // Unnamed.
61 : : }
62 : :
63 : : template<typename _Facet>
64 : : locale
65 : : locale::
66 : : combine(const locale& __other) const
67 : : {
68 : : _Impl* __tmp = new _Impl(*_M_impl, 1);
69 : : try
70 : : {
71 : : __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
72 : : }
73 : : catch(...)
74 : : {
75 : : __tmp->_M_remove_reference();
76 : : __throw_exception_again;
77 : : }
78 : : return locale(__tmp);
79 : : }
80 : :
81 : : template<typename _CharT, typename _Traits, typename _Alloc>
82 : : bool
83 : : locale::
84 : : operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
85 : : const basic_string<_CharT, _Traits, _Alloc>& __s2) const
86 : : {
87 : : typedef std::collate<_CharT> __collate_type;
88 : : const __collate_type& __collate = use_facet<__collate_type>(*this);
89 : : return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
90 : : __s2.data(), __s2.data() + __s2.length()) < 0);
91 : : }
92 : :
93 : :
94 : : template<typename _Facet>
95 : : bool
96 : 0 : has_facet(const locale& __loc) throw()
97 : : {
98 : 0 : const size_t __i = _Facet::id._M_id();
99 : 0 : const locale::facet** __facets = __loc._M_impl->_M_facets;
100 : : return (__i < __loc._M_impl->_M_facets_size
101 : : #ifdef __GXX_RTTI
102 [ # # ][ # # ]: 0 : && dynamic_cast<const _Facet*>(__facets[__i]));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
103 : : #else
104 : : && static_cast<const _Facet*>(__facets[__i]));
105 : : #endif
106 : : }
107 : :
108 : : template<typename _Facet>
109 : : const _Facet&
110 : 0 : use_facet(const locale& __loc)
111 : : {
112 : 0 : const size_t __i = _Facet::id._M_id();
113 : 0 : const locale::facet** __facets = __loc._M_impl->_M_facets;
114 [ # # ]: 0 : if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
[ # # # # ]
[ # # # # ]
[ # # ]
115 : 0 : __throw_bad_cast();
116 : : #ifdef __GXX_RTTI
117 [ # # ][ # # ]: 0 : return dynamic_cast<const _Facet&>(*__facets[__i]);
[ # # ]
118 : : #else
119 : : return static_cast<const _Facet&>(*__facets[__i]);
120 : : #endif
121 : : }
122 : :
123 : :
124 : : // Generic version does nothing.
125 : : template<typename _CharT>
126 : : int
127 : : collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
128 : : { return 0; }
129 : :
130 : : // Generic version does nothing.
131 : : template<typename _CharT>
132 : : size_t
133 : : collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
134 : : { return 0; }
135 : :
136 : : template<typename _CharT>
137 : : int
138 : : collate<_CharT>::
139 : : do_compare(const _CharT* __lo1, const _CharT* __hi1,
140 : : const _CharT* __lo2, const _CharT* __hi2) const
141 : : {
142 : : // strcoll assumes zero-terminated strings so we make a copy
143 : : // and then put a zero at the end.
144 : : const string_type __one(__lo1, __hi1);
145 : : const string_type __two(__lo2, __hi2);
146 : :
147 : : const _CharT* __p = __one.c_str();
148 : : const _CharT* __pend = __one.data() + __one.length();
149 : : const _CharT* __q = __two.c_str();
150 : : const _CharT* __qend = __two.data() + __two.length();
151 : :
152 : : // strcoll stops when it sees a nul character so we break
153 : : // the strings into zero-terminated substrings and pass those
154 : : // to strcoll.
155 : : for (;;)
156 : : {
157 : : const int __res = _M_compare(__p, __q);
158 : : if (__res)
159 : : return __res;
160 : :
161 : : __p += char_traits<_CharT>::length(__p);
162 : : __q += char_traits<_CharT>::length(__q);
163 : : if (__p == __pend && __q == __qend)
164 : : return 0;
165 : : else if (__p == __pend)
166 : : return -1;
167 : : else if (__q == __qend)
168 : : return 1;
169 : :
170 : : __p++;
171 : : __q++;
172 : : }
173 : : }
174 : :
175 : : template<typename _CharT>
176 : : typename collate<_CharT>::string_type
177 : : collate<_CharT>::
178 : : do_transform(const _CharT* __lo, const _CharT* __hi) const
179 : : {
180 : : string_type __ret;
181 : :
182 : : // strxfrm assumes zero-terminated strings so we make a copy
183 : : const string_type __str(__lo, __hi);
184 : :
185 : : const _CharT* __p = __str.c_str();
186 : : const _CharT* __pend = __str.data() + __str.length();
187 : :
188 : : size_t __len = (__hi - __lo) * 2;
189 : :
190 : : _CharT* __c = new _CharT[__len];
191 : :
192 : : try
193 : : {
194 : : // strxfrm stops when it sees a nul character so we break
195 : : // the string into zero-terminated substrings and pass those
196 : : // to strxfrm.
197 : : for (;;)
198 : : {
199 : : // First try a buffer perhaps big enough.
200 : : size_t __res = _M_transform(__c, __p, __len);
201 : : // If the buffer was not large enough, try again with the
202 : : // correct size.
203 : : if (__res >= __len)
204 : : {
205 : : __len = __res + 1;
206 : : delete [] __c, __c = 0;
207 : : __c = new _CharT[__len];
208 : : __res = _M_transform(__c, __p, __len);
209 : : }
210 : :
211 : : __ret.append(__c, __res);
212 : : __p += char_traits<_CharT>::length(__p);
213 : : if (__p == __pend)
214 : : break;
215 : :
216 : : __p++;
217 : : __ret.push_back(_CharT());
218 : : }
219 : : }
220 : : catch(...)
221 : : {
222 : : delete [] __c;
223 : : __throw_exception_again;
224 : : }
225 : :
226 : : delete [] __c;
227 : :
228 : : return __ret;
229 : : }
230 : :
231 : : template<typename _CharT>
232 : : long
233 : : collate<_CharT>::
234 : : do_hash(const _CharT* __lo, const _CharT* __hi) const
235 : : {
236 : : unsigned long __val = 0;
237 : : for (; __lo < __hi; ++__lo)
238 : : __val =
239 : : *__lo + ((__val << 7)
240 : : | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
241 : : __digits - 7)));
242 : : return static_cast<long>(__val);
243 : : }
244 : :
245 : : // Inhibit implicit instantiations for required instantiations,
246 : : // which are defined via explicit instantiations elsewhere.
247 : : // NB: This syntax is a GNU extension.
248 : : #if _GLIBCXX_EXTERN_TEMPLATE
249 : : extern template class _GLIBCXX_IMPORT collate<char>;
250 : : extern template class _GLIBCXX_IMPORT collate_byname<char>;
251 : :
252 : : extern template
253 : : const collate<char>&
254 : : use_facet<collate<char> >(const locale&);
255 : :
256 : : extern template
257 : : bool
258 : : has_facet<collate<char> >(const locale&);
259 : :
260 : : #ifdef _GLIBCXX_USE_WCHAR_T
261 : : extern template class _GLIBCXX_IMPORT collate<wchar_t>;
262 : : extern template class _GLIBCXX_IMPORT collate_byname<wchar_t>;
263 : :
264 : : extern template
265 : : const collate<wchar_t>&
266 : : use_facet<collate<wchar_t> >(const locale&);
267 : :
268 : : extern template
269 : : bool
270 : : has_facet<collate<wchar_t> >(const locale&);
271 : : #endif
272 : : #endif
273 : :
274 : : _GLIBCXX_END_NAMESPACE
275 : :
276 : : #endif
|