libstdc++
locale_classes.tcc
Go to the documentation of this file.
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 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 locale_classes.tcc
26  * This is an internal header file, included by other library headers.
27  * You should not attempt to use it directly.
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 _GLIBCXX_BEGIN_NAMESPACE(std)
40 
41  template<typename _Facet>
42  locale::
43  locale(const locale& __other, _Facet* __f)
44  {
45  _M_impl = new _Impl(*__other._M_impl, 1);
46 
47  __try
48  { _M_impl->_M_install_facet(&_Facet::id, __f); }
49  __catch(...)
50  {
51  _M_impl->_M_remove_reference();
52  __throw_exception_again;
53  }
54  delete [] _M_impl->_M_names[0];
55  _M_impl->_M_names[0] = 0; // Unnamed.
56  }
57 
58  template<typename _Facet>
59  locale
60  locale::
61  combine(const locale& __other) const
62  {
63  _Impl* __tmp = new _Impl(*_M_impl, 1);
64  __try
65  {
66  __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
67  }
68  __catch(...)
69  {
70  __tmp->_M_remove_reference();
71  __throw_exception_again;
72  }
73  return locale(__tmp);
74  }
75 
76  template<typename _CharT, typename _Traits, typename _Alloc>
77  bool
78  locale::
79  operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
80  const basic_string<_CharT, _Traits, _Alloc>& __s2) const
81  {
82  typedef std::collate<_CharT> __collate_type;
83  const __collate_type& __collate = use_facet<__collate_type>(*this);
84  return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
85  __s2.data(), __s2.data() + __s2.length()) < 0);
86  }
87 
88 
89  template<typename _Facet>
90  bool
91  has_facet(const locale& __loc) throw()
92  {
93  const size_t __i = _Facet::id._M_id();
94  const locale::facet** __facets = __loc._M_impl->_M_facets;
95  return (__i < __loc._M_impl->_M_facets_size
96 #ifdef __GXX_RTTI
97  && dynamic_cast<const _Facet*>(__facets[__i]));
98 #else
99  && static_cast<const _Facet*>(__facets[__i]));
100 #endif
101  }
102 
103  template<typename _Facet>
104  const _Facet&
105  use_facet(const locale& __loc)
106  {
107  const size_t __i = _Facet::id._M_id();
108  const locale::facet** __facets = __loc._M_impl->_M_facets;
109  if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
110  __throw_bad_cast();
111 #ifdef __GXX_RTTI
112  return dynamic_cast<const _Facet&>(*__facets[__i]);
113 #else
114  return static_cast<const _Facet&>(*__facets[__i]);
115 #endif
116  }
117 
118 
119  // Generic version does nothing.
120  template<typename _CharT>
121  int
122  collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const
123  { return 0; }
124 
125  // Generic version does nothing.
126  template<typename _CharT>
127  size_t
128  collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const
129  { return 0; }
130 
131  template<typename _CharT>
132  int
133  collate<_CharT>::
134  do_compare(const _CharT* __lo1, const _CharT* __hi1,
135  const _CharT* __lo2, const _CharT* __hi2) const
136  {
137  // strcoll assumes zero-terminated strings so we make a copy
138  // and then put a zero at the end.
139  const string_type __one(__lo1, __hi1);
140  const string_type __two(__lo2, __hi2);
141 
142  const _CharT* __p = __one.c_str();
143  const _CharT* __pend = __one.data() + __one.length();
144  const _CharT* __q = __two.c_str();
145  const _CharT* __qend = __two.data() + __two.length();
146 
147  // strcoll stops when it sees a nul character so we break
148  // the strings into zero-terminated substrings and pass those
149  // to strcoll.
150  for (;;)
151  {
152  const int __res = _M_compare(__p, __q);
153  if (__res)
154  return __res;
155 
156  __p += char_traits<_CharT>::length(__p);
157  __q += char_traits<_CharT>::length(__q);
158  if (__p == __pend && __q == __qend)
159  return 0;
160  else if (__p == __pend)
161  return -1;
162  else if (__q == __qend)
163  return 1;
164 
165  __p++;
166  __q++;
167  }
168  }
169 
170  template<typename _CharT>
173  do_transform(const _CharT* __lo, const _CharT* __hi) const
174  {
175  string_type __ret;
176 
177  // strxfrm assumes zero-terminated strings so we make a copy
178  const string_type __str(__lo, __hi);
179 
180  const _CharT* __p = __str.c_str();
181  const _CharT* __pend = __str.data() + __str.length();
182 
183  size_t __len = (__hi - __lo) * 2;
184 
185  _CharT* __c = new _CharT[__len];
186 
187  __try
188  {
189  // strxfrm stops when it sees a nul character so we break
190  // the string into zero-terminated substrings and pass those
191  // to strxfrm.
192  for (;;)
193  {
194  // First try a buffer perhaps big enough.
195  size_t __res = _M_transform(__c, __p, __len);
196  // If the buffer was not large enough, try again with the
197  // correct size.
198  if (__res >= __len)
199  {
200  __len = __res + 1;
201  delete [] __c, __c = 0;
202  __c = new _CharT[__len];
203  __res = _M_transform(__c, __p, __len);
204  }
205 
206  __ret.append(__c, __res);
207  __p += char_traits<_CharT>::length(__p);
208  if (__p == __pend)
209  break;
210 
211  __p++;
212  __ret.push_back(_CharT());
213  }
214  }
215  __catch(...)
216  {
217  delete [] __c;
218  __throw_exception_again;
219  }
220 
221  delete [] __c;
222 
223  return __ret;
224  }
225 
226  template<typename _CharT>
227  long
229  do_hash(const _CharT* __lo, const _CharT* __hi) const
230  {
231  unsigned long __val = 0;
232  for (; __lo < __hi; ++__lo)
233  __val =
234  *__lo + ((__val << 7)
235  | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
236  __digits - 7)));
237  return static_cast<long>(__val);
238  }
239 
240  // Inhibit implicit instantiations for required instantiations,
241  // which are defined via explicit instantiations elsewhere.
242  // NB: This syntax is a GNU extension.
243 #if _GLIBCXX_EXTERN_TEMPLATE
244  extern template class collate<char>;
245  extern template class collate_byname<char>;
246 
247  extern template
248  const collate<char>&
249  use_facet<collate<char> >(const locale&);
250 
251  extern template
252  bool
253  has_facet<collate<char> >(const locale&);
254 
255 #ifdef _GLIBCXX_USE_WCHAR_T
256  extern template class collate<wchar_t>;
257  extern template class collate_byname<wchar_t>;
258 
259  extern template
260  const collate<wchar_t>&
261  use_facet<collate<wchar_t> >(const locale&);
262 
263  extern template
264  bool
265  has_facet<collate<wchar_t> >(const locale&);
266 #endif
267 #endif
268 
269 _GLIBCXX_END_NAMESPACE
270 
271 #endif
const _CharT * c_str() const
Return const pointer to null-terminated contents.
size_type length() const
Returns the number of characters in the string, not including any null-termination.
Definition: basic_string.h:634
Localization functionality base class.
const _CharT * data() const
Return const pointer to contents.
bool has_facet(const locale &__loc)
Test for the presence of a facet.
const _Facet & use_facet(const locale &__loc)
Return a facet.
void push_back(_CharT __c)
Append a single character.
Definition: basic_string.h:914
class collate_byname [22.2.4.2].
Container class for localization functionality.
basic_string & append(const basic_string &__str)
Append a string to this string.
Facet for localized string comparison.
Managing sequences of characters and character-like objects.
Definition: basic_string.h:104
Basis for explicit traits specializations.
Definition: char_traits.h:231