]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/include/bits/locale_classes.tcc
re PR libstdc++/25191 (exception_defines.h #defines try/catch)
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / locale_classes.tcc
1 // Locale support -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 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 has_facet(const locale& __loc) throw()
97 {
98 const size_t __i = _Facet::id._M_id();
99 const locale::facet** __facets = __loc._M_impl->_M_facets;
100 return (__i < __loc._M_impl->_M_facets_size
101 #ifdef __GXX_RTTI
102 && 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 use_facet(const locale& __loc)
111 {
112 const size_t __i = _Facet::id._M_id();
113 const locale::facet** __facets = __loc._M_impl->_M_facets;
114 if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
115 __throw_bad_cast();
116 #ifdef __GXX_RTTI
117 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 collate<char>;
250 extern template class 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 collate<wchar_t>;
262 extern template class 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