xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/locale_classes.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino // Locale support -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4*e4b17023SJohn Marino // 2006, 2007, 2008, 2009, 2010, 2011
5*e4b17023SJohn Marino // Free Software Foundation, Inc.
6*e4b17023SJohn Marino //
7*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
8*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
9*e4b17023SJohn Marino // terms of the GNU General Public License as published by the
10*e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino // any later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e4b17023SJohn Marino // GNU General Public License for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
19*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
20*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
23*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
24*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino /** @file bits/locale_classes.h
28*e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
29*e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{locale}
30*e4b17023SJohn Marino  */
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino //
33*e4b17023SJohn Marino // ISO C++ 14882: 22.1  Locales
34*e4b17023SJohn Marino //
35*e4b17023SJohn Marino 
36*e4b17023SJohn Marino #ifndef _LOCALE_CLASSES_H
37*e4b17023SJohn Marino #define _LOCALE_CLASSES_H 1
38*e4b17023SJohn Marino 
39*e4b17023SJohn Marino #pragma GCC system_header
40*e4b17023SJohn Marino 
41*e4b17023SJohn Marino #include <bits/localefwd.h>
42*e4b17023SJohn Marino #include <string>
43*e4b17023SJohn Marino #include <ext/atomicity.h>
44*e4b17023SJohn Marino 
_GLIBCXX_VISIBILITY(default)45*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
46*e4b17023SJohn Marino {
47*e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
48*e4b17023SJohn Marino 
49*e4b17023SJohn Marino   // 22.1.1 Class locale
50*e4b17023SJohn Marino   /**
51*e4b17023SJohn Marino    *  @brief  Container class for localization functionality.
52*e4b17023SJohn Marino    *  @ingroup locales
53*e4b17023SJohn Marino    *
54*e4b17023SJohn Marino    *  The locale class is first a class wrapper for C library locales.  It is
55*e4b17023SJohn Marino    *  also an extensible container for user-defined localization.  A locale is
56*e4b17023SJohn Marino    *  a collection of facets that implement various localization features such
57*e4b17023SJohn Marino    *  as money, time, and number printing.
58*e4b17023SJohn Marino    *
59*e4b17023SJohn Marino    *  Constructing C++ locales does not change the C library locale.
60*e4b17023SJohn Marino    *
61*e4b17023SJohn Marino    *  This library supports efficient construction and copying of locales
62*e4b17023SJohn Marino    *  through a reference counting implementation of the locale class.
63*e4b17023SJohn Marino   */
64*e4b17023SJohn Marino   class locale
65*e4b17023SJohn Marino   {
66*e4b17023SJohn Marino   public:
67*e4b17023SJohn Marino     // Types:
68*e4b17023SJohn Marino     /// Definition of locale::category.
69*e4b17023SJohn Marino     typedef int	category;
70*e4b17023SJohn Marino 
71*e4b17023SJohn Marino     // Forward decls and friends:
72*e4b17023SJohn Marino     class facet;
73*e4b17023SJohn Marino     class id;
74*e4b17023SJohn Marino     class _Impl;
75*e4b17023SJohn Marino 
76*e4b17023SJohn Marino     friend class facet;
77*e4b17023SJohn Marino     friend class _Impl;
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino     template<typename _Facet>
80*e4b17023SJohn Marino       friend bool
81*e4b17023SJohn Marino       has_facet(const locale&) throw();
82*e4b17023SJohn Marino 
83*e4b17023SJohn Marino     template<typename _Facet>
84*e4b17023SJohn Marino       friend const _Facet&
85*e4b17023SJohn Marino       use_facet(const locale&);
86*e4b17023SJohn Marino 
87*e4b17023SJohn Marino     template<typename _Cache>
88*e4b17023SJohn Marino       friend struct __use_cache;
89*e4b17023SJohn Marino 
90*e4b17023SJohn Marino     //@{
91*e4b17023SJohn Marino     /**
92*e4b17023SJohn Marino      *  @brief  Category values.
93*e4b17023SJohn Marino      *
94*e4b17023SJohn Marino      *  The standard category values are none, ctype, numeric, collate, time,
95*e4b17023SJohn Marino      *  monetary, and messages.  They form a bitmask that supports union and
96*e4b17023SJohn Marino      *  intersection.  The category all is the union of these values.
97*e4b17023SJohn Marino      *
98*e4b17023SJohn Marino      *  NB: Order must match _S_facet_categories definition in locale.cc
99*e4b17023SJohn Marino     */
100*e4b17023SJohn Marino     static const category none		= 0;
101*e4b17023SJohn Marino     static const category ctype		= 1L << 0;
102*e4b17023SJohn Marino     static const category numeric	= 1L << 1;
103*e4b17023SJohn Marino     static const category collate	= 1L << 2;
104*e4b17023SJohn Marino     static const category time		= 1L << 3;
105*e4b17023SJohn Marino     static const category monetary	= 1L << 4;
106*e4b17023SJohn Marino     static const category messages	= 1L << 5;
107*e4b17023SJohn Marino     static const category all		= (ctype | numeric | collate |
108*e4b17023SJohn Marino 					   time  | monetary | messages);
109*e4b17023SJohn Marino     //@}
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino     // Construct/copy/destroy:
112*e4b17023SJohn Marino 
113*e4b17023SJohn Marino     /**
114*e4b17023SJohn Marino      *  @brief  Default constructor.
115*e4b17023SJohn Marino      *
116*e4b17023SJohn Marino      *  Constructs a copy of the global locale.  If no locale has been
117*e4b17023SJohn Marino      *  explicitly set, this is the C locale.
118*e4b17023SJohn Marino     */
119*e4b17023SJohn Marino     locale() throw();
120*e4b17023SJohn Marino 
121*e4b17023SJohn Marino     /**
122*e4b17023SJohn Marino      *  @brief  Copy constructor.
123*e4b17023SJohn Marino      *
124*e4b17023SJohn Marino      *  Constructs a copy of @a other.
125*e4b17023SJohn Marino      *
126*e4b17023SJohn Marino      *  @param  __other  The locale to copy.
127*e4b17023SJohn Marino     */
128*e4b17023SJohn Marino     locale(const locale& __other) throw();
129*e4b17023SJohn Marino 
130*e4b17023SJohn Marino     /**
131*e4b17023SJohn Marino      *  @brief  Named locale constructor.
132*e4b17023SJohn Marino      *
133*e4b17023SJohn Marino      *  Constructs a copy of the named C library locale.
134*e4b17023SJohn Marino      *
135*e4b17023SJohn Marino      *  @param  __s  Name of the locale to construct.
136*e4b17023SJohn Marino      *  @throw  std::runtime_error if __s is null or an undefined locale.
137*e4b17023SJohn Marino     */
138*e4b17023SJohn Marino     explicit
139*e4b17023SJohn Marino     locale(const char* __s);
140*e4b17023SJohn Marino 
141*e4b17023SJohn Marino     /**
142*e4b17023SJohn Marino      *  @brief  Construct locale with facets from another locale.
143*e4b17023SJohn Marino      *
144*e4b17023SJohn Marino      *  Constructs a copy of the locale @a base.  The facets specified by @a
145*e4b17023SJohn Marino      *  cat are replaced with those from the locale named by @a s.  If base is
146*e4b17023SJohn Marino      *  named, this locale instance will also be named.
147*e4b17023SJohn Marino      *
148*e4b17023SJohn Marino      *  @param  __base  The locale to copy.
149*e4b17023SJohn Marino      *  @param  __s  Name of the locale to use facets from.
150*e4b17023SJohn Marino      *  @param  __cat  Set of categories defining the facets to use from __s.
151*e4b17023SJohn Marino      *  @throw  std::runtime_error if __s is null or an undefined locale.
152*e4b17023SJohn Marino     */
153*e4b17023SJohn Marino     locale(const locale& __base, const char* __s, category __cat);
154*e4b17023SJohn Marino 
155*e4b17023SJohn Marino     /**
156*e4b17023SJohn Marino      *  @brief  Construct locale with facets from another locale.
157*e4b17023SJohn Marino      *
158*e4b17023SJohn Marino      *  Constructs a copy of the locale @a base.  The facets specified by @a
159*e4b17023SJohn Marino      *  cat are replaced with those from the locale @a add.  If @a base and @a
160*e4b17023SJohn Marino      *  add are named, this locale instance will also be named.
161*e4b17023SJohn Marino      *
162*e4b17023SJohn Marino      *  @param  __base  The locale to copy.
163*e4b17023SJohn Marino      *  @param  __add  The locale to use facets from.
164*e4b17023SJohn Marino      *  @param  __cat  Set of categories defining the facets to use from add.
165*e4b17023SJohn Marino     */
166*e4b17023SJohn Marino     locale(const locale& __base, const locale& __add, category __cat);
167*e4b17023SJohn Marino 
168*e4b17023SJohn Marino     /**
169*e4b17023SJohn Marino      *  @brief  Construct locale with another facet.
170*e4b17023SJohn Marino      *
171*e4b17023SJohn Marino      *  Constructs a copy of the locale @a __other.  The facet @a __f
172*e4b17023SJohn Marino      *  is added to @a __other, replacing an existing facet of type
173*e4b17023SJohn Marino      *  Facet if there is one.  If @a __f is null, this locale is a
174*e4b17023SJohn Marino      *  copy of @a __other.
175*e4b17023SJohn Marino      *
176*e4b17023SJohn Marino      *  @param  __other  The locale to copy.
177*e4b17023SJohn Marino      *  @param  __f  The facet to add in.
178*e4b17023SJohn Marino     */
179*e4b17023SJohn Marino     template<typename _Facet>
180*e4b17023SJohn Marino       locale(const locale& __other, _Facet* __f);
181*e4b17023SJohn Marino 
182*e4b17023SJohn Marino     /// Locale destructor.
183*e4b17023SJohn Marino     ~locale() throw();
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino     /**
186*e4b17023SJohn Marino      *  @brief  Assignment operator.
187*e4b17023SJohn Marino      *
188*e4b17023SJohn Marino      *  Set this locale to be a copy of @a other.
189*e4b17023SJohn Marino      *
190*e4b17023SJohn Marino      *  @param  __other  The locale to copy.
191*e4b17023SJohn Marino      *  @return  A reference to this locale.
192*e4b17023SJohn Marino     */
193*e4b17023SJohn Marino     const locale&
194*e4b17023SJohn Marino     operator=(const locale& __other) throw();
195*e4b17023SJohn Marino 
196*e4b17023SJohn Marino     /**
197*e4b17023SJohn Marino      *  @brief  Construct locale with another facet.
198*e4b17023SJohn Marino      *
199*e4b17023SJohn Marino      *  Constructs and returns a new copy of this locale.  Adds or replaces an
200*e4b17023SJohn Marino      *  existing facet of type Facet from the locale @a other into the new
201*e4b17023SJohn Marino      *  locale.
202*e4b17023SJohn Marino      *
203*e4b17023SJohn Marino      *  @tparam  _Facet  The facet type to copy from other
204*e4b17023SJohn Marino      *  @param  __other  The locale to copy from.
205*e4b17023SJohn Marino      *  @return  Newly constructed locale.
206*e4b17023SJohn Marino      *  @throw  std::runtime_error if __other has no facet of type _Facet.
207*e4b17023SJohn Marino     */
208*e4b17023SJohn Marino     template<typename _Facet>
209*e4b17023SJohn Marino       locale
210*e4b17023SJohn Marino       combine(const locale& __other) const;
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino     // Locale operations:
213*e4b17023SJohn Marino     /**
214*e4b17023SJohn Marino      *  @brief  Return locale name.
215*e4b17023SJohn Marino      *  @return  Locale name or "*" if unnamed.
216*e4b17023SJohn Marino     */
217*e4b17023SJohn Marino     string
218*e4b17023SJohn Marino     name() const;
219*e4b17023SJohn Marino 
220*e4b17023SJohn Marino     /**
221*e4b17023SJohn Marino      *  @brief  Locale equality.
222*e4b17023SJohn Marino      *
223*e4b17023SJohn Marino      *  @param  __other  The locale to compare against.
224*e4b17023SJohn Marino      *  @return  True if other and this refer to the same locale instance, are
225*e4b17023SJohn Marino      *		 copies, or have the same name.  False otherwise.
226*e4b17023SJohn Marino     */
227*e4b17023SJohn Marino     bool
228*e4b17023SJohn Marino     operator==(const locale& __other) const throw();
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino     /**
231*e4b17023SJohn Marino      *  @brief  Locale inequality.
232*e4b17023SJohn Marino      *
233*e4b17023SJohn Marino      *  @param  __other  The locale to compare against.
234*e4b17023SJohn Marino      *  @return  ! (*this == __other)
235*e4b17023SJohn Marino     */
236*e4b17023SJohn Marino     bool
237*e4b17023SJohn Marino     operator!=(const locale& __other) const throw()
238*e4b17023SJohn Marino     { return !(this->operator==(__other)); }
239*e4b17023SJohn Marino 
240*e4b17023SJohn Marino     /**
241*e4b17023SJohn Marino      *  @brief  Compare two strings according to collate.
242*e4b17023SJohn Marino      *
243*e4b17023SJohn Marino      *  Template operator to compare two strings using the compare function of
244*e4b17023SJohn Marino      *  the collate facet in this locale.  One use is to provide the locale to
245*e4b17023SJohn Marino      *  the sort function.  For example, a vector v of strings could be sorted
246*e4b17023SJohn Marino      *  according to locale loc by doing:
247*e4b17023SJohn Marino      *  @code
248*e4b17023SJohn Marino      *  std::sort(v.begin(), v.end(), loc);
249*e4b17023SJohn Marino      *  @endcode
250*e4b17023SJohn Marino      *
251*e4b17023SJohn Marino      *  @param  __s1  First string to compare.
252*e4b17023SJohn Marino      *  @param  __s2  Second string to compare.
253*e4b17023SJohn Marino      *  @return  True if collate<_Char> facet compares __s1 < __s2, else false.
254*e4b17023SJohn Marino     */
255*e4b17023SJohn Marino     template<typename _Char, typename _Traits, typename _Alloc>
256*e4b17023SJohn Marino       bool
257*e4b17023SJohn Marino       operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
258*e4b17023SJohn Marino 		 const basic_string<_Char, _Traits, _Alloc>& __s2) const;
259*e4b17023SJohn Marino 
260*e4b17023SJohn Marino     // Global locale objects:
261*e4b17023SJohn Marino     /**
262*e4b17023SJohn Marino      *  @brief  Set global locale
263*e4b17023SJohn Marino      *
264*e4b17023SJohn Marino      *  This function sets the global locale to the argument and returns a
265*e4b17023SJohn Marino      *  copy of the previous global locale.  If the argument has a name, it
266*e4b17023SJohn Marino      *  will also call std::setlocale(LC_ALL, loc.name()).
267*e4b17023SJohn Marino      *
268*e4b17023SJohn Marino      *  @param  __loc  The new locale to make global.
269*e4b17023SJohn Marino      *  @return  Copy of the old global locale.
270*e4b17023SJohn Marino     */
271*e4b17023SJohn Marino     static locale
272*e4b17023SJohn Marino     global(const locale& __loc);
273*e4b17023SJohn Marino 
274*e4b17023SJohn Marino     /**
275*e4b17023SJohn Marino      *  @brief  Return reference to the C locale.
276*e4b17023SJohn Marino     */
277*e4b17023SJohn Marino     static const locale&
278*e4b17023SJohn Marino     classic();
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino   private:
281*e4b17023SJohn Marino     // The (shared) implementation
282*e4b17023SJohn Marino     _Impl*		_M_impl;
283*e4b17023SJohn Marino 
284*e4b17023SJohn Marino     // The "C" reference locale
285*e4b17023SJohn Marino     static _Impl*       _S_classic;
286*e4b17023SJohn Marino 
287*e4b17023SJohn Marino     // Current global locale
288*e4b17023SJohn Marino     static _Impl*	_S_global;
289*e4b17023SJohn Marino 
290*e4b17023SJohn Marino     // Names of underlying locale categories.
291*e4b17023SJohn Marino     // NB: locale::global() has to know how to modify all the
292*e4b17023SJohn Marino     // underlying categories, not just the ones required by the C++
293*e4b17023SJohn Marino     // standard.
294*e4b17023SJohn Marino     static const char* const* const _S_categories;
295*e4b17023SJohn Marino 
296*e4b17023SJohn Marino     // Number of standard categories. For C++, these categories are
297*e4b17023SJohn Marino     // collate, ctype, monetary, numeric, time, and messages. These
298*e4b17023SJohn Marino     // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
299*e4b17023SJohn Marino     // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
300*e4b17023SJohn Marino     // 1003.1-2001) specifies LC_MESSAGES.
301*e4b17023SJohn Marino     // In addition to the standard categories, the underlying
302*e4b17023SJohn Marino     // operating system is allowed to define extra LC_*
303*e4b17023SJohn Marino     // macros. For GNU systems, the following are also valid:
304*e4b17023SJohn Marino     // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
305*e4b17023SJohn Marino     // and LC_IDENTIFICATION.
306*e4b17023SJohn Marino     enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES };
307*e4b17023SJohn Marino 
308*e4b17023SJohn Marino #ifdef __GTHREADS
309*e4b17023SJohn Marino     static __gthread_once_t _S_once;
310*e4b17023SJohn Marino #endif
311*e4b17023SJohn Marino 
312*e4b17023SJohn Marino     explicit
313*e4b17023SJohn Marino     locale(_Impl*) throw();
314*e4b17023SJohn Marino 
315*e4b17023SJohn Marino     static void
316*e4b17023SJohn Marino     _S_initialize();
317*e4b17023SJohn Marino 
318*e4b17023SJohn Marino     static void
319*e4b17023SJohn Marino     _S_initialize_once() throw();
320*e4b17023SJohn Marino 
321*e4b17023SJohn Marino     static category
322*e4b17023SJohn Marino     _S_normalize_category(category);
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino     void
325*e4b17023SJohn Marino     _M_coalesce(const locale& __base, const locale& __add, category __cat);
326*e4b17023SJohn Marino   };
327*e4b17023SJohn Marino 
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino   // 22.1.1.1.2  Class locale::facet
330*e4b17023SJohn Marino   /**
331*e4b17023SJohn Marino    *  @brief  Localization functionality base class.
332*e4b17023SJohn Marino    *  @ingroup locales
333*e4b17023SJohn Marino    *
334*e4b17023SJohn Marino    *  The facet class is the base class for a localization feature, such as
335*e4b17023SJohn Marino    *  money, time, and number printing.  It provides common support for facets
336*e4b17023SJohn Marino    *  and reference management.
337*e4b17023SJohn Marino    *
338*e4b17023SJohn Marino    *  Facets may not be copied or assigned.
339*e4b17023SJohn Marino   */
340*e4b17023SJohn Marino   class locale::facet
341*e4b17023SJohn Marino   {
342*e4b17023SJohn Marino   private:
343*e4b17023SJohn Marino     friend class locale;
344*e4b17023SJohn Marino     friend class locale::_Impl;
345*e4b17023SJohn Marino 
346*e4b17023SJohn Marino     mutable _Atomic_word		_M_refcount;
347*e4b17023SJohn Marino 
348*e4b17023SJohn Marino     // Contains data from the underlying "C" library for the classic locale.
349*e4b17023SJohn Marino     static __c_locale                   _S_c_locale;
350*e4b17023SJohn Marino 
351*e4b17023SJohn Marino     // String literal for the name of the classic locale.
352*e4b17023SJohn Marino     static const char			_S_c_name[2];
353*e4b17023SJohn Marino 
354*e4b17023SJohn Marino #ifdef __GTHREADS
355*e4b17023SJohn Marino     static __gthread_once_t		_S_once;
356*e4b17023SJohn Marino #endif
357*e4b17023SJohn Marino 
358*e4b17023SJohn Marino     static void
359*e4b17023SJohn Marino     _S_initialize_once();
360*e4b17023SJohn Marino 
361*e4b17023SJohn Marino   protected:
362*e4b17023SJohn Marino     /**
363*e4b17023SJohn Marino      *  @brief  Facet constructor.
364*e4b17023SJohn Marino      *
365*e4b17023SJohn Marino      *  This is the constructor provided by the standard.  If refs is 0, the
366*e4b17023SJohn Marino      *  facet is destroyed when the last referencing locale is destroyed.
367*e4b17023SJohn Marino      *  Otherwise the facet will never be destroyed.
368*e4b17023SJohn Marino      *
369*e4b17023SJohn Marino      *  @param __refs  The initial value for reference count.
370*e4b17023SJohn Marino     */
371*e4b17023SJohn Marino     explicit
372*e4b17023SJohn Marino     facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0)
373*e4b17023SJohn Marino     { }
374*e4b17023SJohn Marino 
375*e4b17023SJohn Marino     /// Facet destructor.
376*e4b17023SJohn Marino     virtual
377*e4b17023SJohn Marino     ~facet();
378*e4b17023SJohn Marino 
379*e4b17023SJohn Marino     static void
380*e4b17023SJohn Marino     _S_create_c_locale(__c_locale& __cloc, const char* __s,
381*e4b17023SJohn Marino 		       __c_locale __old = 0);
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino     static __c_locale
384*e4b17023SJohn Marino     _S_clone_c_locale(__c_locale& __cloc) throw();
385*e4b17023SJohn Marino 
386*e4b17023SJohn Marino     static void
387*e4b17023SJohn Marino     _S_destroy_c_locale(__c_locale& __cloc);
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino     static __c_locale
390*e4b17023SJohn Marino     _S_lc_ctype_c_locale(__c_locale __cloc, const char* __s);
391*e4b17023SJohn Marino 
392*e4b17023SJohn Marino     // Returns data from the underlying "C" library data for the
393*e4b17023SJohn Marino     // classic locale.
394*e4b17023SJohn Marino     static __c_locale
395*e4b17023SJohn Marino     _S_get_c_locale();
396*e4b17023SJohn Marino 
397*e4b17023SJohn Marino     _GLIBCXX_CONST static const char*
398*e4b17023SJohn Marino     _S_get_c_name() throw();
399*e4b17023SJohn Marino 
400*e4b17023SJohn Marino   private:
401*e4b17023SJohn Marino     void
402*e4b17023SJohn Marino     _M_add_reference() const throw()
403*e4b17023SJohn Marino     { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino     void
406*e4b17023SJohn Marino     _M_remove_reference() const throw()
407*e4b17023SJohn Marino     {
408*e4b17023SJohn Marino       // Be race-detector-friendly.  For more info see bits/c++config.
409*e4b17023SJohn Marino       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
410*e4b17023SJohn Marino       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
411*e4b17023SJohn Marino 	{
412*e4b17023SJohn Marino           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
413*e4b17023SJohn Marino 	  __try
414*e4b17023SJohn Marino 	    { delete this; }
415*e4b17023SJohn Marino 	  __catch(...)
416*e4b17023SJohn Marino 	    { }
417*e4b17023SJohn Marino 	}
418*e4b17023SJohn Marino     }
419*e4b17023SJohn Marino 
420*e4b17023SJohn Marino     facet(const facet&);  // Not defined.
421*e4b17023SJohn Marino 
422*e4b17023SJohn Marino     facet&
423*e4b17023SJohn Marino     operator=(const facet&);  // Not defined.
424*e4b17023SJohn Marino   };
425*e4b17023SJohn Marino 
426*e4b17023SJohn Marino 
427*e4b17023SJohn Marino   // 22.1.1.1.3 Class locale::id
428*e4b17023SJohn Marino   /**
429*e4b17023SJohn Marino    *  @brief  Facet ID class.
430*e4b17023SJohn Marino    *  @ingroup locales
431*e4b17023SJohn Marino    *
432*e4b17023SJohn Marino    *  The ID class provides facets with an index used to identify them.
433*e4b17023SJohn Marino    *  Every facet class must define a public static member locale::id, or be
434*e4b17023SJohn Marino    *  derived from a facet that provides this member, otherwise the facet
435*e4b17023SJohn Marino    *  cannot be used in a locale.  The locale::id ensures that each class
436*e4b17023SJohn Marino    *  type gets a unique identifier.
437*e4b17023SJohn Marino   */
438*e4b17023SJohn Marino   class locale::id
439*e4b17023SJohn Marino   {
440*e4b17023SJohn Marino   private:
441*e4b17023SJohn Marino     friend class locale;
442*e4b17023SJohn Marino     friend class locale::_Impl;
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino     template<typename _Facet>
445*e4b17023SJohn Marino       friend const _Facet&
446*e4b17023SJohn Marino       use_facet(const locale&);
447*e4b17023SJohn Marino 
448*e4b17023SJohn Marino     template<typename _Facet>
449*e4b17023SJohn Marino       friend bool
450*e4b17023SJohn Marino       has_facet(const locale&) throw();
451*e4b17023SJohn Marino 
452*e4b17023SJohn Marino     // NB: There is no accessor for _M_index because it may be used
453*e4b17023SJohn Marino     // before the constructor is run; the effect of calling a member
454*e4b17023SJohn Marino     // function (even an inline) would be undefined.
455*e4b17023SJohn Marino     mutable size_t		_M_index;
456*e4b17023SJohn Marino 
457*e4b17023SJohn Marino     // Last id number assigned.
458*e4b17023SJohn Marino     static _Atomic_word		_S_refcount;
459*e4b17023SJohn Marino 
460*e4b17023SJohn Marino     void
461*e4b17023SJohn Marino     operator=(const id&);  // Not defined.
462*e4b17023SJohn Marino 
463*e4b17023SJohn Marino     id(const id&);  // Not defined.
464*e4b17023SJohn Marino 
465*e4b17023SJohn Marino   public:
466*e4b17023SJohn Marino     // NB: This class is always a static data member, and thus can be
467*e4b17023SJohn Marino     // counted on to be zero-initialized.
468*e4b17023SJohn Marino     /// Constructor.
469*e4b17023SJohn Marino     id() { }
470*e4b17023SJohn Marino 
471*e4b17023SJohn Marino     size_t
472*e4b17023SJohn Marino     _M_id() const throw();
473*e4b17023SJohn Marino   };
474*e4b17023SJohn Marino 
475*e4b17023SJohn Marino 
476*e4b17023SJohn Marino   // Implementation object for locale.
477*e4b17023SJohn Marino   class locale::_Impl
478*e4b17023SJohn Marino   {
479*e4b17023SJohn Marino   public:
480*e4b17023SJohn Marino     // Friends.
481*e4b17023SJohn Marino     friend class locale;
482*e4b17023SJohn Marino     friend class locale::facet;
483*e4b17023SJohn Marino 
484*e4b17023SJohn Marino     template<typename _Facet>
485*e4b17023SJohn Marino       friend bool
486*e4b17023SJohn Marino       has_facet(const locale&) throw();
487*e4b17023SJohn Marino 
488*e4b17023SJohn Marino     template<typename _Facet>
489*e4b17023SJohn Marino       friend const _Facet&
490*e4b17023SJohn Marino       use_facet(const locale&);
491*e4b17023SJohn Marino 
492*e4b17023SJohn Marino     template<typename _Cache>
493*e4b17023SJohn Marino       friend struct __use_cache;
494*e4b17023SJohn Marino 
495*e4b17023SJohn Marino   private:
496*e4b17023SJohn Marino     // Data Members.
497*e4b17023SJohn Marino     _Atomic_word			_M_refcount;
498*e4b17023SJohn Marino     const facet**			_M_facets;
499*e4b17023SJohn Marino     size_t				_M_facets_size;
500*e4b17023SJohn Marino     const facet**			_M_caches;
501*e4b17023SJohn Marino     char**				_M_names;
502*e4b17023SJohn Marino     static const locale::id* const	_S_id_ctype[];
503*e4b17023SJohn Marino     static const locale::id* const	_S_id_numeric[];
504*e4b17023SJohn Marino     static const locale::id* const	_S_id_collate[];
505*e4b17023SJohn Marino     static const locale::id* const	_S_id_time[];
506*e4b17023SJohn Marino     static const locale::id* const	_S_id_monetary[];
507*e4b17023SJohn Marino     static const locale::id* const	_S_id_messages[];
508*e4b17023SJohn Marino     static const locale::id* const* const _S_facet_categories[];
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino     void
511*e4b17023SJohn Marino     _M_add_reference() throw()
512*e4b17023SJohn Marino     { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
513*e4b17023SJohn Marino 
514*e4b17023SJohn Marino     void
515*e4b17023SJohn Marino     _M_remove_reference() throw()
516*e4b17023SJohn Marino     {
517*e4b17023SJohn Marino       // Be race-detector-friendly.  For more info see bits/c++config.
518*e4b17023SJohn Marino       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
519*e4b17023SJohn Marino       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
520*e4b17023SJohn Marino 	{
521*e4b17023SJohn Marino           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
522*e4b17023SJohn Marino 	  __try
523*e4b17023SJohn Marino 	    { delete this; }
524*e4b17023SJohn Marino 	  __catch(...)
525*e4b17023SJohn Marino 	    { }
526*e4b17023SJohn Marino 	}
527*e4b17023SJohn Marino     }
528*e4b17023SJohn Marino 
529*e4b17023SJohn Marino     _Impl(const _Impl&, size_t);
530*e4b17023SJohn Marino     _Impl(const char*, size_t);
531*e4b17023SJohn Marino     _Impl(size_t) throw();
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino    ~_Impl() throw();
534*e4b17023SJohn Marino 
535*e4b17023SJohn Marino     _Impl(const _Impl&);  // Not defined.
536*e4b17023SJohn Marino 
537*e4b17023SJohn Marino     void
538*e4b17023SJohn Marino     operator=(const _Impl&);  // Not defined.
539*e4b17023SJohn Marino 
540*e4b17023SJohn Marino     bool
541*e4b17023SJohn Marino     _M_check_same_name()
542*e4b17023SJohn Marino     {
543*e4b17023SJohn Marino       bool __ret = true;
544*e4b17023SJohn Marino       if (_M_names[1])
545*e4b17023SJohn Marino 	// We must actually compare all the _M_names: can be all equal!
546*e4b17023SJohn Marino 	for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
547*e4b17023SJohn Marino 	  __ret = __builtin_strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
548*e4b17023SJohn Marino       return __ret;
549*e4b17023SJohn Marino     }
550*e4b17023SJohn Marino 
551*e4b17023SJohn Marino     void
552*e4b17023SJohn Marino     _M_replace_categories(const _Impl*, category);
553*e4b17023SJohn Marino 
554*e4b17023SJohn Marino     void
555*e4b17023SJohn Marino     _M_replace_category(const _Impl*, const locale::id* const*);
556*e4b17023SJohn Marino 
557*e4b17023SJohn Marino     void
558*e4b17023SJohn Marino     _M_replace_facet(const _Impl*, const locale::id*);
559*e4b17023SJohn Marino 
560*e4b17023SJohn Marino     void
561*e4b17023SJohn Marino     _M_install_facet(const locale::id*, const facet*);
562*e4b17023SJohn Marino 
563*e4b17023SJohn Marino     template<typename _Facet>
564*e4b17023SJohn Marino       void
565*e4b17023SJohn Marino       _M_init_facet(_Facet* __facet)
566*e4b17023SJohn Marino       { _M_install_facet(&_Facet::id, __facet); }
567*e4b17023SJohn Marino 
568*e4b17023SJohn Marino     void
569*e4b17023SJohn Marino     _M_install_cache(const facet*, size_t);
570*e4b17023SJohn Marino   };
571*e4b17023SJohn Marino 
572*e4b17023SJohn Marino 
573*e4b17023SJohn Marino   /**
574*e4b17023SJohn Marino    *  @brief  Facet for localized string comparison.
575*e4b17023SJohn Marino    *
576*e4b17023SJohn Marino    *  This facet encapsulates the code to compare strings in a localized
577*e4b17023SJohn Marino    *  manner.
578*e4b17023SJohn Marino    *
579*e4b17023SJohn Marino    *  The collate template uses protected virtual functions to provide
580*e4b17023SJohn Marino    *  the actual results.  The public accessors forward the call to
581*e4b17023SJohn Marino    *  the virtual functions.  These virtual functions are hooks for
582*e4b17023SJohn Marino    *  developers to implement the behavior they require from the
583*e4b17023SJohn Marino    *  collate facet.
584*e4b17023SJohn Marino   */
585*e4b17023SJohn Marino   template<typename _CharT>
586*e4b17023SJohn Marino     class collate : public locale::facet
587*e4b17023SJohn Marino     {
588*e4b17023SJohn Marino     public:
589*e4b17023SJohn Marino       // Types:
590*e4b17023SJohn Marino       //@{
591*e4b17023SJohn Marino       /// Public typedefs
592*e4b17023SJohn Marino       typedef _CharT			char_type;
593*e4b17023SJohn Marino       typedef basic_string<_CharT>	string_type;
594*e4b17023SJohn Marino       //@}
595*e4b17023SJohn Marino 
596*e4b17023SJohn Marino     protected:
597*e4b17023SJohn Marino       // Underlying "C" library locale information saved from
598*e4b17023SJohn Marino       // initialization, needed by collate_byname as well.
599*e4b17023SJohn Marino       __c_locale			_M_c_locale_collate;
600*e4b17023SJohn Marino 
601*e4b17023SJohn Marino     public:
602*e4b17023SJohn Marino       /// Numpunct facet id.
603*e4b17023SJohn Marino       static locale::id			id;
604*e4b17023SJohn Marino 
605*e4b17023SJohn Marino       /**
606*e4b17023SJohn Marino        *  @brief  Constructor performs initialization.
607*e4b17023SJohn Marino        *
608*e4b17023SJohn Marino        *  This is the constructor provided by the standard.
609*e4b17023SJohn Marino        *
610*e4b17023SJohn Marino        *  @param __refs  Passed to the base facet class.
611*e4b17023SJohn Marino       */
612*e4b17023SJohn Marino       explicit
613*e4b17023SJohn Marino       collate(size_t __refs = 0)
614*e4b17023SJohn Marino       : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
615*e4b17023SJohn Marino       { }
616*e4b17023SJohn Marino 
617*e4b17023SJohn Marino       /**
618*e4b17023SJohn Marino        *  @brief  Internal constructor. Not for general use.
619*e4b17023SJohn Marino        *
620*e4b17023SJohn Marino        *  This is a constructor for use by the library itself to set up new
621*e4b17023SJohn Marino        *  locales.
622*e4b17023SJohn Marino        *
623*e4b17023SJohn Marino        *  @param __cloc  The C locale.
624*e4b17023SJohn Marino        *  @param __refs  Passed to the base facet class.
625*e4b17023SJohn Marino       */
626*e4b17023SJohn Marino       explicit
627*e4b17023SJohn Marino       collate(__c_locale __cloc, size_t __refs = 0)
628*e4b17023SJohn Marino       : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
629*e4b17023SJohn Marino       { }
630*e4b17023SJohn Marino 
631*e4b17023SJohn Marino       /**
632*e4b17023SJohn Marino        *  @brief  Compare two strings.
633*e4b17023SJohn Marino        *
634*e4b17023SJohn Marino        *  This function compares two strings and returns the result by calling
635*e4b17023SJohn Marino        *  collate::do_compare().
636*e4b17023SJohn Marino        *
637*e4b17023SJohn Marino        *  @param __lo1  Start of string 1.
638*e4b17023SJohn Marino        *  @param __hi1  End of string 1.
639*e4b17023SJohn Marino        *  @param __lo2  Start of string 2.
640*e4b17023SJohn Marino        *  @param __hi2  End of string 2.
641*e4b17023SJohn Marino        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
642*e4b17023SJohn Marino       */
643*e4b17023SJohn Marino       int
644*e4b17023SJohn Marino       compare(const _CharT* __lo1, const _CharT* __hi1,
645*e4b17023SJohn Marino 	      const _CharT* __lo2, const _CharT* __hi2) const
646*e4b17023SJohn Marino       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
647*e4b17023SJohn Marino 
648*e4b17023SJohn Marino       /**
649*e4b17023SJohn Marino        *  @brief  Transform string to comparable form.
650*e4b17023SJohn Marino        *
651*e4b17023SJohn Marino        *  This function is a wrapper for strxfrm functionality.  It takes the
652*e4b17023SJohn Marino        *  input string and returns a modified string that can be directly
653*e4b17023SJohn Marino        *  compared to other transformed strings.  In the C locale, this
654*e4b17023SJohn Marino        *  function just returns a copy of the input string.  In some other
655*e4b17023SJohn Marino        *  locales, it may replace two chars with one, change a char for
656*e4b17023SJohn Marino        *  another, etc.  It does so by returning collate::do_transform().
657*e4b17023SJohn Marino        *
658*e4b17023SJohn Marino        *  @param __lo  Start of string.
659*e4b17023SJohn Marino        *  @param __hi  End of string.
660*e4b17023SJohn Marino        *  @return  Transformed string_type.
661*e4b17023SJohn Marino       */
662*e4b17023SJohn Marino       string_type
663*e4b17023SJohn Marino       transform(const _CharT* __lo, const _CharT* __hi) const
664*e4b17023SJohn Marino       { return this->do_transform(__lo, __hi); }
665*e4b17023SJohn Marino 
666*e4b17023SJohn Marino       /**
667*e4b17023SJohn Marino        *  @brief  Return hash of a string.
668*e4b17023SJohn Marino        *
669*e4b17023SJohn Marino        *  This function computes and returns a hash on the input string.  It
670*e4b17023SJohn Marino        *  does so by returning collate::do_hash().
671*e4b17023SJohn Marino        *
672*e4b17023SJohn Marino        *  @param __lo  Start of string.
673*e4b17023SJohn Marino        *  @param __hi  End of string.
674*e4b17023SJohn Marino        *  @return  Hash value.
675*e4b17023SJohn Marino       */
676*e4b17023SJohn Marino       long
677*e4b17023SJohn Marino       hash(const _CharT* __lo, const _CharT* __hi) const
678*e4b17023SJohn Marino       { return this->do_hash(__lo, __hi); }
679*e4b17023SJohn Marino 
680*e4b17023SJohn Marino       // Used to abstract out _CharT bits in virtual member functions, below.
681*e4b17023SJohn Marino       int
682*e4b17023SJohn Marino       _M_compare(const _CharT*, const _CharT*) const throw();
683*e4b17023SJohn Marino 
684*e4b17023SJohn Marino       size_t
685*e4b17023SJohn Marino       _M_transform(_CharT*, const _CharT*, size_t) const throw();
686*e4b17023SJohn Marino 
687*e4b17023SJohn Marino   protected:
688*e4b17023SJohn Marino       /// Destructor.
689*e4b17023SJohn Marino       virtual
690*e4b17023SJohn Marino       ~collate()
691*e4b17023SJohn Marino       { _S_destroy_c_locale(_M_c_locale_collate); }
692*e4b17023SJohn Marino 
693*e4b17023SJohn Marino       /**
694*e4b17023SJohn Marino        *  @brief  Compare two strings.
695*e4b17023SJohn Marino        *
696*e4b17023SJohn Marino        *  This function is a hook for derived classes to change the value
697*e4b17023SJohn Marino        *  returned.  @see compare().
698*e4b17023SJohn Marino        *
699*e4b17023SJohn Marino        *  @param __lo1  Start of string 1.
700*e4b17023SJohn Marino        *  @param __hi1  End of string 1.
701*e4b17023SJohn Marino        *  @param __lo2  Start of string 2.
702*e4b17023SJohn Marino        *  @param __hi2  End of string 2.
703*e4b17023SJohn Marino        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
704*e4b17023SJohn Marino       */
705*e4b17023SJohn Marino       virtual int
706*e4b17023SJohn Marino       do_compare(const _CharT* __lo1, const _CharT* __hi1,
707*e4b17023SJohn Marino 		 const _CharT* __lo2, const _CharT* __hi2) const;
708*e4b17023SJohn Marino 
709*e4b17023SJohn Marino       /**
710*e4b17023SJohn Marino        *  @brief  Transform string to comparable form.
711*e4b17023SJohn Marino        *
712*e4b17023SJohn Marino        *  This function is a hook for derived classes to change the value
713*e4b17023SJohn Marino        *  returned.
714*e4b17023SJohn Marino        *
715*e4b17023SJohn Marino        *  @param __lo  Start.
716*e4b17023SJohn Marino        *  @param __hi  End.
717*e4b17023SJohn Marino        *  @return  transformed string.
718*e4b17023SJohn Marino       */
719*e4b17023SJohn Marino       virtual string_type
720*e4b17023SJohn Marino       do_transform(const _CharT* __lo, const _CharT* __hi) const;
721*e4b17023SJohn Marino 
722*e4b17023SJohn Marino       /**
723*e4b17023SJohn Marino        *  @brief  Return hash of a string.
724*e4b17023SJohn Marino        *
725*e4b17023SJohn Marino        *  This function computes and returns a hash on the input string.  This
726*e4b17023SJohn Marino        *  function is a hook for derived classes to change the value returned.
727*e4b17023SJohn Marino        *
728*e4b17023SJohn Marino        *  @param __lo  Start of string.
729*e4b17023SJohn Marino        *  @param __hi  End of string.
730*e4b17023SJohn Marino        *  @return  Hash value.
731*e4b17023SJohn Marino       */
732*e4b17023SJohn Marino       virtual long
733*e4b17023SJohn Marino       do_hash(const _CharT* __lo, const _CharT* __hi) const;
734*e4b17023SJohn Marino     };
735*e4b17023SJohn Marino 
736*e4b17023SJohn Marino   template<typename _CharT>
737*e4b17023SJohn Marino     locale::id collate<_CharT>::id;
738*e4b17023SJohn Marino 
739*e4b17023SJohn Marino   // Specializations.
740*e4b17023SJohn Marino   template<>
741*e4b17023SJohn Marino     int
742*e4b17023SJohn Marino     collate<char>::_M_compare(const char*, const char*) const throw();
743*e4b17023SJohn Marino 
744*e4b17023SJohn Marino   template<>
745*e4b17023SJohn Marino     size_t
746*e4b17023SJohn Marino     collate<char>::_M_transform(char*, const char*, size_t) const throw();
747*e4b17023SJohn Marino 
748*e4b17023SJohn Marino #ifdef _GLIBCXX_USE_WCHAR_T
749*e4b17023SJohn Marino   template<>
750*e4b17023SJohn Marino     int
751*e4b17023SJohn Marino     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const throw();
752*e4b17023SJohn Marino 
753*e4b17023SJohn Marino   template<>
754*e4b17023SJohn Marino     size_t
755*e4b17023SJohn Marino     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const throw();
756*e4b17023SJohn Marino #endif
757*e4b17023SJohn Marino 
758*e4b17023SJohn Marino   /// class collate_byname [22.2.4.2].
759*e4b17023SJohn Marino   template<typename _CharT>
760*e4b17023SJohn Marino     class collate_byname : public collate<_CharT>
761*e4b17023SJohn Marino     {
762*e4b17023SJohn Marino     public:
763*e4b17023SJohn Marino       //@{
764*e4b17023SJohn Marino       /// Public typedefs
765*e4b17023SJohn Marino       typedef _CharT               char_type;
766*e4b17023SJohn Marino       typedef basic_string<_CharT> string_type;
767*e4b17023SJohn Marino       //@}
768*e4b17023SJohn Marino 
769*e4b17023SJohn Marino       explicit
770*e4b17023SJohn Marino       collate_byname(const char* __s, size_t __refs = 0)
771*e4b17023SJohn Marino       : collate<_CharT>(__refs)
772*e4b17023SJohn Marino       {
773*e4b17023SJohn Marino 	if (__builtin_strcmp(__s, "C") != 0
774*e4b17023SJohn Marino 	    && __builtin_strcmp(__s, "POSIX") != 0)
775*e4b17023SJohn Marino 	  {
776*e4b17023SJohn Marino 	    this->_S_destroy_c_locale(this->_M_c_locale_collate);
777*e4b17023SJohn Marino 	    this->_S_create_c_locale(this->_M_c_locale_collate, __s);
778*e4b17023SJohn Marino 	  }
779*e4b17023SJohn Marino       }
780*e4b17023SJohn Marino 
781*e4b17023SJohn Marino     protected:
782*e4b17023SJohn Marino       virtual
783*e4b17023SJohn Marino       ~collate_byname() { }
784*e4b17023SJohn Marino     };
785*e4b17023SJohn Marino 
786*e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
787*e4b17023SJohn Marino } // namespace
788*e4b17023SJohn Marino 
789*e4b17023SJohn Marino # include <bits/locale_classes.tcc>
790*e4b17023SJohn Marino 
791*e4b17023SJohn Marino #endif
792