1 // Locale support -*- C++ -*-
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
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)
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.
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.
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/>.
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}
31 // ISO C++ 14882: 22.1 Locales
34 #ifndef _LOCALE_CLASSES_TCC
35 #define _LOCALE_CLASSES_TCC 1
37 #pragma GCC system_header
39 namespace std _GLIBCXX_VISIBILITY(default)
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 template<typename _Facet>
45 locale(const locale& __other, _Facet* __f)
47 _M_impl = new _Impl(*__other._M_impl, 1);
50 { _M_impl->_M_install_facet(&_Facet::id, __f); }
53 _M_impl->_M_remove_reference();
54 __throw_exception_again;
56 delete [] _M_impl->_M_names[0];
57 _M_impl->_M_names[0] = 0; // Unnamed.
60 template<typename _Facet>
63 combine(const locale& __other) const
65 _Impl* __tmp = new _Impl(*_M_impl, 1);
68 __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
72 __tmp->_M_remove_reference();
73 __throw_exception_again;
78 template<typename _CharT, typename _Traits, typename _Alloc>
81 operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
82 const basic_string<_CharT, _Traits, _Alloc>& __s2) const
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);
91 * @brief Test for the presence of a facet.
93 * has_facet tests the locale argument for the presence of the facet type
94 * provided as the template parameter. Facets derived from the facet
95 * parameter will also return true.
97 * @tparam _Facet The facet type to test the presence of.
98 * @param __loc The locale to test.
99 * @return true if @p __loc contains a facet of type _Facet, else false.
101 template<typename _Facet>
103 has_facet(const locale& __loc) throw()
105 const size_t __i = _Facet::id._M_id();
106 const locale::facet** __facets = __loc._M_impl->_M_facets;
107 return (__i < __loc._M_impl->_M_facets_size
109 && dynamic_cast<const _Facet*>(__facets[__i]));
111 && static_cast<const _Facet*>(__facets[__i]));
116 * @brief Return a facet.
118 * use_facet looks for and returns a reference to a facet of type Facet
119 * where Facet is the template parameter. If has_facet(locale) is true,
120 * there is a suitable facet to return. It throws std::bad_cast if the
121 * locale doesn't contain a facet of type Facet.
123 * @tparam _Facet The facet type to access.
124 * @param __loc The locale to use.
125 * @return Reference to facet of type Facet.
126 * @throw std::bad_cast if @p __loc doesn't contain a facet of type _Facet.
128 template<typename _Facet>
130 use_facet(const locale& __loc)
132 const size_t __i = _Facet::id._M_id();
133 const locale::facet** __facets = __loc._M_impl->_M_facets;
134 if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
137 return dynamic_cast<const _Facet&>(*__facets[__i]);
139 return static_cast<const _Facet&>(*__facets[__i]);
144 // Generic version does nothing.
145 template<typename _CharT>
147 collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw ()
150 // Generic version does nothing.
151 template<typename _CharT>
153 collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw ()
156 template<typename _CharT>
159 do_compare(const _CharT* __lo1, const _CharT* __hi1,
160 const _CharT* __lo2, const _CharT* __hi2) const
162 // strcoll assumes zero-terminated strings so we make a copy
163 // and then put a zero at the end.
164 const string_type __one(__lo1, __hi1);
165 const string_type __two(__lo2, __hi2);
167 const _CharT* __p = __one.c_str();
168 const _CharT* __pend = __one.data() + __one.length();
169 const _CharT* __q = __two.c_str();
170 const _CharT* __qend = __two.data() + __two.length();
172 // strcoll stops when it sees a nul character so we break
173 // the strings into zero-terminated substrings and pass those
177 const int __res = _M_compare(__p, __q);
181 __p += char_traits<_CharT>::length(__p);
182 __q += char_traits<_CharT>::length(__q);
183 if (__p == __pend && __q == __qend)
185 else if (__p == __pend)
187 else if (__q == __qend)
195 template<typename _CharT>
196 typename collate<_CharT>::string_type
198 do_transform(const _CharT* __lo, const _CharT* __hi) const
202 // strxfrm assumes zero-terminated strings so we make a copy
203 const string_type __str(__lo, __hi);
205 const _CharT* __p = __str.c_str();
206 const _CharT* __pend = __str.data() + __str.length();
208 size_t __len = (__hi - __lo) * 2;
210 _CharT* __c = new _CharT[__len];
214 // strxfrm stops when it sees a nul character so we break
215 // the string into zero-terminated substrings and pass those
219 // First try a buffer perhaps big enough.
220 size_t __res = _M_transform(__c, __p, __len);
221 // If the buffer was not large enough, try again with the
226 delete [] __c, __c = 0;
227 __c = new _CharT[__len];
228 __res = _M_transform(__c, __p, __len);
231 __ret.append(__c, __res);
232 __p += char_traits<_CharT>::length(__p);
237 __ret.push_back(_CharT());
243 __throw_exception_again;
251 template<typename _CharT>
254 do_hash(const _CharT* __lo, const _CharT* __hi) const
256 unsigned long __val = 0;
257 for (; __lo < __hi; ++__lo)
259 *__lo + ((__val << 7)
260 | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
262 return static_cast<long>(__val);
265 // Inhibit implicit instantiations for required instantiations,
266 // which are defined via explicit instantiations elsewhere.
267 #if _GLIBCXX_EXTERN_TEMPLATE
268 extern template class collate<char>;
269 extern template class collate_byname<char>;
273 use_facet<collate<char> >(const locale&);
277 has_facet<collate<char> >(const locale&);
279 #ifdef _GLIBCXX_USE_WCHAR_T
280 extern template class collate<wchar_t>;
281 extern template class collate_byname<wchar_t>;
284 const collate<wchar_t>&
285 use_facet<collate<wchar_t> >(const locale&);
289 has_facet<collate<wchar_t> >(const locale&);
293 _GLIBCXX_END_NAMESPACE_VERSION