LCOV - code coverage report
Current view: top level - usr/include/c++/12/bits - char_traits.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 5 9 55.6 %
Date: 2023-07-19 08:18:47 Functions: 0 0 -

          Line data    Source code
       1             : // Character Traits for use by standard string and iostream -*- C++ -*-
       2             : 
       3             : // Copyright (C) 1997-2022 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/char_traits.h
      26             :  *  This is an internal header file, included by other library headers.
      27             :  *  Do not attempt to use it directly. @headername{string}
      28             :  */
      29             : 
      30             : //
      31             : // ISO C++ 14882: 21  Strings library
      32             : //
      33             : 
      34             : #ifndef _CHAR_TRAITS_H
      35             : #define _CHAR_TRAITS_H 1
      36             : 
      37             : #pragma GCC system_header
      38             : 
      39             : #include <bits/postypes.h>      // For streampos
      40             : #include <cwchar>               // For WEOF, wmemmove, wmemset, etc.
      41             : #if __cplusplus >= 201103L
      42             : # include <type_traits>
      43             : #endif
      44             : #if __cplusplus >= 202002L
      45             : # include <compare>
      46             : # include <bits/stl_construct.h>
      47             : #endif
      48             : 
      49             : #ifndef _GLIBCXX_ALWAYS_INLINE
      50             : # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
      51             : #endif
      52             : 
      53             : namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
      54             : {
      55             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      56             : 
      57             : #pragma GCC diagnostic push
      58             : #pragma GCC diagnostic ignored "-Wstringop-overflow"
      59             : #pragma GCC diagnostic ignored "-Wstringop-overread"
      60             : #pragma GCC diagnostic ignored "-Warray-bounds"
      61             : 
      62             :   /**
      63             :    *  @brief  Mapping from character type to associated types.
      64             :    *
      65             :    *  @note This is an implementation class for the generic version
      66             :    *  of char_traits.  It defines int_type, off_type, pos_type, and
      67             :    *  state_type.  By default these are unsigned long, streamoff,
      68             :    *  streampos, and mbstate_t.  Users who need a different set of
      69             :    *  types, but who don't need to change the definitions of any function
      70             :    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
      71             :    *  while leaving __gnu_cxx::char_traits alone. */
      72             :   template<typename _CharT>
      73             :     struct _Char_types
      74             :     {
      75             :       typedef unsigned long   int_type;
      76             :       typedef std::streampos  pos_type;
      77             :       typedef std::streamoff  off_type;
      78             :       typedef std::mbstate_t  state_type;
      79             :     };
      80             : 
      81             : 
      82             :   /**
      83             :    *  @brief  Base class used to implement std::char_traits.
      84             :    *
      85             :    *  @note For any given actual character type, this definition is
      86             :    *  probably wrong.  (Most of the member functions are likely to be
      87             :    *  right, but the int_type and state_type typedefs, and the eof()
      88             :    *  member function, are likely to be wrong.)  The reason this class
      89             :    *  exists is so users can specialize it.  Classes in namespace std
      90             :    *  may not be specialized for fundamental types, but classes in
      91             :    *  namespace __gnu_cxx may be.
      92             :    *
      93             :    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
      94             :    *  for advice on how to make use of this class for @a unusual character
      95             :    *  types. Also, check out include/ext/pod_char_traits.h.  
      96             :    */
      97             :   template<typename _CharT>
      98             :     struct char_traits
      99             :     {
     100             :       typedef _CharT                                    char_type;
     101             :       typedef typename _Char_types<_CharT>::int_type    int_type;
     102             :       typedef typename _Char_types<_CharT>::pos_type    pos_type;
     103             :       typedef typename _Char_types<_CharT>::off_type    off_type;
     104             :       typedef typename _Char_types<_CharT>::state_type  state_type;
     105             : #if __cpp_lib_three_way_comparison
     106             :       using comparison_category = std::strong_ordering;
     107             : #endif
     108             : 
     109             :       static _GLIBCXX14_CONSTEXPR void
     110             :       assign(char_type& __c1, const char_type& __c2)
     111             :       {
     112             : #if __cpp_constexpr_dynamic_alloc
     113             :         if (std::__is_constant_evaluated())
     114             :           std::construct_at(__builtin_addressof(__c1), __c2);
     115             :         else
     116             : #endif
     117             :         __c1 = __c2;
     118             :       }
     119             : 
     120             :       static _GLIBCXX_CONSTEXPR bool
     121             :       eq(const char_type& __c1, const char_type& __c2)
     122             :       { return __c1 == __c2; }
     123             : 
     124             :       static _GLIBCXX_CONSTEXPR bool
     125             :       lt(const char_type& __c1, const char_type& __c2)
     126             :       { return __c1 < __c2; }
     127             : 
     128             :       static _GLIBCXX14_CONSTEXPR int
     129             :       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
     130             : 
     131             :       static _GLIBCXX14_CONSTEXPR std::size_t
     132             :       length(const char_type* __s);
     133             : 
     134             :       static _GLIBCXX14_CONSTEXPR const char_type*
     135             :       find(const char_type* __s, std::size_t __n, const char_type& __a);
     136             : 
     137             :       static _GLIBCXX20_CONSTEXPR char_type*
     138             :       move(char_type* __s1, const char_type* __s2, std::size_t __n);
     139             : 
     140             :       static _GLIBCXX20_CONSTEXPR char_type*
     141             :       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
     142             : 
     143             :       static _GLIBCXX20_CONSTEXPR char_type*
     144             :       assign(char_type* __s, std::size_t __n, char_type __a);
     145             : 
     146             :       static _GLIBCXX_CONSTEXPR char_type
     147             :       to_char_type(const int_type& __c)
     148             :       { return static_cast<char_type>(__c); }
     149             : 
     150             :       static _GLIBCXX_CONSTEXPR int_type
     151             :       to_int_type(const char_type& __c)
     152             :       { return static_cast<int_type>(__c); }
     153             : 
     154             :       static _GLIBCXX_CONSTEXPR bool
     155             :       eq_int_type(const int_type& __c1, const int_type& __c2)
     156             :       { return __c1 == __c2; }
     157             : 
     158             :       static _GLIBCXX_CONSTEXPR int_type
     159             :       eof()
     160             :       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
     161             : 
     162             :       static _GLIBCXX_CONSTEXPR int_type
     163             :       not_eof(const int_type& __c)
     164             :       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
     165             :     };
     166             : 
     167             :   template<typename _CharT>
     168             :     _GLIBCXX14_CONSTEXPR int
     169             :     char_traits<_CharT>::
     170             :     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
     171             :     {
     172             :       for (std::size_t __i = 0; __i < __n; ++__i)
     173             :         if (lt(__s1[__i], __s2[__i]))
     174             :           return -1;
     175             :         else if (lt(__s2[__i], __s1[__i]))
     176             :           return 1;
     177             :       return 0;
     178             :     }
     179             : 
     180             :   template<typename _CharT>
     181             :     _GLIBCXX14_CONSTEXPR std::size_t
     182             :     char_traits<_CharT>::
     183             :     length(const char_type* __p)
     184             :     {
     185             :       std::size_t __i = 0;
     186             :       while (!eq(__p[__i], char_type()))
     187             :         ++__i;
     188             :       return __i;
     189             :     }
     190             : 
     191             :   template<typename _CharT>
     192             :     _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
     193             :     char_traits<_CharT>::
     194             :     find(const char_type* __s, std::size_t __n, const char_type& __a)
     195             :     {
     196             :       for (std::size_t __i = 0; __i < __n; ++__i)
     197             :         if (eq(__s[__i], __a))
     198             :           return __s + __i;
     199             :       return 0;
     200             :     }
     201             : 
     202             :   template<typename _CharT>
     203             :     _GLIBCXX20_CONSTEXPR
     204             :     typename char_traits<_CharT>::char_type*
     205             :     char_traits<_CharT>::
     206             :     move(char_type* __s1, const char_type* __s2, std::size_t __n)
     207             :     {
     208             :       if (__n == 0)
     209             :         return __s1;
     210             : #if __cplusplus >= 202002L
     211             :       if (std::__is_constant_evaluated())
     212             :         {
     213             :           if (__s1 == __s2) // unlikely, but saves a lot of work
     214             :             return __s1;
     215             : #if __cpp_constexpr_dynamic_alloc
     216             :           // The overlap detection below fails due to PR c++/89074,
     217             :           // so use a temporary buffer instead.
     218             :           char_type* __tmp = new char_type[__n];
     219             :           copy(__tmp, __s2, __n);
     220             :           copy(__s1, __tmp, __n);
     221             :           delete[] __tmp;
     222             : #else
     223             :           const auto __end = __s2 + __n - 1;
     224             :           bool __overlap = false;
     225             :           for (std::size_t __i = 0; __i < __n - 1; ++__i)
     226             :             {
     227             :               if (__s1 + __i == __end)
     228             :                 {
     229             :                   __overlap = true;
     230             :                   break;
     231             :                 }
     232             :             }
     233             :           if (__overlap)
     234             :             {
     235             :               do
     236             :                 {
     237             :                   --__n;
     238             :                   assign(__s1[__n], __s2[__n]);
     239             :                 }
     240             :               while (__n > 0);
     241             :             }
     242             :           else
     243             :             copy(__s1, __s2, __n);
     244             : #endif
     245             :           return __s1;
     246             :         }
     247             : #endif
     248             :       __builtin_memmove(__s1, __s2, __n * sizeof(char_type));
     249             :       return __s1;
     250             :     }
     251             : 
     252             :   template<typename _CharT>
     253             :     _GLIBCXX20_CONSTEXPR
     254             :     typename char_traits<_CharT>::char_type*
     255             :     char_traits<_CharT>::
     256             :     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
     257             :     {
     258             :       if (__n == 0)
     259             :         return __s1;
     260             : #if __cplusplus >= 202002L
     261             :       if (std::__is_constant_evaluated())
     262             :         {
     263             :           for (std::size_t __i = 0; __i < __n; ++__i)
     264             :             std::construct_at(__s1 + __i, __s2[__i]);
     265             :           return __s1;
     266             :         }
     267             : #endif
     268             :       __builtin_memcpy(__s1, __s2, __n * sizeof(char_type));
     269             :       return __s1;
     270             :     }
     271             : 
     272             :   template<typename _CharT>
     273             :     _GLIBCXX20_CONSTEXPR
     274             :     typename char_traits<_CharT>::char_type*
     275             :     char_traits<_CharT>::
     276             :     assign(char_type* __s, std::size_t __n, char_type __a)
     277             :     {
     278             : #if __cplusplus >= 202002L
     279             :       if (std::__is_constant_evaluated())
     280             :         {
     281             :           for (std::size_t __i = 0; __i < __n; ++__i)
     282             :             std::construct_at(__s + __i, __a);
     283             :           return __s;
     284             :         }
     285             : #endif
     286             : 
     287             :       if _GLIBCXX17_CONSTEXPR (sizeof(_CharT) == 1 && __is_trivial(_CharT))
     288             :         {
     289             :           if (__n)
     290             :             {
     291             :               unsigned char __c;
     292             :               __builtin_memcpy(&__c, __builtin_addressof(__a), 1);
     293             :               __builtin_memset(__s, __c, __n);
     294             :             }
     295             :         }
     296             :       else
     297             :         {
     298             :           for (std::size_t __i = 0; __i < __n; ++__i)
     299             :             __s[__i] = __a;
     300             :         }
     301             :       return __s;
     302             :     }
     303             : 
     304             : _GLIBCXX_END_NAMESPACE_VERSION
     305             : } // namespace
     306             : 
     307             : namespace std _GLIBCXX_VISIBILITY(default)
     308             : {
     309             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
     310             : 
     311             : #ifdef __cpp_lib_is_constant_evaluated
     312             : // Unofficial macro indicating P1032R1 support in C++20
     313             : # define __cpp_lib_constexpr_char_traits 201811L
     314             : #elif __cplusplus >= 201703L && _GLIBCXX_HAVE_IS_CONSTANT_EVALUATED
     315             : // Unofficial macro indicating P0426R1 support in C++17
     316             : # define __cpp_lib_constexpr_char_traits 201611L
     317             : #endif
     318             : 
     319             :   // 21.1
     320             :   /**
     321             :    *  @brief  Basis for explicit traits specializations.
     322             :    *
     323             :    *  @note  For any given actual character type, this definition is
     324             :    *  probably wrong.  Since this is just a thin wrapper around
     325             :    *  __gnu_cxx::char_traits, it is possible to achieve a more
     326             :    *  appropriate definition by specializing __gnu_cxx::char_traits.
     327             :    *
     328             :    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
     329             :    *  for advice on how to make use of this class for @a unusual character
     330             :    *  types. Also, check out include/ext/pod_char_traits.h.
     331             :   */
     332             :   template<typename _CharT>
     333             :     struct char_traits : public __gnu_cxx::char_traits<_CharT>
     334             :     { };
     335             : 
     336             : 
     337             :   /// 21.1.3.1  char_traits specializations
     338             :   template<>
     339             :     struct char_traits<char>
     340             :     {
     341             :       typedef char              char_type;
     342             :       typedef int               int_type;
     343             :       typedef streampos         pos_type;
     344             :       typedef streamoff         off_type;
     345             :       typedef mbstate_t         state_type;
     346             : #if __cpp_lib_three_way_comparison
     347             :       using comparison_category = strong_ordering;
     348             : #endif
     349             : 
     350             :       static _GLIBCXX17_CONSTEXPR void
     351       82511 :       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     352             :       {
     353             : #if __cpp_constexpr_dynamic_alloc
     354             :         if (std::__is_constant_evaluated())
     355             :           std::construct_at(__builtin_addressof(__c1), __c2);
     356             :         else
     357             : #endif
     358       24248 :         __c1 = __c2;
     359             :       }
     360             : 
     361             :       static _GLIBCXX_CONSTEXPR bool
     362             :       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     363             :       { return __c1 == __c2; }
     364             : 
     365             :       static _GLIBCXX_CONSTEXPR bool
     366             :       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     367             :       {
     368             :         // LWG 467.
     369             :         return (static_cast<unsigned char>(__c1)
     370             :                 < static_cast<unsigned char>(__c2));
     371             :       }
     372             : 
     373             :       static _GLIBCXX17_CONSTEXPR int
     374           0 :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     375             :       {
     376           0 :         if (__n == 0)
     377             :           return 0;
     378             : #if __cplusplus >= 201703L
     379           0 :         if (std::__is_constant_evaluated())
     380             :           {
     381             :             for (size_t __i = 0; __i < __n; ++__i)
     382             :               if (lt(__s1[__i], __s2[__i]))
     383             :                 return -1;
     384             :               else if (lt(__s2[__i], __s1[__i]))
     385             :                 return 1;
     386             :             return 0;
     387             :           }
     388             : #endif
     389           0 :         return __builtin_memcmp(__s1, __s2, __n);
     390             :       }
     391             : 
     392             :       static _GLIBCXX17_CONSTEXPR size_t
     393        5737 :       length(const char_type* __s)
     394             :       {
     395             : #if __cplusplus >= 201703L
     396        5737 :         if (std::__is_constant_evaluated())
     397             :           return __gnu_cxx::char_traits<char_type>::length(__s);
     398             : #endif
     399        5737 :         return __builtin_strlen(__s);
     400             :       }
     401             : 
     402             :       static _GLIBCXX17_CONSTEXPR const char_type*
     403             :       find(const char_type* __s, size_t __n, const char_type& __a)
     404             :       {
     405             :         if (__n == 0)
     406             :           return 0;
     407             : #if __cplusplus >= 201703L
     408             :         if (std::__is_constant_evaluated())
     409             :           return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
     410             : #endif
     411             :         return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
     412             :       }
     413             : 
     414             :       static _GLIBCXX20_CONSTEXPR char_type*
     415             :       move(char_type* __s1, const char_type* __s2, size_t __n)
     416             :       {
     417             :         if (__n == 0)
     418             :           return __s1;
     419             : #if __cplusplus >= 202002L
     420             :         if (std::__is_constant_evaluated())
     421             :           return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     422             : #endif
     423             :         return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
     424             :       }
     425             : 
     426             :       static _GLIBCXX20_CONSTEXPR char_type*
     427             :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     428             :       {
     429             :         if (__n == 0)
     430             :           return __s1;
     431             : #if __cplusplus >= 202002L
     432             :         if (std::__is_constant_evaluated())
     433             :           return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     434             : #endif
     435             :         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
     436             :       }
     437             : 
     438             :       static _GLIBCXX20_CONSTEXPR char_type*
     439             :       assign(char_type* __s, size_t __n, char_type __a)
     440             :       {
     441             :         if (__n == 0)
     442             :           return __s;
     443             : #if __cplusplus >= 202002L
     444             :         if (std::__is_constant_evaluated())
     445             :           return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
     446             : #endif
     447             :         return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
     448             :       }
     449             : 
     450             :       static _GLIBCXX_CONSTEXPR char_type
     451             :       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
     452             :       { return static_cast<char_type>(__c); }
     453             : 
     454             :       // To keep both the byte 0xff and the eof symbol 0xffffffff
     455             :       // from ending up as 0xffffffff.
     456             :       static _GLIBCXX_CONSTEXPR int_type
     457             :       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
     458             :       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
     459             : 
     460             :       static _GLIBCXX_CONSTEXPR bool
     461             :       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
     462             :       { return __c1 == __c2; }
     463             : 
     464             :       static _GLIBCXX_CONSTEXPR int_type
     465             :       eof() _GLIBCXX_NOEXCEPT
     466             :       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
     467             : 
     468             :       static _GLIBCXX_CONSTEXPR int_type
     469             :       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
     470             :       { return (__c == eof()) ? 0 : __c; }
     471             :   };
     472             : 
     473             : 
     474             : #ifdef _GLIBCXX_USE_WCHAR_T
     475             :   /// 21.1.3.2  char_traits specializations
     476             :   template<>
     477             :     struct char_traits<wchar_t>
     478             :     {
     479             :       typedef wchar_t           char_type;
     480             :       typedef wint_t            int_type;
     481             :       typedef streamoff         off_type;
     482             :       typedef wstreampos        pos_type;
     483             :       typedef mbstate_t         state_type;
     484             : #if __cpp_lib_three_way_comparison
     485             :       using comparison_category = strong_ordering;
     486             : #endif
     487             : 
     488             :       static _GLIBCXX17_CONSTEXPR void
     489             :       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     490             :       {
     491             : #if __cpp_constexpr_dynamic_alloc
     492             :         if (std::__is_constant_evaluated())
     493             :           std::construct_at(__builtin_addressof(__c1), __c2);
     494             :         else
     495             : #endif
     496             :         __c1 = __c2;
     497             :       }
     498             : 
     499             :       static _GLIBCXX_CONSTEXPR bool
     500             :       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     501             :       { return __c1 == __c2; }
     502             : 
     503             :       static _GLIBCXX_CONSTEXPR bool
     504             :       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     505             :       { return __c1 < __c2; }
     506             : 
     507             :       static _GLIBCXX17_CONSTEXPR int
     508             :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     509             :       {
     510             :         if (__n == 0)
     511             :           return 0;
     512             : #if __cplusplus >= 201703L
     513             :         if (std::__is_constant_evaluated())
     514             :           return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
     515             : #endif
     516             :         return wmemcmp(__s1, __s2, __n);
     517             :       }
     518             : 
     519             :       static _GLIBCXX17_CONSTEXPR size_t
     520             :       length(const char_type* __s)
     521             :       {
     522             : #if __cplusplus >= 201703L
     523             :         if (std::__is_constant_evaluated())
     524             :           return __gnu_cxx::char_traits<char_type>::length(__s);
     525             : #endif
     526             :         return wcslen(__s);
     527             :       }
     528             : 
     529             :       static _GLIBCXX17_CONSTEXPR const char_type*
     530             :       find(const char_type* __s, size_t __n, const char_type& __a)
     531             :       {
     532             :         if (__n == 0)
     533             :           return 0;
     534             : #if __cplusplus >= 201703L
     535             :         if (std::__is_constant_evaluated())
     536             :           return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
     537             : #endif
     538             :         return wmemchr(__s, __a, __n);
     539             :       }
     540             : 
     541             :       static _GLIBCXX20_CONSTEXPR char_type*
     542             :       move(char_type* __s1, const char_type* __s2, size_t __n)
     543             :       {
     544             :         if (__n == 0)
     545             :           return __s1;
     546             : #if __cplusplus >= 202002L
     547             :         if (std::__is_constant_evaluated())
     548             :           return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     549             : #endif
     550             :         return wmemmove(__s1, __s2, __n);
     551             :       }
     552             : 
     553             :       static _GLIBCXX20_CONSTEXPR char_type*
     554             :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     555             :       {
     556             :         if (__n == 0)
     557             :           return __s1;
     558             : #if __cplusplus >= 202002L
     559             :         if (std::__is_constant_evaluated())
     560             :           return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     561             : #endif
     562             :         return wmemcpy(__s1, __s2, __n);
     563             :       }
     564             : 
     565             :       static _GLIBCXX20_CONSTEXPR char_type*
     566             :       assign(char_type* __s, size_t __n, char_type __a)
     567             :       {
     568             :         if (__n == 0)
     569             :           return __s;
     570             : #if __cplusplus >= 202002L
     571             :         if (std::__is_constant_evaluated())
     572             :           return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
     573             : #endif
     574             :         return wmemset(__s, __a, __n);
     575             :       }
     576             : 
     577             :       static _GLIBCXX_CONSTEXPR char_type
     578             :       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
     579             :       { return char_type(__c); }
     580             : 
     581             :       static _GLIBCXX_CONSTEXPR int_type
     582             :       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
     583             :       { return int_type(__c); }
     584             : 
     585             :       static _GLIBCXX_CONSTEXPR bool
     586             :       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
     587             :       { return __c1 == __c2; }
     588             : 
     589             :       static _GLIBCXX_CONSTEXPR int_type
     590             :       eof() _GLIBCXX_NOEXCEPT
     591             :       { return static_cast<int_type>(WEOF); }
     592             : 
     593             :       static _GLIBCXX_CONSTEXPR int_type
     594             :       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
     595             :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     596             :   };
     597             : #else // _GLIBCXX_USE_WCHAR_T
     598             :   template<>
     599             :     struct char_traits<wchar_t> : public __gnu_cxx::char_traits<wchar_t>
     600             :     { };
     601             : #endif //_GLIBCXX_USE_WCHAR_T
     602             : 
     603             : #ifdef _GLIBCXX_USE_CHAR8_T
     604             :   template<>
     605             :     struct char_traits<char8_t>
     606             :     {
     607             :       typedef char8_t           char_type;
     608             :       typedef unsigned int      int_type;
     609             :       typedef u8streampos       pos_type;
     610             :       typedef streamoff         off_type;
     611             :       typedef mbstate_t         state_type;
     612             : #if __cpp_lib_three_way_comparison
     613             :       using comparison_category = strong_ordering;
     614             : #endif
     615             : 
     616             :       static _GLIBCXX17_CONSTEXPR void
     617             :       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     618             :       {
     619             : #if __cpp_constexpr_dynamic_alloc
     620             :         if (std::__is_constant_evaluated())
     621             :           std::construct_at(__builtin_addressof(__c1), __c2);
     622             :         else
     623             : #endif
     624             :         __c1 = __c2;
     625             :       }
     626             : 
     627             :       static _GLIBCXX_CONSTEXPR bool
     628             :       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     629             :       { return __c1 == __c2; }
     630             : 
     631             :       static _GLIBCXX_CONSTEXPR bool
     632             :       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     633             :       { return __c1 < __c2; }
     634             : 
     635             :       static _GLIBCXX17_CONSTEXPR int
     636             :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     637             :       {
     638             :         if (__n == 0)
     639             :           return 0;
     640             : #if __cplusplus >= 201703L
     641             :         if (std::__is_constant_evaluated())
     642             :           return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
     643             : #endif
     644             :         return __builtin_memcmp(__s1, __s2, __n);
     645             :       }
     646             : 
     647             :       static _GLIBCXX17_CONSTEXPR size_t
     648             :       length(const char_type* __s)
     649             :       {
     650             : #if __cplusplus >= 201703L
     651             :         if (std::__is_constant_evaluated())
     652             :           return __gnu_cxx::char_traits<char_type>::length(__s);
     653             : #endif
     654             :         size_t __i = 0;
     655             :         while (!eq(__s[__i], char_type()))
     656             :           ++__i;
     657             :         return __i;
     658             :       }
     659             : 
     660             :       static _GLIBCXX17_CONSTEXPR const char_type*
     661             :       find(const char_type* __s, size_t __n, const char_type& __a)
     662             :       {
     663             :         if (__n == 0)
     664             :           return 0;
     665             : #if __cplusplus >= 201703L
     666             :         if (std::__is_constant_evaluated())
     667             :           return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
     668             : #endif
     669             :         return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
     670             :       }
     671             : 
     672             :       static _GLIBCXX20_CONSTEXPR char_type*
     673             :       move(char_type* __s1, const char_type* __s2, size_t __n)
     674             :       {
     675             :         if (__n == 0)
     676             :           return __s1;
     677             : #if __cplusplus >= 202002L
     678             :         if (std::__is_constant_evaluated())
     679             :           return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     680             : #endif
     681             :         return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
     682             :       }
     683             : 
     684             :       static _GLIBCXX20_CONSTEXPR char_type*
     685             :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     686             :       {
     687             :         if (__n == 0)
     688             :           return __s1;
     689             : #if __cplusplus >= 202002L
     690             :         if (std::__is_constant_evaluated())
     691             :           return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     692             : #endif
     693             :         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
     694             :       }
     695             : 
     696             :       static _GLIBCXX20_CONSTEXPR char_type*
     697             :       assign(char_type* __s, size_t __n, char_type __a)
     698             :       {
     699             :         if (__n == 0)
     700             :           return __s;
     701             : #if __cplusplus >= 202002L
     702             :         if (std::__is_constant_evaluated())
     703             :           return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
     704             : #endif
     705             :         return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
     706             :       }
     707             : 
     708             :       static _GLIBCXX_CONSTEXPR char_type
     709             :       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
     710             :       { return char_type(__c); }
     711             : 
     712             :       static _GLIBCXX_CONSTEXPR int_type
     713             :       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
     714             :       { return int_type(__c); }
     715             : 
     716             :       static _GLIBCXX_CONSTEXPR bool
     717             :       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
     718             :       { return __c1 == __c2; }
     719             : 
     720             :       static _GLIBCXX_CONSTEXPR int_type
     721             :       eof() _GLIBCXX_NOEXCEPT
     722             :       { return static_cast<int_type>(-1); }
     723             : 
     724             :       static _GLIBCXX_CONSTEXPR int_type
     725             :       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
     726             :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     727             :     };
     728             : #endif //_GLIBCXX_USE_CHAR8_T
     729             : 
     730             : _GLIBCXX_END_NAMESPACE_VERSION
     731             : } // namespace
     732             : 
     733             : #if __cplusplus >= 201103L
     734             : 
     735             : #include <cstdint>
     736             : 
     737             : namespace std _GLIBCXX_VISIBILITY(default)
     738             : {
     739             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
     740             : 
     741             :   template<>
     742             :     struct char_traits<char16_t>
     743             :     {
     744             :       typedef char16_t          char_type;
     745             : #ifdef _GLIBCXX_USE_C99_STDINT_TR1
     746             :       typedef uint_least16_t    int_type;
     747             : #elif defined __UINT_LEAST16_TYPE__
     748             :       typedef __UINT_LEAST16_TYPE__         int_type;
     749             : #else
     750             :       typedef make_unsigned<char16_t>::type int_type;
     751             : #endif
     752             :       typedef streamoff         off_type;
     753             :       typedef u16streampos      pos_type;
     754             :       typedef mbstate_t         state_type;
     755             : #if __cpp_lib_three_way_comparison
     756             :       using comparison_category = strong_ordering;
     757             : #endif
     758             : 
     759             :       static _GLIBCXX17_CONSTEXPR void
     760             :       assign(char_type& __c1, const char_type& __c2) noexcept
     761             :       {
     762             : #if __cpp_constexpr_dynamic_alloc
     763             :         if (std::__is_constant_evaluated())
     764             :           std::construct_at(__builtin_addressof(__c1), __c2);
     765             :         else
     766             : #endif
     767             :         __c1 = __c2;
     768             :       }
     769             : 
     770             :       static constexpr bool
     771             :       eq(const char_type& __c1, const char_type& __c2) noexcept
     772             :       { return __c1 == __c2; }
     773             : 
     774             :       static constexpr bool
     775             :       lt(const char_type& __c1, const char_type& __c2) noexcept
     776             :       { return __c1 < __c2; }
     777             : 
     778             :       static _GLIBCXX17_CONSTEXPR int
     779             :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     780             :       {
     781             :         for (size_t __i = 0; __i < __n; ++__i)
     782             :           if (lt(__s1[__i], __s2[__i]))
     783             :             return -1;
     784             :           else if (lt(__s2[__i], __s1[__i]))
     785             :             return 1;
     786             :         return 0;
     787             :       }
     788             : 
     789             :       static _GLIBCXX17_CONSTEXPR size_t
     790             :       length(const char_type* __s)
     791             :       {
     792             :         size_t __i = 0;
     793             :         while (!eq(__s[__i], char_type()))
     794             :           ++__i;
     795             :         return __i;
     796             :       }
     797             : 
     798             :       static _GLIBCXX17_CONSTEXPR const char_type*
     799             :       find(const char_type* __s, size_t __n, const char_type& __a)
     800             :       {
     801             :         for (size_t __i = 0; __i < __n; ++__i)
     802             :           if (eq(__s[__i], __a))
     803             :             return __s + __i;
     804             :         return 0;
     805             :       }
     806             : 
     807             :       static _GLIBCXX20_CONSTEXPR char_type*
     808             :       move(char_type* __s1, const char_type* __s2, size_t __n)
     809             :       {
     810             :         if (__n == 0)
     811             :           return __s1;
     812             : #if __cplusplus >= 202002L
     813             :         if (std::__is_constant_evaluated())
     814             :           return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     815             : #endif
     816             :         return (static_cast<char_type*>
     817             :                 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
     818             :       }
     819             : 
     820             :       static _GLIBCXX20_CONSTEXPR char_type*
     821             :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     822             :       {
     823             :         if (__n == 0)
     824             :           return __s1;
     825             : #if __cplusplus >= 202002L
     826             :         if (std::__is_constant_evaluated())
     827             :           return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     828             : #endif
     829             :         return (static_cast<char_type*>
     830             :                 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
     831             :       }
     832             : 
     833             :       static _GLIBCXX20_CONSTEXPR char_type*
     834             :       assign(char_type* __s, size_t __n, char_type __a)
     835             :       {
     836             :         for (size_t __i = 0; __i < __n; ++__i)
     837             :           assign(__s[__i], __a);
     838             :         return __s;
     839             :       }
     840             : 
     841             :       static constexpr char_type
     842             :       to_char_type(const int_type& __c) noexcept
     843             :       { return char_type(__c); }
     844             : 
     845             :       static constexpr int_type
     846             :       to_int_type(const char_type& __c) noexcept
     847             :       { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
     848             : 
     849             :       static constexpr bool
     850             :       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
     851             :       { return __c1 == __c2; }
     852             : 
     853             :       static constexpr int_type
     854             :       eof() noexcept
     855             :       { return static_cast<int_type>(-1); }
     856             : 
     857             :       static constexpr int_type
     858             :       not_eof(const int_type& __c) noexcept
     859             :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     860             :     };
     861             : 
     862             :   template<>
     863             :     struct char_traits<char32_t>
     864             :     {
     865             :       typedef char32_t          char_type;
     866             : #ifdef _GLIBCXX_USE_C99_STDINT_TR1
     867             :       typedef uint_least32_t    int_type;
     868             : #elif defined __UINT_LEAST32_TYPE__
     869             :       typedef __UINT_LEAST32_TYPE__         int_type;
     870             : #else
     871             :       typedef make_unsigned<char32_t>::type int_type;
     872             : #endif
     873             :       typedef streamoff         off_type;
     874             :       typedef u32streampos      pos_type;
     875             :       typedef mbstate_t         state_type;
     876             : #if __cpp_lib_three_way_comparison
     877             :       using comparison_category = strong_ordering;
     878             : #endif
     879             : 
     880             :       static _GLIBCXX17_CONSTEXPR void
     881             :       assign(char_type& __c1, const char_type& __c2) noexcept
     882             :       {
     883             : #if __cpp_constexpr_dynamic_alloc
     884             :         if (std::__is_constant_evaluated())
     885             :           std::construct_at(__builtin_addressof(__c1), __c2);
     886             :         else
     887             : #endif
     888             :         __c1 = __c2;
     889             :       }
     890             : 
     891             :       static constexpr bool
     892             :       eq(const char_type& __c1, const char_type& __c2) noexcept
     893             :       { return __c1 == __c2; }
     894             : 
     895             :       static constexpr bool
     896             :       lt(const char_type& __c1, const char_type& __c2) noexcept
     897             :       { return __c1 < __c2; }
     898             : 
     899             :       static _GLIBCXX17_CONSTEXPR int
     900             :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     901             :       {
     902             :         for (size_t __i = 0; __i < __n; ++__i)
     903             :           if (lt(__s1[__i], __s2[__i]))
     904             :             return -1;
     905             :           else if (lt(__s2[__i], __s1[__i]))
     906             :             return 1;
     907             :         return 0;
     908             :       }
     909             : 
     910             :       static _GLIBCXX17_CONSTEXPR size_t
     911             :       length(const char_type* __s)
     912             :       {
     913             :         size_t __i = 0;
     914             :         while (!eq(__s[__i], char_type()))
     915             :           ++__i;
     916             :         return __i;
     917             :       }
     918             : 
     919             :       static _GLIBCXX17_CONSTEXPR const char_type*
     920             :       find(const char_type* __s, size_t __n, const char_type& __a)
     921             :       {
     922             :         for (size_t __i = 0; __i < __n; ++__i)
     923             :           if (eq(__s[__i], __a))
     924             :             return __s + __i;
     925             :         return 0;
     926             :       }
     927             : 
     928             :       static _GLIBCXX20_CONSTEXPR char_type*
     929             :       move(char_type* __s1, const char_type* __s2, size_t __n)
     930             :       {
     931             :         if (__n == 0)
     932             :           return __s1;
     933             : #if __cplusplus >= 202002L
     934             :         if (std::__is_constant_evaluated())
     935             :           return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     936             : #endif
     937             :         return (static_cast<char_type*>
     938             :                 (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
     939             :       }
     940             : 
     941             :       static _GLIBCXX20_CONSTEXPR char_type*
     942             :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     943             :       { 
     944             :         if (__n == 0)
     945             :           return __s1;
     946             : #if __cplusplus >= 202002L
     947             :         if (std::__is_constant_evaluated())
     948             :           return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     949             : #endif
     950             :         return (static_cast<char_type*>
     951             :                 (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
     952             :       }
     953             : 
     954             :       static _GLIBCXX20_CONSTEXPR char_type*
     955             :       assign(char_type* __s, size_t __n, char_type __a)
     956             :       {
     957             :         for (size_t __i = 0; __i < __n; ++__i)
     958             :           assign(__s[__i], __a);
     959             :         return __s;
     960             :       }
     961             : 
     962             :       static constexpr char_type
     963             :       to_char_type(const int_type& __c) noexcept
     964             :       { return char_type(__c); }
     965             : 
     966             :       static constexpr int_type
     967             :       to_int_type(const char_type& __c) noexcept
     968             :       { return int_type(__c); }
     969             : 
     970             :       static constexpr bool
     971             :       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
     972             :       { return __c1 == __c2; }
     973             : 
     974             :       static constexpr int_type
     975             :       eof() noexcept
     976             :       { return static_cast<int_type>(-1); }
     977             : 
     978             :       static constexpr int_type
     979             :       not_eof(const int_type& __c) noexcept
     980             :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     981             :     };
     982             : 
     983             : #if __cpp_lib_three_way_comparison
     984             :   namespace __detail
     985             :   {
     986             :     template<typename _ChTraits>
     987             :       constexpr auto
     988             :       __char_traits_cmp_cat(int __cmp) noexcept
     989             :       {
     990             :         if constexpr (requires { typename _ChTraits::comparison_category; })
     991             :           {
     992             :             using _Cat = typename _ChTraits::comparison_category;
     993             :             static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
     994             :             return static_cast<_Cat>(__cmp <=> 0);
     995             :           }
     996             :         else
     997             :           return static_cast<weak_ordering>(__cmp <=> 0);
     998             :       }
     999             :   } // namespace __detail
    1000             : #endif // C++20
    1001             : 
    1002             : #pragma GCC diagnostic pop
    1003             : 
    1004             : _GLIBCXX_END_NAMESPACE_VERSION
    1005             : } // namespace
    1006             : 
    1007             : #endif  // C++11
    1008             : 
    1009             : #endif // _CHAR_TRAITS_H

Generated by: LCOV version 1.16