]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.6/include/bits/locale_classes.tcc
update
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.6 / include / bits / locale_classes.tcc
1 // Locale support -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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
39 namespace 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   template<typename _Facet>
92     bool
93     has_facet(const locale& __loc) throw()
94     {
95       const size_t __i = _Facet::id._M_id();
96       const locale::facet** __facets = __loc._M_impl->_M_facets;
97       return (__i < __loc._M_impl->_M_facets_size
98 #ifdef __GXX_RTTI
99               && dynamic_cast<const _Facet*>(__facets[__i]));
100 #else
101               && static_cast<const _Facet*>(__facets[__i]));
102 #endif
103     }
104
105   template<typename _Facet>
106     const _Facet&
107     use_facet(const locale& __loc)
108     {
109       const size_t __i = _Facet::id._M_id();
110       const locale::facet** __facets = __loc._M_impl->_M_facets;
111       if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
112         __throw_bad_cast();
113 #ifdef __GXX_RTTI
114       return dynamic_cast<const _Facet&>(*__facets[__i]);
115 #else
116       return static_cast<const _Facet&>(*__facets[__i]);
117 #endif
118     }
119
120
121   // Generic version does nothing.
122   template<typename _CharT>
123     int
124     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw ()
125     { return 0; }
126
127   // Generic version does nothing.
128   template<typename _CharT>
129     size_t
130     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw ()
131     { return 0; }
132
133   template<typename _CharT>
134     int
135     collate<_CharT>::
136     do_compare(const _CharT* __lo1, const _CharT* __hi1,
137                const _CharT* __lo2, const _CharT* __hi2) const
138     {
139       // strcoll assumes zero-terminated strings so we make a copy
140       // and then put a zero at the end.
141       const string_type __one(__lo1, __hi1);
142       const string_type __two(__lo2, __hi2);
143
144       const _CharT* __p = __one.c_str();
145       const _CharT* __pend = __one.data() + __one.length();
146       const _CharT* __q = __two.c_str();
147       const _CharT* __qend = __two.data() + __two.length();
148
149       // strcoll stops when it sees a nul character so we break
150       // the strings into zero-terminated substrings and pass those
151       // to strcoll.
152       for (;;)
153         {
154           const int __res = _M_compare(__p, __q);
155           if (__res)
156             return __res;
157
158           __p += char_traits<_CharT>::length(__p);
159           __q += char_traits<_CharT>::length(__q);
160           if (__p == __pend && __q == __qend)
161             return 0;
162           else if (__p == __pend)
163             return -1;
164           else if (__q == __qend)
165             return 1;
166
167           __p++;
168           __q++;
169         }
170     }
171
172   template<typename _CharT>
173     typename collate<_CharT>::string_type
174     collate<_CharT>::
175     do_transform(const _CharT* __lo, const _CharT* __hi) const
176     {
177       string_type __ret;
178
179       // strxfrm assumes zero-terminated strings so we make a copy
180       const string_type __str(__lo, __hi);
181
182       const _CharT* __p = __str.c_str();
183       const _CharT* __pend = __str.data() + __str.length();
184
185       size_t __len = (__hi - __lo) * 2;
186
187       _CharT* __c = new _CharT[__len];
188
189       __try
190         {
191           // strxfrm stops when it sees a nul character so we break
192           // the string into zero-terminated substrings and pass those
193           // to strxfrm.
194           for (;;)
195             {
196               // First try a buffer perhaps big enough.
197               size_t __res = _M_transform(__c, __p, __len);
198               // If the buffer was not large enough, try again with the
199               // correct size.
200               if (__res >= __len)
201                 {
202                   __len = __res + 1;
203                   delete [] __c, __c = 0;
204                   __c = new _CharT[__len];
205                   __res = _M_transform(__c, __p, __len);
206                 }
207
208               __ret.append(__c, __res);
209               __p += char_traits<_CharT>::length(__p);
210               if (__p == __pend)
211                 break;
212
213               __p++;
214               __ret.push_back(_CharT());
215             }
216         }
217       __catch(...)
218         {
219           delete [] __c;
220           __throw_exception_again;
221         }
222
223       delete [] __c;
224
225       return __ret;
226     }
227
228   template<typename _CharT>
229     long
230     collate<_CharT>::
231     do_hash(const _CharT* __lo, const _CharT* __hi) const
232     {
233       unsigned long __val = 0;
234       for (; __lo < __hi; ++__lo)
235         __val =
236           *__lo + ((__val << 7)
237                    | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
238                                 __digits - 7)));
239       return static_cast<long>(__val);
240     }
241
242   // Inhibit implicit instantiations for required instantiations,
243   // which are defined via explicit instantiations elsewhere.
244 #if _GLIBCXX_EXTERN_TEMPLATE
245   extern template class collate<char>;
246   extern template class collate_byname<char>;
247
248   extern template
249     const collate<char>&
250     use_facet<collate<char> >(const locale&);
251
252   extern template
253     bool
254     has_facet<collate<char> >(const locale&);
255
256 #ifdef _GLIBCXX_USE_WCHAR_T
257   extern template class collate<wchar_t>;
258   extern template class collate_byname<wchar_t>;
259
260   extern template
261     const collate<wchar_t>&
262     use_facet<collate<wchar_t> >(const locale&);
263
264   extern template
265     bool
266     has_facet<collate<wchar_t> >(const locale&);
267 #endif
268 #endif
269
270 _GLIBCXX_END_NAMESPACE_VERSION
271 } // namespace std
272
273 #endif