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