LCOV - code coverage report
Current view: top level - 11/bits - locale_classes.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 1 5 20.0 %
Date: 2025-08-24 09:11:10 Functions: 1 3 33.3 %

          Line data    Source code
       1             : // Locale support -*- C++ -*-
       2             : 
       3             : // Copyright (C) 1997-2021 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             : #if __cplusplus >= 201103L
     154             :     /**
     155             :      *  @brief  Named locale constructor.
     156             :      *
     157             :      *  Constructs a copy of the named C library locale.
     158             :      *
     159             :      *  @param  __s  Name of the locale to construct.
     160             :      *  @throw  std::runtime_error if __s is an undefined locale.
     161             :     */
     162             :     explicit
     163             :     locale(const std::string& __s) : locale(__s.c_str()) { }
     164             : 
     165             :     /**
     166             :      *  @brief  Construct locale with facets from another locale.
     167             :      *
     168             :      *  Constructs a copy of the locale @a base.  The facets specified by @a
     169             :      *  cat are replaced with those from the locale named by @a s.  If base is
     170             :      *  named, this locale instance will also be named.
     171             :      *
     172             :      *  @param  __base  The locale to copy.
     173             :      *  @param  __s  Name of the locale to use facets from.
     174             :      *  @param  __cat  Set of categories defining the facets to use from __s.
     175             :      *  @throw  std::runtime_error if __s is an undefined locale.
     176             :     */
     177             :     locale(const locale& __base, const std::string& __s, category __cat)
     178             :     : locale(__base, __s.c_str(), __cat) { }
     179             : #endif
     180             : 
     181             :     /**
     182             :      *  @brief  Construct locale with facets from another locale.
     183             :      *
     184             :      *  Constructs a copy of the locale @a base.  The facets specified by @a
     185             :      *  cat are replaced with those from the locale @a add.  If @a base and @a
     186             :      *  add are named, this locale instance will also be named.
     187             :      *
     188             :      *  @param  __base  The locale to copy.
     189             :      *  @param  __add  The locale to use facets from.
     190             :      *  @param  __cat  Set of categories defining the facets to use from add.
     191             :     */
     192             :     locale(const locale& __base, const locale& __add, category __cat);
     193             : 
     194             :     /**
     195             :      *  @brief  Construct locale with another facet.
     196             :      *
     197             :      *  Constructs a copy of the locale @a __other.  The facet @a __f
     198             :      *  is added to @a __other, replacing an existing facet of type
     199             :      *  Facet if there is one.  If @a __f is null, this locale is a
     200             :      *  copy of @a __other.
     201             :      *
     202             :      *  @param  __other  The locale to copy.
     203             :      *  @param  __f  The facet to add in.
     204             :     */
     205             :     template<typename _Facet>
     206             :       locale(const locale& __other, _Facet* __f);
     207             : 
     208             :     /// Locale destructor.
     209             :     ~locale() throw();
     210             : 
     211             :     /**
     212             :      *  @brief  Assignment operator.
     213             :      *
     214             :      *  Set this locale to be a copy of @a other.
     215             :      *
     216             :      *  @param  __other  The locale to copy.
     217             :      *  @return  A reference to this locale.
     218             :     */
     219             :     const locale&
     220             :     operator=(const locale& __other) throw();
     221             : 
     222             :     /**
     223             :      *  @brief  Construct locale with another facet.
     224             :      *
     225             :      *  Constructs and returns a new copy of this locale.  Adds or replaces an
     226             :      *  existing facet of type Facet from the locale @a other into the new
     227             :      *  locale.
     228             :      *
     229             :      *  @tparam  _Facet  The facet type to copy from other
     230             :      *  @param  __other  The locale to copy from.
     231             :      *  @return  Newly constructed locale.
     232             :      *  @throw  std::runtime_error if __other has no facet of type _Facet.
     233             :     */
     234             :     template<typename _Facet>
     235             :       locale
     236             :       combine(const locale& __other) const;
     237             : 
     238             :     // Locale operations:
     239             :     /**
     240             :      *  @brief  Return locale name.
     241             :      *  @return  Locale name or "*" if unnamed.
     242             :     */
     243             :     _GLIBCXX_DEFAULT_ABI_TAG
     244             :     string
     245             :     name() const;
     246             : 
     247             :     /**
     248             :      *  @brief  Locale equality.
     249             :      *
     250             :      *  @param  __other  The locale to compare against.
     251             :      *  @return  True if other and this refer to the same locale instance, are
     252             :      *           copies, or have the same name.  False otherwise.
     253             :     */
     254             :     bool
     255             :     operator==(const locale& __other) const throw();
     256             : 
     257             : #if __cpp_impl_three_way_comparison < 201907L
     258             :     /**
     259             :      *  @brief  Locale inequality.
     260             :      *
     261             :      *  @param  __other  The locale to compare against.
     262             :      *  @return  ! (*this == __other)
     263             :     */
     264             :     bool
     265           0 :     operator!=(const locale& __other) const throw()
     266           0 :     { return !(this->operator==(__other)); }
     267             : #endif
     268             : 
     269             :     /**
     270             :      *  @brief  Compare two strings according to collate.
     271             :      *
     272             :      *  Template operator to compare two strings using the compare function of
     273             :      *  the collate facet in this locale.  One use is to provide the locale to
     274             :      *  the sort function.  For example, a vector v of strings could be sorted
     275             :      *  according to locale loc by doing:
     276             :      *  @code
     277             :      *  std::sort(v.begin(), v.end(), loc);
     278             :      *  @endcode
     279             :      *
     280             :      *  @param  __s1  First string to compare.
     281             :      *  @param  __s2  Second string to compare.
     282             :      *  @return  True if collate<_Char> facet compares __s1 < __s2, else false.
     283             :     */
     284             :     template<typename _Char, typename _Traits, typename _Alloc>
     285             :       bool
     286             :       operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
     287             :                  const basic_string<_Char, _Traits, _Alloc>& __s2) const;
     288             : 
     289             :     // Global locale objects:
     290             :     /**
     291             :      *  @brief  Set global locale
     292             :      *
     293             :      *  This function sets the global locale to the argument and returns a
     294             :      *  copy of the previous global locale.  If the argument has a name, it
     295             :      *  will also call std::setlocale(LC_ALL, loc.name()).
     296             :      *
     297             :      *  @param  __loc  The new locale to make global.
     298             :      *  @return  Copy of the old global locale.
     299             :     */
     300             :     static locale
     301             :     global(const locale& __loc);
     302             : 
     303             :     /**
     304             :      *  @brief  Return reference to the C locale.
     305             :     */
     306             :     static const locale&
     307             :     classic();
     308             : 
     309             :   private:
     310             :     // The (shared) implementation
     311             :     _Impl*              _M_impl;
     312             : 
     313             :     // The "C" reference locale
     314             :     static _Impl*       _S_classic;
     315             : 
     316             :     // Current global locale
     317             :     static _Impl*       _S_global;
     318             : 
     319             :     // Names of underlying locale categories.
     320             :     // NB: locale::global() has to know how to modify all the
     321             :     // underlying categories, not just the ones required by the C++
     322             :     // standard.
     323             :     static const char* const* const _S_categories;
     324             : 
     325             :     // Number of standard categories. For C++, these categories are
     326             :     // collate, ctype, monetary, numeric, time, and messages. These
     327             :     // directly correspond to ISO C99 macros LC_COLLATE, LC_CTYPE,
     328             :     // LC_MONETARY, LC_NUMERIC, and LC_TIME. In addition, POSIX (IEEE
     329             :     // 1003.1-2001) specifies LC_MESSAGES.
     330             :     // In addition to the standard categories, the underlying
     331             :     // operating system is allowed to define extra LC_*
     332             :     // macros. For GNU systems, the following are also valid:
     333             :     // LC_PAPER, LC_NAME, LC_ADDRESS, LC_TELEPHONE, LC_MEASUREMENT,
     334             :     // and LC_IDENTIFICATION.
     335             :     enum { _S_categories_size = 6 + _GLIBCXX_NUM_CATEGORIES };
     336             : 
     337             : #ifdef __GTHREADS
     338             :     static __gthread_once_t _S_once;
     339             : #endif
     340             : 
     341             :     explicit
     342             :     locale(_Impl*) throw();
     343             : 
     344             :     static void
     345             :     _S_initialize();
     346             : 
     347             :     static void
     348             :     _S_initialize_once() throw();
     349             : 
     350             :     static category
     351             :     _S_normalize_category(category);
     352             : 
     353             :     void
     354             :     _M_coalesce(const locale& __base, const locale& __add, category __cat);
     355             : 
     356             : #if _GLIBCXX_USE_CXX11_ABI
     357             :     static const id* const _S_twinned_facets[];
     358             : #endif
     359             :   };
     360             : 
     361             : 
     362             :   // 22.1.1.1.2  Class locale::facet
     363             :   /**
     364             :    *  @brief  Localization functionality base class.
     365             :    *  @ingroup locales
     366             :    *
     367             :    *  The facet class is the base class for a localization feature, such as
     368             :    *  money, time, and number printing.  It provides common support for facets
     369             :    *  and reference management.
     370             :    *
     371             :    *  Facets may not be copied or assigned.
     372             :   */
     373             :   class locale::facet
     374             :   {
     375             :   private:
     376             :     friend class locale;
     377             :     friend class locale::_Impl;
     378             : 
     379             :     mutable _Atomic_word                _M_refcount;
     380             : 
     381             :     // Contains data from the underlying "C" library for the classic locale.
     382             :     static __c_locale                   _S_c_locale;
     383             : 
     384             :     // String literal for the name of the classic locale.
     385             :     static const char                   _S_c_name[2];
     386             : 
     387             : #ifdef __GTHREADS
     388             :     static __gthread_once_t             _S_once;
     389             : #endif
     390             : 
     391             :     static void
     392             :     _S_initialize_once();
     393             : 
     394             :   protected:
     395             :     /**
     396             :      *  @brief  Facet constructor.
     397             :      *
     398             :      *  This is the constructor provided by the standard.  If refs is 0, the
     399             :      *  facet is destroyed when the last referencing locale is destroyed.
     400             :      *  Otherwise the facet will never be destroyed.
     401             :      *
     402             :      *  @param __refs  The initial value for reference count.
     403             :     */
     404             :     explicit
     405           0 :     facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0)
     406           0 :     { }
     407             : 
     408             :     /// Facet destructor.
     409             :     virtual
     410             :     ~facet();
     411             : 
     412             :     static void
     413             :     _S_create_c_locale(__c_locale& __cloc, const char* __s,
     414             :                        __c_locale __old = 0);
     415             : 
     416             :     static __c_locale
     417             :     _S_clone_c_locale(__c_locale& __cloc) throw();
     418             : 
     419             :     static void
     420             :     _S_destroy_c_locale(__c_locale& __cloc);
     421             : 
     422             :     static __c_locale
     423             :     _S_lc_ctype_c_locale(__c_locale __cloc, const char* __s);
     424             : 
     425             :     // Returns data from the underlying "C" library data for the
     426             :     // classic locale.
     427             :     static __c_locale
     428             :     _S_get_c_locale();
     429             : 
     430             :     _GLIBCXX_CONST static const char*
     431             :     _S_get_c_name() throw();
     432             : 
     433             : #if __cplusplus < 201103L
     434             :   private:
     435             :     facet(const facet&);  // Not defined.
     436             : 
     437             :     facet&
     438             :     operator=(const facet&);  // Not defined.
     439             : #else
     440             :     facet(const facet&) = delete;
     441             : 
     442             :     facet&
     443             :     operator=(const facet&) = delete;
     444             : #endif
     445             : 
     446             :   private:
     447             :     void
     448             :     _M_add_reference() const throw()
     449             :     { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
     450             : 
     451             :     void
     452             :     _M_remove_reference() const throw()
     453             :     {
     454             :       // Be race-detector-friendly.  For more info see bits/c++config.
     455             :       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
     456             :       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
     457             :         {
     458             :           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
     459             :           __try
     460             :             { delete this; }
     461             :           __catch(...)
     462             :             { }
     463             :         }
     464             :     }
     465             : 
     466             :     const facet* _M_sso_shim(const id*) const;
     467             :     const facet* _M_cow_shim(const id*) const;
     468             : 
     469             :   protected:
     470             :     class __shim; // For internal use only.
     471             :   };
     472             : 
     473             : 
     474             :   // 22.1.1.1.3 Class locale::id
     475             :   /**
     476             :    *  @brief  Facet ID class.
     477             :    *  @ingroup locales
     478             :    *
     479             :    *  The ID class provides facets with an index used to identify them.
     480             :    *  Every facet class must define a public static member locale::id, or be
     481             :    *  derived from a facet that provides this member, otherwise the facet
     482             :    *  cannot be used in a locale.  The locale::id ensures that each class
     483             :    *  type gets a unique identifier.
     484             :   */
     485             :   class locale::id
     486             :   {
     487             :   private:
     488             :     friend class locale;
     489             :     friend class locale::_Impl;
     490             : 
     491             :     template<typename _Facet>
     492             :       friend const _Facet&
     493             :       use_facet(const locale&);
     494             : 
     495             :     template<typename _Facet>
     496             :       friend bool
     497             :       has_facet(const locale&) throw();
     498             : 
     499             :     // NB: There is no accessor for _M_index because it may be used
     500             :     // before the constructor is run; the effect of calling a member
     501             :     // function (even an inline) would be undefined.
     502             :     mutable size_t              _M_index;
     503             : 
     504             :     // Last id number assigned.
     505             :     static _Atomic_word         _S_refcount;
     506             : 
     507             :     void
     508             :     operator=(const id&);  // Not defined.
     509             : 
     510             :     id(const id&);  // Not defined.
     511             : 
     512             :   public:
     513             :     // NB: This class is always a static data member, and thus can be
     514             :     // counted on to be zero-initialized.
     515             :     /// Constructor.
     516           1 :     id() { }
     517             : 
     518             :     size_t
     519             :     _M_id() const throw();
     520             :   };
     521             : 
     522             : 
     523             :   // Implementation object for locale.
     524             :   class locale::_Impl
     525             :   {
     526             :   public:
     527             :     // Friends.
     528             :     friend class locale;
     529             :     friend class locale::facet;
     530             : 
     531             :     template<typename _Facet>
     532             :       friend bool
     533             :       has_facet(const locale&) throw();
     534             : 
     535             :     template<typename _Facet>
     536             :       friend const _Facet&
     537             :       use_facet(const locale&);
     538             : 
     539             :     template<typename _Cache>
     540             :       friend struct __use_cache;
     541             : 
     542             :   private:
     543             :     // Data Members.
     544             :     _Atomic_word                        _M_refcount;
     545             :     const facet**                       _M_facets;
     546             :     size_t                              _M_facets_size;
     547             :     const facet**                       _M_caches;
     548             :     char**                              _M_names;
     549             :     static const locale::id* const      _S_id_ctype[];
     550             :     static const locale::id* const      _S_id_numeric[];
     551             :     static const locale::id* const      _S_id_collate[];
     552             :     static const locale::id* const      _S_id_time[];
     553             :     static const locale::id* const      _S_id_monetary[];
     554             :     static const locale::id* const      _S_id_messages[];
     555             :     static const locale::id* const* const _S_facet_categories[];
     556             : 
     557             :     void
     558             :     _M_add_reference() throw()
     559             :     { __gnu_cxx::__atomic_add_dispatch(&_M_refcount, 1); }
     560             : 
     561             :     void
     562             :     _M_remove_reference() throw()
     563             :     {
     564             :       // Be race-detector-friendly.  For more info see bits/c++config.
     565             :       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
     566             :       if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
     567             :         {
     568             :           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
     569             :           __try
     570             :             { delete this; }
     571             :           __catch(...)
     572             :             { }
     573             :         }
     574             :     }
     575             : 
     576             :     _Impl(const _Impl&, size_t);
     577             :     _Impl(const char*, size_t);
     578             :     _Impl(size_t) throw();
     579             : 
     580             :    ~_Impl() throw();
     581             : 
     582             :     _Impl(const _Impl&);  // Not defined.
     583             : 
     584             :     void
     585             :     operator=(const _Impl&);  // Not defined.
     586             : 
     587             :     bool
     588             :     _M_check_same_name()
     589             :     {
     590             :       bool __ret = true;
     591             :       if (_M_names[1])
     592             :         // We must actually compare all the _M_names: can be all equal!
     593             :         for (size_t __i = 0; __ret && __i < _S_categories_size - 1; ++__i)
     594             :           __ret = __builtin_strcmp(_M_names[__i], _M_names[__i + 1]) == 0;
     595             :       return __ret;
     596             :     }
     597             : 
     598             :     void
     599             :     _M_replace_categories(const _Impl*, category);
     600             : 
     601             :     void
     602             :     _M_replace_category(const _Impl*, const locale::id* const*);
     603             : 
     604             :     void
     605             :     _M_replace_facet(const _Impl*, const locale::id*);
     606             : 
     607             :     void
     608             :     _M_install_facet(const locale::id*, const facet*);
     609             : 
     610             :     template<typename _Facet>
     611             :       void
     612             :       _M_init_facet(_Facet* __facet)
     613             :       { _M_install_facet(&_Facet::id, __facet); }
     614             : 
     615             :     template<typename _Facet>
     616             :       void
     617             :       _M_init_facet_unchecked(_Facet* __facet)
     618             :       {
     619             :         __facet->_M_add_reference();
     620             :         _M_facets[_Facet::id._M_id()] = __facet;
     621             :       }
     622             : 
     623             :     void
     624             :     _M_install_cache(const facet*, size_t);
     625             : 
     626             :     void _M_init_extra(facet**);
     627             :     void _M_init_extra(void*, void*, const char*, const char*);
     628             : 
     629             : #ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
     630             :     void _M_init_extra_ldbl128(bool);
     631             : #endif
     632             :   };
     633             : 
     634             : 
     635             :   /**
     636             :    *  @brief  Facet for localized string comparison.
     637             :    *
     638             :    *  This facet encapsulates the code to compare strings in a localized
     639             :    *  manner.
     640             :    *
     641             :    *  The collate template uses protected virtual functions to provide
     642             :    *  the actual results.  The public accessors forward the call to
     643             :    *  the virtual functions.  These virtual functions are hooks for
     644             :    *  developers to implement the behavior they require from the
     645             :    *  collate facet.
     646             :   */
     647             :   template<typename _CharT>
     648             :     class _GLIBCXX_NAMESPACE_CXX11 collate : public locale::facet
     649             :     {
     650             :     public:
     651             :       // Types:
     652             :       ///@{
     653             :       /// Public typedefs
     654             :       typedef _CharT                    char_type;
     655             :       typedef basic_string<_CharT>        string_type;
     656             :       ///@}
     657             : 
     658             :     protected:
     659             :       // Underlying "C" library locale information saved from
     660             :       // initialization, needed by collate_byname as well.
     661             :       __c_locale                        _M_c_locale_collate;
     662             : 
     663             :     public:
     664             :       /// Numpunct facet id.
     665             :       static locale::id                 id;
     666             : 
     667             :       /**
     668             :        *  @brief  Constructor performs initialization.
     669             :        *
     670             :        *  This is the constructor provided by the standard.
     671             :        *
     672             :        *  @param __refs  Passed to the base facet class.
     673             :       */
     674             :       explicit
     675             :       collate(size_t __refs = 0)
     676             :       : facet(__refs), _M_c_locale_collate(_S_get_c_locale())
     677             :       { }
     678             : 
     679             :       /**
     680             :        *  @brief  Internal constructor. Not for general use.
     681             :        *
     682             :        *  This is a constructor for use by the library itself to set up new
     683             :        *  locales.
     684             :        *
     685             :        *  @param __cloc  The C locale.
     686             :        *  @param __refs  Passed to the base facet class.
     687             :       */
     688             :       explicit
     689             :       collate(__c_locale __cloc, size_t __refs = 0)
     690             :       : facet(__refs), _M_c_locale_collate(_S_clone_c_locale(__cloc))
     691             :       { }
     692             : 
     693             :       /**
     694             :        *  @brief  Compare two strings.
     695             :        *
     696             :        *  This function compares two strings and returns the result by calling
     697             :        *  collate::do_compare().
     698             :        *
     699             :        *  @param __lo1  Start of string 1.
     700             :        *  @param __hi1  End of string 1.
     701             :        *  @param __lo2  Start of string 2.
     702             :        *  @param __hi2  End of string 2.
     703             :        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
     704             :       */
     705             :       int
     706             :       compare(const _CharT* __lo1, const _CharT* __hi1,
     707             :               const _CharT* __lo2, const _CharT* __hi2) const
     708             :       { return this->do_compare(__lo1, __hi1, __lo2, __hi2); }
     709             : 
     710             :       /**
     711             :        *  @brief  Transform string to comparable form.
     712             :        *
     713             :        *  This function is a wrapper for strxfrm functionality.  It takes the
     714             :        *  input string and returns a modified string that can be directly
     715             :        *  compared to other transformed strings.  In the C locale, this
     716             :        *  function just returns a copy of the input string.  In some other
     717             :        *  locales, it may replace two chars with one, change a char for
     718             :        *  another, etc.  It does so by returning collate::do_transform().
     719             :        *
     720             :        *  @param __lo  Start of string.
     721             :        *  @param __hi  End of string.
     722             :        *  @return  Transformed string_type.
     723             :       */
     724             :       string_type
     725             :       transform(const _CharT* __lo, const _CharT* __hi) const
     726             :       { return this->do_transform(__lo, __hi); }
     727             : 
     728             :       /**
     729             :        *  @brief  Return hash of a string.
     730             :        *
     731             :        *  This function computes and returns a hash on the input string.  It
     732             :        *  does so by returning collate::do_hash().
     733             :        *
     734             :        *  @param __lo  Start of string.
     735             :        *  @param __hi  End of string.
     736             :        *  @return  Hash value.
     737             :       */
     738             :       long
     739             :       hash(const _CharT* __lo, const _CharT* __hi) const
     740             :       { return this->do_hash(__lo, __hi); }
     741             : 
     742             :       // Used to abstract out _CharT bits in virtual member functions, below.
     743             :       int
     744             :       _M_compare(const _CharT*, const _CharT*) const throw();
     745             : 
     746             :       size_t
     747             :       _M_transform(_CharT*, const _CharT*, size_t) const throw();
     748             : 
     749             :   protected:
     750             :       /// Destructor.
     751             :       virtual
     752             :       ~collate()
     753             :       { _S_destroy_c_locale(_M_c_locale_collate); }
     754             : 
     755             :       /**
     756             :        *  @brief  Compare two strings.
     757             :        *
     758             :        *  This function is a hook for derived classes to change the value
     759             :        *  returned.  @see compare().
     760             :        *
     761             :        *  @param __lo1  Start of string 1.
     762             :        *  @param __hi1  End of string 1.
     763             :        *  @param __lo2  Start of string 2.
     764             :        *  @param __hi2  End of string 2.
     765             :        *  @return  1 if string1 > string2, -1 if string1 < string2, else 0.
     766             :       */
     767             :       virtual int
     768             :       do_compare(const _CharT* __lo1, const _CharT* __hi1,
     769             :                  const _CharT* __lo2, const _CharT* __hi2) const;
     770             : 
     771             :       /**
     772             :        *  @brief  Transform string to comparable form.
     773             :        *
     774             :        *  This function is a hook for derived classes to change the value
     775             :        *  returned.
     776             :        *
     777             :        *  @param __lo  Start.
     778             :        *  @param __hi  End.
     779             :        *  @return  transformed string.
     780             :       */
     781             :       virtual string_type
     782             :       do_transform(const _CharT* __lo, const _CharT* __hi) const;
     783             : 
     784             :       /**
     785             :        *  @brief  Return hash of a string.
     786             :        *
     787             :        *  This function computes and returns a hash on the input string.  This
     788             :        *  function is a hook for derived classes to change the value returned.
     789             :        *
     790             :        *  @param __lo  Start of string.
     791             :        *  @param __hi  End of string.
     792             :        *  @return  Hash value.
     793             :       */
     794             :       virtual long
     795             :       do_hash(const _CharT* __lo, const _CharT* __hi) const;
     796             :     };
     797             : 
     798             :   template<typename _CharT>
     799             :     locale::id collate<_CharT>::id;
     800             : 
     801             :   // Specializations.
     802             :   template<>
     803             :     int
     804             :     collate<char>::_M_compare(const char*, const char*) const throw();
     805             : 
     806             :   template<>
     807             :     size_t
     808             :     collate<char>::_M_transform(char*, const char*, size_t) const throw();
     809             : 
     810             : #ifdef _GLIBCXX_USE_WCHAR_T
     811             :   template<>
     812             :     int
     813             :     collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const throw();
     814             : 
     815             :   template<>
     816             :     size_t
     817             :     collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const throw();
     818             : #endif
     819             : 
     820             :   /// class collate_byname [22.2.4.2].
     821             :   template<typename _CharT>
     822             :     class _GLIBCXX_NAMESPACE_CXX11 collate_byname : public collate<_CharT>
     823             :     {
     824             :     public:
     825             :       ///@{
     826             :       /// Public typedefs
     827             :       typedef _CharT               char_type;
     828             :       typedef basic_string<_CharT> string_type;
     829             :       ///@}
     830             : 
     831             :       explicit
     832             :       collate_byname(const char* __s, size_t __refs = 0)
     833             :       : collate<_CharT>(__refs)
     834             :       {
     835             :         if (__builtin_strcmp(__s, "C") != 0
     836             :             && __builtin_strcmp(__s, "POSIX") != 0)
     837             :           {
     838             :             this->_S_destroy_c_locale(this->_M_c_locale_collate);
     839             :             this->_S_create_c_locale(this->_M_c_locale_collate, __s);
     840             :           }
     841             :       }
     842             : 
     843             : #if __cplusplus >= 201103L
     844             :       explicit
     845             :       collate_byname(const string& __s, size_t __refs = 0)
     846             :       : collate_byname(__s.c_str(), __refs) { }
     847             : #endif
     848             : 
     849             :     protected:
     850             :       virtual
     851             :       ~collate_byname() { }
     852             :     };
     853             : 
     854             : _GLIBCXX_END_NAMESPACE_VERSION
     855             : } // namespace
     856             : 
     857             : # include <bits/locale_classes.tcc>
     858             : 
     859             : #endif

Generated by: LCOV version 1.14