]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libstdc++-v3/contrib/libstdc++-v3-4.3.3/include/bits/locale_classes.tcc
update
[l4.git] / l4 / pkg / libstdc++-v3 / contrib / libstdc++-v3-4.3.3 / include / bits / locale_classes.tcc
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     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