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