xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/locale_classes.tcc (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino // Locale support -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9*e4b17023SJohn Marino // any later version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*e4b17023SJohn Marino // GNU General Public License for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /** @file bits/locale_classes.tcc
26*e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
27*e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{locale}
28*e4b17023SJohn Marino  */
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino //
31*e4b17023SJohn Marino // ISO C++ 14882: 22.1  Locales
32*e4b17023SJohn Marino //
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino #ifndef _LOCALE_CLASSES_TCC
35*e4b17023SJohn Marino #define _LOCALE_CLASSES_TCC 1
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino #pragma GCC system_header
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
40*e4b17023SJohn Marino {
41*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino   template<typename _Facet>
44*e4b17023SJohn Marino     locale::
locale(const locale & __other,_Facet * __f)45*e4b17023SJohn Marino     locale(const locale& __other, _Facet* __f)
46*e4b17023SJohn Marino     {
47*e4b17023SJohn Marino       _M_impl = new _Impl(*__other._M_impl, 1);
48*e4b17023SJohn Marino 
49*e4b17023SJohn Marino       __try
50*e4b17023SJohn Marino 	{ _M_impl->_M_install_facet(&_Facet::id, __f); }
51*e4b17023SJohn Marino       __catch(...)
52*e4b17023SJohn Marino 	{
53*e4b17023SJohn Marino 	  _M_impl->_M_remove_reference();
54*e4b17023SJohn Marino 	  __throw_exception_again;
55*e4b17023SJohn Marino 	}
56*e4b17023SJohn Marino       delete [] _M_impl->_M_names[0];
57*e4b17023SJohn Marino       _M_impl->_M_names[0] = 0;   // Unnamed.
58*e4b17023SJohn Marino     }
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino   template<typename _Facet>
61*e4b17023SJohn Marino     locale
62*e4b17023SJohn Marino     locale::
combine(const locale & __other) const63*e4b17023SJohn Marino     combine(const locale& __other) const
64*e4b17023SJohn Marino     {
65*e4b17023SJohn Marino       _Impl* __tmp = new _Impl(*_M_impl, 1);
66*e4b17023SJohn Marino       __try
67*e4b17023SJohn Marino 	{
68*e4b17023SJohn Marino 	  __tmp->_M_replace_facet(__other._M_impl, &_Facet::id);
69*e4b17023SJohn Marino 	}
70*e4b17023SJohn Marino       __catch(...)
71*e4b17023SJohn Marino 	{
72*e4b17023SJohn Marino 	  __tmp->_M_remove_reference();
73*e4b17023SJohn Marino 	  __throw_exception_again;
74*e4b17023SJohn Marino 	}
75*e4b17023SJohn Marino       return locale(__tmp);
76*e4b17023SJohn Marino     }
77*e4b17023SJohn Marino 
78*e4b17023SJohn Marino   template<typename _CharT, typename _Traits, typename _Alloc>
79*e4b17023SJohn Marino     bool
80*e4b17023SJohn Marino     locale::
operator ()(const basic_string<_CharT,_Traits,_Alloc> & __s1,const basic_string<_CharT,_Traits,_Alloc> & __s2) const81*e4b17023SJohn Marino     operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1,
82*e4b17023SJohn Marino 	       const basic_string<_CharT, _Traits, _Alloc>& __s2) const
83*e4b17023SJohn Marino     {
84*e4b17023SJohn Marino       typedef std::collate<_CharT> __collate_type;
85*e4b17023SJohn Marino       const __collate_type& __collate = use_facet<__collate_type>(*this);
86*e4b17023SJohn Marino       return (__collate.compare(__s1.data(), __s1.data() + __s1.length(),
87*e4b17023SJohn Marino 				__s2.data(), __s2.data() + __s2.length()) < 0);
88*e4b17023SJohn Marino     }
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino   /**
91*e4b17023SJohn Marino    *  @brief  Test for the presence of a facet.
92*e4b17023SJohn Marino    *
93*e4b17023SJohn Marino    *  has_facet tests the locale argument for the presence of the facet type
94*e4b17023SJohn Marino    *  provided as the template parameter.  Facets derived from the facet
95*e4b17023SJohn Marino    *  parameter will also return true.
96*e4b17023SJohn Marino    *
97*e4b17023SJohn Marino    *  @tparam  _Facet  The facet type to test the presence of.
98*e4b17023SJohn Marino    *  @param  __loc  The locale to test.
99*e4b17023SJohn Marino    *  @return  true if @p __loc contains a facet of type _Facet, else false.
100*e4b17023SJohn Marino   */
101*e4b17023SJohn Marino   template<typename _Facet>
102*e4b17023SJohn Marino     bool
has_facet(const locale & __loc)103*e4b17023SJohn Marino     has_facet(const locale& __loc) throw()
104*e4b17023SJohn Marino     {
105*e4b17023SJohn Marino       const size_t __i = _Facet::id._M_id();
106*e4b17023SJohn Marino       const locale::facet** __facets = __loc._M_impl->_M_facets;
107*e4b17023SJohn Marino       return (__i < __loc._M_impl->_M_facets_size
108*e4b17023SJohn Marino #ifdef __GXX_RTTI
109*e4b17023SJohn Marino 	      && dynamic_cast<const _Facet*>(__facets[__i]));
110*e4b17023SJohn Marino #else
111*e4b17023SJohn Marino               && static_cast<const _Facet*>(__facets[__i]));
112*e4b17023SJohn Marino #endif
113*e4b17023SJohn Marino     }
114*e4b17023SJohn Marino 
115*e4b17023SJohn Marino   /**
116*e4b17023SJohn Marino    *  @brief  Return a facet.
117*e4b17023SJohn Marino    *
118*e4b17023SJohn Marino    *  use_facet looks for and returns a reference to a facet of type Facet
119*e4b17023SJohn Marino    *  where Facet is the template parameter.  If has_facet(locale) is true,
120*e4b17023SJohn Marino    *  there is a suitable facet to return.  It throws std::bad_cast if the
121*e4b17023SJohn Marino    *  locale doesn't contain a facet of type Facet.
122*e4b17023SJohn Marino    *
123*e4b17023SJohn Marino    *  @tparam  _Facet  The facet type to access.
124*e4b17023SJohn Marino    *  @param  __loc  The locale to use.
125*e4b17023SJohn Marino    *  @return  Reference to facet of type Facet.
126*e4b17023SJohn Marino    *  @throw  std::bad_cast if @p __loc doesn't contain a facet of type _Facet.
127*e4b17023SJohn Marino   */
128*e4b17023SJohn Marino   template<typename _Facet>
129*e4b17023SJohn Marino     const _Facet&
use_facet(const locale & __loc)130*e4b17023SJohn Marino     use_facet(const locale& __loc)
131*e4b17023SJohn Marino     {
132*e4b17023SJohn Marino       const size_t __i = _Facet::id._M_id();
133*e4b17023SJohn Marino       const locale::facet** __facets = __loc._M_impl->_M_facets;
134*e4b17023SJohn Marino       if (__i >= __loc._M_impl->_M_facets_size || !__facets[__i])
135*e4b17023SJohn Marino         __throw_bad_cast();
136*e4b17023SJohn Marino #ifdef __GXX_RTTI
137*e4b17023SJohn Marino       return dynamic_cast<const _Facet&>(*__facets[__i]);
138*e4b17023SJohn Marino #else
139*e4b17023SJohn Marino       return static_cast<const _Facet&>(*__facets[__i]);
140*e4b17023SJohn Marino #endif
141*e4b17023SJohn Marino     }
142*e4b17023SJohn Marino 
143*e4b17023SJohn Marino 
144*e4b17023SJohn Marino   // Generic version does nothing.
145*e4b17023SJohn Marino   template<typename _CharT>
146*e4b17023SJohn Marino     int
_M_compare(const _CharT *,const _CharT *) const147*e4b17023SJohn Marino     collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const throw ()
148*e4b17023SJohn Marino     { return 0; }
149*e4b17023SJohn Marino 
150*e4b17023SJohn Marino   // Generic version does nothing.
151*e4b17023SJohn Marino   template<typename _CharT>
152*e4b17023SJohn Marino     size_t
_M_transform(_CharT *,const _CharT *,size_t) const153*e4b17023SJohn Marino     collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const throw ()
154*e4b17023SJohn Marino     { return 0; }
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino   template<typename _CharT>
157*e4b17023SJohn Marino     int
158*e4b17023SJohn Marino     collate<_CharT>::
do_compare(const _CharT * __lo1,const _CharT * __hi1,const _CharT * __lo2,const _CharT * __hi2) const159*e4b17023SJohn Marino     do_compare(const _CharT* __lo1, const _CharT* __hi1,
160*e4b17023SJohn Marino 	       const _CharT* __lo2, const _CharT* __hi2) const
161*e4b17023SJohn Marino     {
162*e4b17023SJohn Marino       // strcoll assumes zero-terminated strings so we make a copy
163*e4b17023SJohn Marino       // and then put a zero at the end.
164*e4b17023SJohn Marino       const string_type __one(__lo1, __hi1);
165*e4b17023SJohn Marino       const string_type __two(__lo2, __hi2);
166*e4b17023SJohn Marino 
167*e4b17023SJohn Marino       const _CharT* __p = __one.c_str();
168*e4b17023SJohn Marino       const _CharT* __pend = __one.data() + __one.length();
169*e4b17023SJohn Marino       const _CharT* __q = __two.c_str();
170*e4b17023SJohn Marino       const _CharT* __qend = __two.data() + __two.length();
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino       // strcoll stops when it sees a nul character so we break
173*e4b17023SJohn Marino       // the strings into zero-terminated substrings and pass those
174*e4b17023SJohn Marino       // to strcoll.
175*e4b17023SJohn Marino       for (;;)
176*e4b17023SJohn Marino 	{
177*e4b17023SJohn Marino 	  const int __res = _M_compare(__p, __q);
178*e4b17023SJohn Marino 	  if (__res)
179*e4b17023SJohn Marino 	    return __res;
180*e4b17023SJohn Marino 
181*e4b17023SJohn Marino 	  __p += char_traits<_CharT>::length(__p);
182*e4b17023SJohn Marino 	  __q += char_traits<_CharT>::length(__q);
183*e4b17023SJohn Marino 	  if (__p == __pend && __q == __qend)
184*e4b17023SJohn Marino 	    return 0;
185*e4b17023SJohn Marino 	  else if (__p == __pend)
186*e4b17023SJohn Marino 	    return -1;
187*e4b17023SJohn Marino 	  else if (__q == __qend)
188*e4b17023SJohn Marino 	    return 1;
189*e4b17023SJohn Marino 
190*e4b17023SJohn Marino 	  __p++;
191*e4b17023SJohn Marino 	  __q++;
192*e4b17023SJohn Marino 	}
193*e4b17023SJohn Marino     }
194*e4b17023SJohn Marino 
195*e4b17023SJohn Marino   template<typename _CharT>
196*e4b17023SJohn Marino     typename collate<_CharT>::string_type
197*e4b17023SJohn Marino     collate<_CharT>::
do_transform(const _CharT * __lo,const _CharT * __hi) const198*e4b17023SJohn Marino     do_transform(const _CharT* __lo, const _CharT* __hi) const
199*e4b17023SJohn Marino     {
200*e4b17023SJohn Marino       string_type __ret;
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino       // strxfrm assumes zero-terminated strings so we make a copy
203*e4b17023SJohn Marino       const string_type __str(__lo, __hi);
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino       const _CharT* __p = __str.c_str();
206*e4b17023SJohn Marino       const _CharT* __pend = __str.data() + __str.length();
207*e4b17023SJohn Marino 
208*e4b17023SJohn Marino       size_t __len = (__hi - __lo) * 2;
209*e4b17023SJohn Marino 
210*e4b17023SJohn Marino       _CharT* __c = new _CharT[__len];
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino       __try
213*e4b17023SJohn Marino 	{
214*e4b17023SJohn Marino 	  // strxfrm stops when it sees a nul character so we break
215*e4b17023SJohn Marino 	  // the string into zero-terminated substrings and pass those
216*e4b17023SJohn Marino 	  // to strxfrm.
217*e4b17023SJohn Marino 	  for (;;)
218*e4b17023SJohn Marino 	    {
219*e4b17023SJohn Marino 	      // First try a buffer perhaps big enough.
220*e4b17023SJohn Marino 	      size_t __res = _M_transform(__c, __p, __len);
221*e4b17023SJohn Marino 	      // If the buffer was not large enough, try again with the
222*e4b17023SJohn Marino 	      // correct size.
223*e4b17023SJohn Marino 	      if (__res >= __len)
224*e4b17023SJohn Marino 		{
225*e4b17023SJohn Marino 		  __len = __res + 1;
226*e4b17023SJohn Marino 		  delete [] __c, __c = 0;
227*e4b17023SJohn Marino 		  __c = new _CharT[__len];
228*e4b17023SJohn Marino 		  __res = _M_transform(__c, __p, __len);
229*e4b17023SJohn Marino 		}
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino 	      __ret.append(__c, __res);
232*e4b17023SJohn Marino 	      __p += char_traits<_CharT>::length(__p);
233*e4b17023SJohn Marino 	      if (__p == __pend)
234*e4b17023SJohn Marino 		break;
235*e4b17023SJohn Marino 
236*e4b17023SJohn Marino 	      __p++;
237*e4b17023SJohn Marino 	      __ret.push_back(_CharT());
238*e4b17023SJohn Marino 	    }
239*e4b17023SJohn Marino 	}
240*e4b17023SJohn Marino       __catch(...)
241*e4b17023SJohn Marino 	{
242*e4b17023SJohn Marino 	  delete [] __c;
243*e4b17023SJohn Marino 	  __throw_exception_again;
244*e4b17023SJohn Marino 	}
245*e4b17023SJohn Marino 
246*e4b17023SJohn Marino       delete [] __c;
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino       return __ret;
249*e4b17023SJohn Marino     }
250*e4b17023SJohn Marino 
251*e4b17023SJohn Marino   template<typename _CharT>
252*e4b17023SJohn Marino     long
253*e4b17023SJohn Marino     collate<_CharT>::
do_hash(const _CharT * __lo,const _CharT * __hi) const254*e4b17023SJohn Marino     do_hash(const _CharT* __lo, const _CharT* __hi) const
255*e4b17023SJohn Marino     {
256*e4b17023SJohn Marino       unsigned long __val = 0;
257*e4b17023SJohn Marino       for (; __lo < __hi; ++__lo)
258*e4b17023SJohn Marino 	__val =
259*e4b17023SJohn Marino 	  *__lo + ((__val << 7)
260*e4b17023SJohn Marino 		   | (__val >> (__gnu_cxx::__numeric_traits<unsigned long>::
261*e4b17023SJohn Marino 				__digits - 7)));
262*e4b17023SJohn Marino       return static_cast<long>(__val);
263*e4b17023SJohn Marino     }
264*e4b17023SJohn Marino 
265*e4b17023SJohn Marino   // Inhibit implicit instantiations for required instantiations,
266*e4b17023SJohn Marino   // which are defined via explicit instantiations elsewhere.
267*e4b17023SJohn Marino #if _GLIBCXX_EXTERN_TEMPLATE
268*e4b17023SJohn Marino   extern template class collate<char>;
269*e4b17023SJohn Marino   extern template class collate_byname<char>;
270*e4b17023SJohn Marino 
271*e4b17023SJohn Marino   extern template
272*e4b17023SJohn Marino     const collate<char>&
273*e4b17023SJohn Marino     use_facet<collate<char> >(const locale&);
274*e4b17023SJohn Marino 
275*e4b17023SJohn Marino   extern template
276*e4b17023SJohn Marino     bool
277*e4b17023SJohn Marino     has_facet<collate<char> >(const locale&);
278*e4b17023SJohn Marino 
279*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_WCHAR_T
280*e4b17023SJohn Marino   extern template class collate<wchar_t>;
281*e4b17023SJohn Marino   extern template class collate_byname<wchar_t>;
282*e4b17023SJohn Marino 
283*e4b17023SJohn Marino   extern template
284*e4b17023SJohn Marino     const collate<wchar_t>&
285*e4b17023SJohn Marino     use_facet<collate<wchar_t> >(const locale&);
286*e4b17023SJohn Marino 
287*e4b17023SJohn Marino   extern template
288*e4b17023SJohn Marino     bool
289*e4b17023SJohn Marino     has_facet<collate<wchar_t> >(const locale&);
290*e4b17023SJohn Marino #endif
291*e4b17023SJohn Marino #endif
292*e4b17023SJohn Marino 
293*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
294*e4b17023SJohn Marino } // namespace std
295*e4b17023SJohn Marino 
296*e4b17023SJohn Marino #endif
297