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