# locale_classes.h

Go to the documentation of this file.

    00001 // Locale support -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    00004 // 2006, 2007, 2008, 2009
    00005 // Free Software Foundation, Inc.
    00006 //
    00007 // This file is part of the GNU ISO C++ Library.  This library is free
    00008 // software; you can redistribute it and/or modify it under the
    00009 // terms of the GNU General Public License as published by the
    00010 // Free Software Foundation; either version 3, or (at your option)
    00011 // any later version.
    00012
    00013 // This library is distributed in the hope that it will be useful,
    00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00016 // GNU General Public License for more details.
    00017
    00018 // Under Section 7 of GPL version 3, you are granted additional
    00019 // permissions described in the GCC Runtime Library Exception, version
    00020 // 3.1, as published by the Free Software Foundation.
    00021
    00022 // You should have received a copy of the GNU General Public License and
    00023 // a copy of the GCC Runtime Library Exception along with this program;
    00024 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00025 // <http://www.gnu.org/licenses/>.
    00026
    00027 /** @file locale_classes.h
    00028  *  This is an internal header file, included by other library headers.
    00029  *  You should not attempt to use it directly.
    00030  */
    00031
    00032 //
    00033 // ISO C++ 14882: 22.1  Locales
    00034 //
    00035
    00036 #ifndef _LOCALE_CLASSES_H
    00037 #define _LOCALE_CLASSES_H 1
    00038
    00039 #pragma GCC system_header
    00040
    00041 #include <bits/localefwd.h>
    00042 #include <string>
    00043 #include <ext/atomicity.h>
    00044
    00045 _GLIBCXX_BEGIN_NAMESPACE(std)
    00046
    00047   // 22.1.1 Class locale
    00048   /**
    00049    *  @brief  Container class for localization functionality.
    00050    *
    00051    *  The locale class is first a class wrapper for C library locales.  It is
    00052    *  also an extensible container for user-defined localization.  A locale is
    00053    *  a collection of facets that implement various localization features such
    00054    *  as money, time, and number printing.
    00055    *
    00056    *  Constructing C++ locales does not change the C library locale.
    00057    *
    00058    *  This library supports efficient construction and copying of locales
    00059    *  through a reference counting implementation of the locale class.
    00060   */
    00061   class locale
    00062   {
    00063   public:
    00064     // Types:
    00065     /// Definition of locale::category.
    00066     typedef int category;
    00067
    00068     // Forward decls and friends:
    00069     class facet;
    00070     class id;
    00071     class _Impl;
    00072
    00073     friend class facet;
    00074     friend class _Impl;
    00075
    00076     template<typename _Facet>
    00077       friend bool
    00078       has_facet(const locale&) throw();
    00079
    00080     template<typename _Facet>
    00081       friend const _Facet&
    00082       use_facet(const locale&);
    00083
    00084     template<typename _Cache>
    00085       friend struct __use_cache;
    00086
    00087     //@{
    00088     /**
    00089      *  @brief  Category values.
    00090      *
    00091      *  The standard category values are none, ctype, numeric, collate, time,
    00092      *  monetary, and messages.  They form a bitmask that supports union and
    00093      *  intersection.  The category all is the union of these values.
    00094      *
    00095      *  NB: Order must match _S_facet_categories definition in locale.cc
    00096     */
    00097     static const category none      = 0;
    00098     static const category ctype     = 1L << 0;
    00099     static const category numeric   = 1L << 1;
    00100     static const category collate   = 1L << 2;
    00101     static const category time      = 1L << 3;
    00102     static const category monetary  = 1L << 4;
    00103     static const category messages  = 1L << 5;
    00104     static const category all       = (ctype | numeric | collate |
    00105                        time  | monetary | messages);
    00106     //@}
    00107
    00108     // Construct/copy/destroy:
    00109
    00110     /**
    00111      *  @brief  Default constructor.
    00112      *
    00113      *  Constructs a copy of the global locale.  If no locale has been
    00114      *  explicitly set, this is the "C" locale.
    00115     */
    00116     locale() throw();
    00117
    00118     /**
    00119      *  @brief  Copy constructor.
    00120      *
    00121      *  Constructs a copy of @a other.
    00122      *
    00123      *  @param  other  The locale to copy.
    00124     */
    00125     locale(const locale& __other) throw();
    00126
    00127     /**
    00128      *  @brief  Named locale constructor.
    00129      *
    00130      *  Constructs a copy of the named C library locale.
    00131      *
    00132      *  @param  s  Name of the locale to construct.
    00133      *  @throw  std::runtime_error if s is null or an undefined locale.
    00134     */
    00135     explicit
    00136     locale(const char* __s);
    00137
    00138     /**
    00139      *  @brief  Construct locale with facets from another locale.
    00140      *
    00141      *  Constructs a copy of the locale @a base.  The facets specified by @a
    00142      *  cat are replaced with those from the locale named by @a s.  If base is
    00143      *  named, this locale instance will also be named.
    00144      *
    00145      *  @param  base  The locale to copy.
    00146      *  @param  s  Name of the locale to use facets from.
    00147      *  @param  cat  Set of categories defining the facets to use from s.
    00148      *  @throw  std::runtime_error if s is null or an undefined locale.
    00149     */
    00150     locale(const locale& __base, const char* __s, category __cat);
    00151
    00152     /**
    00153      *  @brief  Construct locale with facets from another locale.
    00154      *
    00155      *  Constructs a copy of the locale @a base.  The facets specified by @a
    00156      *  cat are replaced with those from the locale @a add.  If @a base and @a
    00157      *  add are named, this locale instance will also be named.
    00158      *
    00159      *  @param  base  The locale to copy.
    00160      *  @param  add  The locale to use facets from.
    00161      *  @param  cat  Set of categories defining the facets to use from add.
    00162     */
    00163     locale(const locale& __base, const locale& __add, category __cat);
    00164
    00165     /**
    00166      *  @brief  Construct locale with another facet.
    00167      *
    00168      *  Constructs a copy of the locale @a other.  The facet @f is added to
    00169      *  @other, replacing an existing facet of type Facet if there is one.  If
    00170      *  @f is null, this locale is a copy of @a other.
    00171      *
    00172      *  @param  other  The locale to copy.
    00173      *  @param  f  The facet to add in.
    00174     */
    00175     template<typename _Facet>
    00176       locale(const locale& __other, _Facet* __f);
    00177
    00178     /// Locale destructor.
    00179     ~locale() throw();
    00180
    00181     /**
    00182      *  @brief  Assignment operator.
    00183      *
    00184      *  Set this locale to be a copy of @a other.
    00185      *
    00186      *  @param  other  The locale to copy.
    00187      *  @return  A reference to this locale.
    00188     */
    00189     const locale&
    00190     operator=(const locale& __other) throw();
    00191
    00192     /**
    00193      *  @brief  Construct locale with another facet.
    00194      *
    00195      *  Constructs and returns a new copy of this locale.  Adds or replaces an
    00196      *  existing facet of type Facet from the locale @a other into the new
    00197      *  locale.
    00198      *
    00199      *  @param  Facet  The facet type to copy from other
    00200      *  @param  other  The locale to copy from.
    00201      *  @return  Newly constructed locale.
    00202      *  @throw  std::runtime_error if other has no facet of type Facet.
    00203     */
    00204     template<typename _Facet>
    00205       locale
    00206       combine(const locale& __other) const;
    00207
    00208     // Locale operations:
    00209     /**
    00210      *  @brief  Return locale name.
    00211      *  @return  Locale name or "*" if unnamed.
    00212     */
    00213     string
    00214     name() const;
    00215
    00216     /**
    00217      *  @brief  Locale equality.
    00218      *
    00219      *  @param  other  The locale to compare against.
    00220      *  @return  True if other and this refer to the same locale instance, are
    00221      *       copies, or have the same name.  False otherwise.
    00222     */
    00223     bool
    00224     operator==(const locale& __other) const throw ();
    00225
    00226     /**
    00227      *  @brief  Locale inequality.
    00228      *
    00229      *  @param  other  The locale to compare against.
    00230      *  @return  ! (*this == other)
    00231     */
    00232     bool
    00233     operator!=(const locale& __other) const throw ()
    00234     { return !(this->operator==(__other)); }
    00235
    00236     /**
    00237      *  @brief  Compare two strings according to collate.
    00238      *
    00239      *  Template operator to compare two strings using the compare function of
    00240      *  the collate facet in this locale.  One use is to provide the locale to
    00241      *  the sort function.  For example, a vector v of strings could be sorted
    00242      *  according to locale loc by doing:
    00243      *  @code
    00244      *  std::sort(v.begin(), v.end(), loc);
    00245      *  @endcode
    00246      *
    00247      *  @param  s1  First string to compare.
    00248      *  @param  s2  Second string to compare.
    00249      *  @return  True if collate<Char> facet compares s1 < s2, else false.
    00250     */
    00251     template<typename _Char, typename _Traits, typename _Alloc>
    00252       bool
    00253       operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
    00254          const basic_string<_Char, _Traits, _Alloc>& __s2) const;
    00255
    00256     // Global locale objects:
    00257     /**
    00258      *  @brief  Set global locale
    00259      *
    00260      *  This function sets the global locale to the argument and returns a
    00261      *  copy of the previous global locale.  If the argument has a name, it
    00262      *  will also call std::setlocale(LC_ALL, loc.name()).
    00263      *
    00264      *  @param  locale  The new locale to make global.
    00265      *  @return  Copy of the old global locale.
    00266     */
    00267     static locale
    00268     global(const locale&);
    00269
    00270     /**
    00271      *  @brief  Return reference to the "C" locale.
    00272     */
    00273     static const locale&
    00274     classic();
    00275
    00276   private:
    00277     // The (shared) implementation
    00278     _Impl*      _M_impl;
    00279
    00280     // The "C" reference locale
    00281     static _Impl*       _S_classic;
    00282
    00283     // Current global locale
    00284     static _Impl*   _S_global;
    00285
    00286     // Names of underlying locale categories.
    00287     // NB: locale::global() has to know how to modify all the
    00288     // underlying categories, not just the ones required by the C++
    00289     // standard.
    00290     static const char* const* const _S_categories;
    00291
    00292     // Number of standard categories. For C++, these categories are
    00293     // collate, ctype, monetary, numeric, time, and messages. These
    00294     // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
    00295     // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
    00296     // 1003.1-2001) specifies LC_MESSAGES.
    00297     // In addition to the standard categories, the underlying
    00298     // operating system is allowed to define extra LC_*
    00299     // macros. For GNU systems, the following are also valid:
    00300     // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
    00301     // and LC_IDENTIFICATION.
    00302     enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES };
    00303
    00304 #ifdef __GTHREADS
    00305     static __gthread_once_t _S_once;
    00306 #endif
    00307
    00308     explicit
    00309     locale(_Impl*) throw();
    00310
    00311     static void
    00312     _S_initialize();
    00313
    00314     static void
    00315     _S_initialize_once();
    00316
    00317     static category
    00318     _S_normalize_category(category);
    00319
    00320     void
    00321     _M_coalesce(const locale& __base, const locale& __add, category __cat);
    00322   };
    00323
    00324
    00325   // 22.1.1.1.2  Class locale::facet
    00326   /**
    00327    *  @brief  Localization functionality base class.
    00328    *
    00329    *  The facet class is the base class for a localization feature, such as
    00330    *  money, time, and number printing.  It provides common support for facets
    00331    *  and reference management.
    00332    *
    00333    *  Facets may not be copied or assigned.
    00334   */
    00335   class locale::facet
    00336   {
    00337   private:
    00338     friend class locale;
    00339     friend class locale::_Impl;
    00340
    00341     mutable _Atomic_word        _M_refcount;
    00342
    00343     // Contains data from the underlying "C" library for the classic locale.
    00344     static __c_locale                   _S_c_locale;
    00345
    00346     // String literal for the name of the classic locale.
    00347     static const char           _S_c_name[2];
    00348
    00349 #ifdef __GTHREADS
    00350     static __gthread_once_t     _S_once;
    00351 #endif
    00352
    00353     static void
    00354     _S_initialize_once();
    00355
    00356   protected:
    00357     /**
    00358      *  @brief  Facet constructor.
    00359      *
    00360      *  This is the constructor provided by the standard.  If refs is 0, the
    00361      *  facet is destroyed when the last referencing locale is destroyed.
    00362      *  Otherwise the facet will never be destroyed.
    00363      *
    00364      *  @param refs  The initial value for reference count.
    00365     */
    00366     explicit
    00367     facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0)
    00368     { }
    00369
    00370     /// Facet destructor.
    00371     virtual
    00372     ~facet();
    00373
    00374     static void
    00375     _S_create_c_locale(__c_locale& __cloc, const char* __s,
    00376                __c_locale __old = 0);
    00377
    00378     static __c_locale
    00379     _S_clone_c_locale(__c_locale& __cloc);
    00380
    00381     static void
    00382     _S_destroy_c_locale(__c_locale& __cloc);
    00383
    00384     // Returns data from the underlying "C" library data for the
    00385     // classic locale.
    00386     static __c_locale
    00387     _S_get_c_locale();
    00388
    00389     static const char*
    00390     _S_get_c_name();
    00391
    00392   private:
    00393     void
    00394     _M_add_reference() const throw()
    00395     { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
    00396
    00397     void
    00398     _M_remove_reference() const throw()
    00399     {
    00400       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
    00401     {
    00402       __try
    00403         { delete this; }
    00404       __catch(...)
    00405         { }
    00406     }
    00407     }
    00408
    00409     facet(const facet&);  // Not defined.
    00410
    00411     facet&
    00412     operator=(const facet&);  // Not defined.
    00413   };
    00414
    00415
    00416   // 22.1.1.1.3 Class locale::id
    00417   /**
    00418    *  @brief  Facet ID class.
    00419    *
    00420    *  The ID class provides facets with an index used to identify them.
    00421    *  Every facet class must define a public static member locale::id, or be
    00422    *  derived from a facet that provides this member, otherwise the facet
    00423    *  cannot be used in a locale.  The locale::id ensures that each class
    00424    *  type gets a unique identifier.
    00425   */
    00426   class locale::id
    00427   {
    00428   private:
    00429     friend class locale;
    00430     friend class locale::_Impl;
    00431
    00432     template<typename _Facet>
    00433       friend const _Facet&
    00434       use_facet(const locale&);
    00435
    00436     template<typename _Facet>
    00437       friend bool
    00438       has_facet(const locale&) throw ();
    00439
    00440     // NB: There is no accessor for _M_index because it may be used
    00441     // before the constructor is run; the effect of calling a member
    00442     // function (even an inline) would be undefined.
    00443     mutable size_t      _M_index;
    00444
    00445     // Last id number assigned.
    00446     static _Atomic_word     _S_refcount;
    00447
    00448     void
    00449     operator=(const id&);  // Not defined.
    00450
    00451     id(const id&);  // Not defined.
    00452
    00453   public:
    00454     // NB: This class is always a static data member, and thus can be
    00455     // counted on to be zero-initialized.
    00456     /// Constructor.
    00457     id() { }
    00458
    00459     size_t
    00460     _M_id() const;
    00461   };
    00462
    00463
    00464   // Implementation object for locale.
    00465   class locale::_Impl
    00466   {
    00467   public:
    00468     // Friends.
    00469     friend class locale;
    00470     friend class locale::facet;
    00471
    00472     template<typename _Facet>
    00473       friend bool
    00474       has_facet(const locale&) throw();
    00475
    00476     template<typename _Facet>
    00477       friend const _Facet&
    00478       use_facet(const locale&);
    00479
    00480     template<typename _Cache>
    00481       friend struct __use_cache;
    00482
    00483   private:
    00484     // Data Members.
    00485     _Atomic_word            _M_refcount;
    00486     const facet**           _M_facets;
    00487     size_t              _M_facets_size;
    00488     const facet**           _M_caches;
    00489     char**              _M_names;
    00490     static const locale::id* const  _S_id_ctype[];
    00491     static const locale::id* const  _S_id_numeric[];
    00492     static const locale::id* const  _S_id_collate[];
    00493     static const locale::id* const  _S_id_time[];
    00494     static const locale::id* const  _S_id_monetary[];
    00495     static const locale::id* const  _S_id_messages[];
    00496     static const locale::id* const* const _S_facet_categories[];
    00497
    00498     void
    00499     _M_add_reference() throw()
    00500     { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
    00501
    00502     void
    00503     _M_remove_reference() throw()
    00504     {
    00505       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
    00506     {
    00507       __try
    00508         { delete this; }
    00509       __catch(...)
    00510         { }
    00511     }
    00512     }
    00513
    00514     _Impl(const _Impl&, size_t);
    00515     _Impl(const char*, size_t);
    00516     _Impl(size_t) throw();
    00517
    00518    ~_Impl() throw();
    00519
    00520     _Impl(const _Impl&);  // Not defined.
    00521
    00522     void
    00523     operator=(const _Impl&);  // Not defined.
    00524
    00525     bool
    00526     _M_check_same_name()
    00527     {
    00528       bool __ret = true;
    00529       if (_M_names[1])
    00530     // We must actually compare all the _M_names: can be all equal!
    00531     for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
    00532       __ret = __builtin_strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
    00533       return __ret;
    00534     }
    00535
    00536     void
    00537     _M_replace_categories(const _Impl*, category);
    00538
    00539     void
    00540     _M_replace_category(const _Impl*, const locale::id* const*);
    00541
    00542     void
    00543     _M_replace_facet(const _Impl*, const locale::id*);
    00544
    00545     void
    00546     _M_install_facet(const locale::id*, const facet*);
    00547
    00548     template<typename _Facet>
    00549       void
    00550       _M_init_facet(_Facet* __facet)
    00551       { _M_install_facet(&_Facet::id, __facet); }
    00552
    00553     void
    00554     _M_install_cache(const facet*, size_t);
    00555   };
    00556
    00557
    00558   /**
    00559    *  @brief  Test for the presence of a facet.
    00560    *
    00561    *  has_facet tests the locale argument for the presence of the facet type
    00562    *  provided as the template parameter.  Facets derived from the facet
    00563    *  parameter will also return true.
    00564    *
    00565    *  @param  Facet  The facet type to test the presence of.
    00566    *  @param  locale  The locale to test.
    00567    *  @return  true if locale contains a facet of type Facet, else false.
    00568   */
    00569   template<typename _Facet>
    00570     bool
    00571     has_facet(const locale& __loc) throw();
    00572
    00573   /**
    00574    *  @brief  Return a facet.
    00575    *
    00576    *  use_facet looks for and returns a reference to a facet of type Facet
    00577    *  where Facet is the template parameter.  If has_facet(locale) is true,
    00578    *  there is a suitable facet to return.  It throws std::bad_cast if the
    00579    *  locale doesn't contain a facet of type Facet.
    00580    *
    00581    *  @param  Facet  The facet type to access.
    00582    *  @param  locale  The locale to use.
    00583    *  @return  Reference to facet of type Facet.
    00584    *  @throw  std::bad_cast if locale doesn't contain a facet of type Facet.
    00585   */
    00586   template<typename _Facet>
    00587     const _Facet&
    00588     use_facet(const locale& __loc);
    00589
    00590
    00591   /**
    00592    *  @brief  Facet for localized string comparison.
    00593    *
    00594    *  This facet encapsulates the code to compare strings in a localized
    00595    *  manner.
    00596    *
    00597    *  The collate template uses protected virtual functions to provide
    00598    *  the actual results.  The public accessors forward the call to
    00599    *  the virtual functions.  These virtual functions are hooks for
    00600    *  developers to implement the behavior they require from the
    00601    *  collate facet.
    00602   */
    00603   template<typename _CharT>
    00604     class collate : public locale::facet
    00605     {
    00606     public:
    00607       // Types:
    00608       //@{
    00609       /// Public typedefs
    00610       typedef _CharT            char_type;
    00611       typedef basic_string<_CharT>  string_type;
    00612       //@}
    00613
    00614     protected:
    00615       // Underlying "C" library locale information saved from
    00616       // initialization, needed by collate_byname as well.
    00617       __c_locale            _M_c_locale_collate;
    00618
    00619     public:
    00620       /// Numpunct facet id.
    00621       static locale::id         id;
    00622
    00623       /**
    00624        *  @brief  Constructor performs initialization.
    00625        *
    00626        *  This is the constructor provided by the standard.
    00627        *
    00628        *  @param refs  Passed to the base facet class.
    00629       */
    00630       explicit
    00631       collate(size_t __refs = 0)
    00632       : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
    00633       { }
    00634
    00635       /**
    00636        *  @brief  Internal constructor. Not for general use.
    00637        *
    00638        *  This is a constructor for use by the library itself to set up new
    00639        *  locales.
    00640        *
    00641        *  @param cloc  The "C" locale.
    00642        *  @param refs  Passed to the base facet class.
    00643       */
    00644       explicit
    00645       collate(__c_locale __cloc, size_t __refs = 0)
    00646       : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
    00647       { }
    00648
    00649       /**
    00650        *  @brief  Compare two strings.
    00651        *
    00652        *  This function compares two strings and returns the result by calling
    00653        *  collate::do_compare().
    00654        *
    00655        *  @param lo1  Start of string 1.
    00656        *  @param hi1  End of string 1.
    00657        *  @param lo2  Start of string 2.
    00658        *  @param hi2  End of string 2.
    00659        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
    00660       */
    00661       int
    00662       compare(const _CharT* __lo1, const _CharT* __hi1,
    00663           const _CharT* __lo2, const _CharT* __hi2) const
    00664       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
    00665
    00666       /**
    00667        *  @brief  Transform string to comparable form.
    00668        *
    00669        *  This function is a wrapper for strxfrm functionality.  It takes the
    00670        *  input string and returns a modified string that can be directly
    00671        *  compared to other transformed strings.  In the "C" locale, this
    00672        *  function just returns a copy of the input string.  In some other
    00673        *  locales, it may replace two chars with one, change a char for
    00674        *  another, etc.  It does so by returning collate::do_transform().
    00675        *
    00676        *  @param lo  Start of string.
    00677        *  @param hi  End of string.
    00678        *  @return  Transformed string_type.
    00679       */
    00680       string_type
    00681       transform(const _CharT* __lo, const _CharT* __hi) const
    00682       { return this->do_transform(__lo, __hi); }
    00683
    00684       /**
    00685        *  @brief  Return hash of a string.
    00686        *
    00687        *  This function computes and returns a hash on the input string.  It
    00688        *  does so by returning collate::do_hash().
    00689        *
    00690        *  @param lo  Start of string.
    00691        *  @param hi  End of string.
    00692        *  @return  Hash value.
    00693       */
    00694       long
    00695       hash(const _CharT* __lo, const _CharT* __hi) const
    00696       { return this->do_hash(__lo, __hi); }
    00697
    00698       // Used to abstract out _CharT bits in virtual member functions, below.
    00699       int
    00700       _M_compare(const _CharT*, const _CharT*) const;
    00701
    00702       size_t
    00703       _M_transform(_CharT*, const _CharT*, size_t) const;
    00704
    00705   protected:
    00706       /// Destructor.
    00707       virtual
    00708       ~collate()
    00709       { _S_destroy_c_locale(_M_c_locale_collate); }
    00710
    00711       /**
    00712        *  @brief  Compare two strings.
    00713        *
    00714        *  This function is a hook for derived classes to change the value
    00715        *  returned.  @see compare().
    00716        *
    00717        *  @param lo1  Start of string 1.
    00718        *  @param hi1  End of string 1.
    00719        *  @param lo2  Start of string 2.
    00720        *  @param hi2  End of string 2.
    00721        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
    00722       */
    00723       virtual int
    00724       do_compare(const _CharT* __lo1, const _CharT* __hi1,
    00725          const _CharT* __lo2, const _CharT* __hi2) const;
    00726
    00727       /**
    00728        *  @brief  Transform string to comparable form.
    00729        *
    00730        *  This function is a hook for derived classes to change the value
    00731        *  returned.
    00732        *
    00733        *  @param lo1  Start of string 1.
    00734        *  @param hi1  End of string 1.
    00735        *  @param lo2  Start of string 2.
    00736        *  @param hi2  End of string 2.
    00737        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
    00738       */
    00739       virtual string_type
    00740       do_transform(const _CharT* __lo, const _CharT* __hi) const;
    00741
    00742       /**
    00743        *  @brief  Return hash of a string.
    00744        *
    00745        *  This function computes and returns a hash on the input string.  This
    00746        *  function is a hook for derived classes to change the value returned.
    00747        *
    00748        *  @param lo  Start of string.
    00749        *  @param hi  End of string.
    00750        *  @return  Hash value.
    00751       */
    00752       virtual long
    00753       do_hash(const _CharT* __lo, const _CharT* __hi) const;
    00754     };
    00755
    00756   template<typename _CharT>
    00757     locale::id collate<_CharT>::id;
    00758
    00759   // Specializations.
    00760   template<>
    00761     int
    00762     collate<char>::_M_compare(const char*, const char*) const;
    00763
    00764   template<>
    00765     size_t
    00766     collate<char>::_M_transform(char*, const char*, size_t) const;
    00767
    00768 #ifdef _GLIBCXX_USE_WCHAR_T
    00769   template<>
    00770     int
    00771     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;
    00772
    00773   template<>
    00774     size_t
    00775     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;
    00776 #endif
    00777
    00778   /// class collate_byname [22.2.4.2].
    00779   template<typename _CharT>
    00780     class collate_byname : public collate<_CharT>
    00781     {
    00782     public:
    00783       //@{
    00784       /// Public typedefs
    00785       typedef _CharT               char_type;
    00786       typedef basic_string<_CharT> string_type;
    00787       //@}
    00788
    00789       explicit
    00790       collate_byname(const char* __s, size_t __refs = 0)
    00791       : collate<_CharT>(__refs)
    00792       {
    00793     if (__builtin_strcmp(__s, "C") != 0
    00794         && __builtin_strcmp(__s, "POSIX") != 0)
    00795       {
    00796         this->_S_destroy_c_locale(this->_M_c_locale_collate);
    00797         this->_S_create_c_locale(this->_M_c_locale_collate, __s);
    00798       }
    00799       }
    00800
    00801     protected:
    00802       virtual
    00803       ~collate_byname() { }
    00804     };
    00805
    00806 _GLIBCXX_END_NAMESPACE
    00807
    00808 #ifndef _GLIBCXX_EXPORT_TEMPLATE
    00809 # include <bits/locale_classes.tcc>
    00810 #endif
    00811
    00812 #endif