LCOV - code coverage report
Current view: top level - /usr/include/c++/14/bits - char_traits.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 20.0 % 15 3
Test Date: 2026-02-27 05:14:50 Functions: 25.0 % 4 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Character Traits for use by standard string and iostream -*- C++ -*-
       2              : 
       3              : // Copyright (C) 1997-2024 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/c++config.h>
      40              : 
      41              : #if _GLIBCXX_HOSTED
      42              : # include <bits/postypes.h>     // For streampos
      43              : #endif // HOSTED
      44              : 
      45              : #ifdef _GLIBCXX_USE_WCHAR_T
      46              : # include <cwchar>              // For WEOF, wmemmove, wmemset, etc.
      47              : #endif // USE_WCHAR_T
      48              : 
      49              : #if __cplusplus >= 201103L
      50              : # include <type_traits>
      51              : #if !defined __UINT_LEAST16_TYPE__ || !defined __UINT_LEAST32_TYPE__
      52              : # include <cstdint>
      53              : #endif
      54              : #endif
      55              : #if __cplusplus >= 202002L
      56              : # include <compare>
      57              : # include <bits/stl_construct.h>
      58              : #endif
      59              : 
      60              : #ifndef _GLIBCXX_ALWAYS_INLINE
      61              : # define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
      62              : #endif
      63              : 
      64              : namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
      65              : {
      66              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      67              : 
      68              : #pragma GCC diagnostic push
      69              : #pragma GCC diagnostic ignored "-Wstringop-overflow"
      70              : #pragma GCC diagnostic ignored "-Wstringop-overread"
      71              : #pragma GCC diagnostic ignored "-Warray-bounds"
      72              : 
      73              :   /**
      74              :    *  @brief  Mapping from character type to associated types.
      75              :    *
      76              :    *  @note This is an implementation class for the generic version
      77              :    *  of char_traits.  It defines int_type, off_type, pos_type, and
      78              :    *  state_type.  By default these are unsigned long, streamoff,
      79              :    *  streampos, and mbstate_t.  Users who need a different set of
      80              :    *  types, but who don't need to change the definitions of any function
      81              :    *  defined in char_traits, can specialize __gnu_cxx::_Char_types
      82              :    *  while leaving __gnu_cxx::char_traits alone. */
      83              :   template<typename _CharT>
      84              :     struct _Char_types
      85              :     {
      86              :       typedef unsigned long   int_type;
      87              : #if _GLIBCXX_HOSTED
      88              :       typedef std::streampos  pos_type;
      89              :       typedef std::streamoff  off_type;
      90              :       typedef std::mbstate_t  state_type;
      91              : #endif // HOSTED
      92              :     };
      93              : 
      94              : 
      95              :   /**
      96              :    *  @brief  Base class used to implement std::char_traits.
      97              :    *
      98              :    *  @note For any given actual character type, this definition is
      99              :    *  probably wrong.  (Most of the member functions are likely to be
     100              :    *  right, but the int_type and state_type typedefs, and the eof()
     101              :    *  member function, are likely to be wrong.)  The reason this class
     102              :    *  exists is so users can specialize it.  Classes in namespace std
     103              :    *  may not be specialized for fundamental types, but classes in
     104              :    *  namespace __gnu_cxx may be.
     105              :    *
     106              :    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
     107              :    *  for advice on how to make use of this class for @a unusual character
     108              :    *  types. Also, check out include/ext/pod_char_traits.h.  
     109              :    */
     110              :   template<typename _CharT>
     111              :     struct char_traits
     112              :     {
     113              :       typedef _CharT                                    char_type;
     114              :       typedef typename _Char_types<_CharT>::int_type    int_type;
     115              : #if _GLIBCXX_HOSTED
     116              :       typedef typename _Char_types<_CharT>::pos_type    pos_type;
     117              :       typedef typename _Char_types<_CharT>::off_type    off_type;
     118              :       typedef typename _Char_types<_CharT>::state_type  state_type;
     119              : #endif // HOSTED
     120              : #if __cpp_lib_three_way_comparison
     121              :       using comparison_category = std::strong_ordering;
     122              : #endif
     123              : 
     124              :       static _GLIBCXX14_CONSTEXPR void
     125              :       assign(char_type& __c1, const char_type& __c2)
     126              :       {
     127              : #if __cpp_constexpr_dynamic_alloc
     128              :     if (std::__is_constant_evaluated())
     129              :       std::construct_at(__builtin_addressof(__c1), __c2);
     130              :     else
     131              : #endif
     132              :     __c1 = __c2;
     133              :       }
     134              : 
     135              :       static _GLIBCXX_CONSTEXPR bool
     136            0 :       eq(const char_type& __c1, const char_type& __c2)
     137            0 :       { return __c1 == __c2; }
     138              : 
     139              :       static _GLIBCXX_CONSTEXPR bool
     140              :       lt(const char_type& __c1, const char_type& __c2)
     141              :       { return __c1 < __c2; }
     142              : 
     143              :       static _GLIBCXX14_CONSTEXPR int
     144              :       compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
     145              : 
     146              :       static _GLIBCXX14_CONSTEXPR std::size_t
     147              :       length(const char_type* __s);
     148              : 
     149              :       static _GLIBCXX14_CONSTEXPR const char_type*
     150              :       find(const char_type* __s, std::size_t __n, const char_type& __a);
     151              : 
     152              :       static _GLIBCXX20_CONSTEXPR char_type*
     153              :       move(char_type* __s1, const char_type* __s2, std::size_t __n);
     154              : 
     155              :       static _GLIBCXX20_CONSTEXPR char_type*
     156              :       copy(char_type* __s1, const char_type* __s2, std::size_t __n);
     157              : 
     158              :       static _GLIBCXX20_CONSTEXPR char_type*
     159              :       assign(char_type* __s, std::size_t __n, char_type __a);
     160              : 
     161              :       static _GLIBCXX_CONSTEXPR char_type
     162              :       to_char_type(const int_type& __c)
     163              :       { return static_cast<char_type>(__c); }
     164              : 
     165              :       static _GLIBCXX_CONSTEXPR int_type
     166              :       to_int_type(const char_type& __c)
     167              :       { return static_cast<int_type>(__c); }
     168              : 
     169              :       static _GLIBCXX_CONSTEXPR bool
     170              :       eq_int_type(const int_type& __c1, const int_type& __c2)
     171              :       { return __c1 == __c2; }
     172              : 
     173              : #ifdef _GLIBCXX_STDIO_EOF
     174              :       static _GLIBCXX_CONSTEXPR int_type
     175              :       eof()
     176              :       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
     177              : 
     178              :       static _GLIBCXX_CONSTEXPR int_type
     179              :       not_eof(const int_type& __c)
     180              :       { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
     181              : #endif // defined(_GLIBCXX_STDIO_EOF)
     182              :     };
     183              : 
     184              :   template<typename _CharT>
     185              :     _GLIBCXX14_CONSTEXPR int
     186              :     char_traits<_CharT>::
     187              :     compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
     188              :     {
     189              :       for (std::size_t __i = 0; __i < __n; ++__i)
     190              :     if (lt(__s1[__i], __s2[__i]))
     191              :       return -1;
     192              :     else if (lt(__s2[__i], __s1[__i]))
     193              :       return 1;
     194              :       return 0;
     195              :     }
     196              : 
     197              :   template<typename _CharT>
     198              :     _GLIBCXX14_CONSTEXPR std::size_t
     199            0 :     char_traits<_CharT>::
     200              :     length(const char_type* __p)
     201              :     {
     202            0 :       std::size_t __i = 0;
     203            0 :       while (!eq(__p[__i], char_type()))
     204            0 :         ++__i;
     205            0 :       return __i;
     206              :     }
     207              : 
     208              :   template<typename _CharT>
     209              :     _GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
     210              :     char_traits<_CharT>::
     211              :     find(const char_type* __s, std::size_t __n, const char_type& __a)
     212              :     {
     213              :       for (std::size_t __i = 0; __i < __n; ++__i)
     214              :         if (eq(__s[__i], __a))
     215              :           return __s + __i;
     216              :       return 0;
     217              :     }
     218              : 
     219              :   template<typename _CharT>
     220              :     _GLIBCXX20_CONSTEXPR
     221              :     typename char_traits<_CharT>::char_type*
     222              :     char_traits<_CharT>::
     223              :     move(char_type* __s1, const char_type* __s2, std::size_t __n)
     224              :     {
     225              :       if (__n == 0)
     226              :     return __s1;
     227              : #if __cplusplus >= 202002L
     228              :       if (std::__is_constant_evaluated())
     229              :     {
     230              :       // Use __builtin_constant_p to avoid comparing unrelated pointers.
     231              :       if (__builtin_constant_p(__s2 < __s1)
     232              :         && __s1 > __s2 && __s1 < (__s2 + __n))
     233              :         {
     234              :           do
     235              :         {
     236              :           --__n;
     237              :           assign(__s1[__n], __s2[__n]);
     238              :         }
     239              :           while (__n > 0);
     240              :         }
     241              :       else
     242              :         copy(__s1, __s2, __n);
     243              :       return __s1;
     244              :     }
     245              : #endif
     246              :       __builtin_memmove(__s1, __s2, __n * sizeof(char_type));
     247              :       return __s1;
     248              :     }
     249              : 
     250              :   template<typename _CharT>
     251              :     _GLIBCXX20_CONSTEXPR
     252              :     typename char_traits<_CharT>::char_type*
     253              :     char_traits<_CharT>::
     254              :     copy(char_type* __s1, const char_type* __s2, std::size_t __n)
     255              :     {
     256              :       if (__n == 0)
     257              :     return __s1;
     258              : #if __cplusplus >= 202002L
     259              :       if (std::__is_constant_evaluated())
     260              :     {
     261              :       for (std::size_t __i = 0; __i < __n; ++__i)
     262              :         std::construct_at(__s1 + __i, __s2[__i]);
     263              :       return __s1;
     264              :     }
     265              : #endif
     266              :       __builtin_memcpy(__s1, __s2, __n * sizeof(char_type));
     267              :       return __s1;
     268              :     }
     269              : 
     270              :   template<typename _CharT>
     271              :     _GLIBCXX20_CONSTEXPR
     272              :     typename char_traits<_CharT>::char_type*
     273              :     char_traits<_CharT>::
     274              :     assign(char_type* __s, std::size_t __n, char_type __a)
     275              :     {
     276              : #if __cplusplus >= 202002L
     277              :       if (std::__is_constant_evaluated())
     278              :     {
     279              :       for (std::size_t __i = 0; __i < __n; ++__i)
     280              :         std::construct_at(__s + __i, __a);
     281              :       return __s;
     282              :     }
     283              : #endif
     284              : 
     285              :       if _GLIBCXX17_CONSTEXPR (sizeof(_CharT) == 1 && __is_trivial(_CharT))
     286              :     {
     287              :       if (__n)
     288              :         {
     289              :           unsigned char __c;
     290              :           __builtin_memcpy(&__c, __builtin_addressof(__a), 1);
     291              :           __builtin_memset(__s, __c, __n);
     292              :         }
     293              :     }
     294              :       else
     295              :     {
     296              :       for (std::size_t __i = 0; __i < __n; ++__i)
     297              :         __s[__i] = __a;
     298              :     }
     299              :       return __s;
     300              :     }
     301              : 
     302              : _GLIBCXX_END_NAMESPACE_VERSION
     303              : } // namespace
     304              : 
     305              : namespace std _GLIBCXX_VISIBILITY(default)
     306              : {
     307              : _GLIBCXX_BEGIN_NAMESPACE_VERSION
     308              : 
     309              :   // 21.1
     310              :   /**
     311              :    *  @brief  Basis for explicit traits specializations.
     312              :    *
     313              :    *  @note  For any given actual character type, this definition is
     314              :    *  probably wrong.  Since this is just a thin wrapper around
     315              :    *  __gnu_cxx::char_traits, it is possible to achieve a more
     316              :    *  appropriate definition by specializing __gnu_cxx::char_traits.
     317              :    *
     318              :    *  See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
     319              :    *  for advice on how to make use of this class for @a unusual character
     320              :    *  types. Also, check out include/ext/pod_char_traits.h.
     321              :   */
     322              :   template<typename _CharT>
     323              :     struct char_traits : public __gnu_cxx::char_traits<_CharT>
     324              :     { };
     325              : 
     326              : 
     327              :   /// 21.1.3.1  char_traits specializations
     328              :   template<>
     329              :     struct char_traits<char>
     330              :     {
     331              :       typedef char              char_type;
     332              :       typedef int               int_type;
     333              : #if _GLIBCXX_HOSTED
     334              :       typedef streampos         pos_type;
     335              :       typedef streamoff         off_type;
     336              :       typedef mbstate_t         state_type;
     337              : #endif // HOSTED
     338              : #if __cpp_lib_three_way_comparison
     339              :       using comparison_category = strong_ordering;
     340              : #endif
     341              : 
     342              :       static _GLIBCXX17_CONSTEXPR void
     343              :       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     344              :       {
     345              : #if __cpp_constexpr_dynamic_alloc
     346              :     if (std::__is_constant_evaluated())
     347              :       std::construct_at(__builtin_addressof(__c1), __c2);
     348              :     else
     349              : #endif
     350              :     __c1 = __c2;
     351              :       }
     352              : 
     353              :       static _GLIBCXX_CONSTEXPR bool
     354              :       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     355              :       { return __c1 == __c2; }
     356              : 
     357              :       static _GLIBCXX_CONSTEXPR bool
     358              :       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     359              :       {
     360              :     // LWG 467.
     361              :     return (static_cast<unsigned char>(__c1)
     362              :         < static_cast<unsigned char>(__c2));
     363              :       }
     364              : 
     365              :       static _GLIBCXX17_CONSTEXPR int
     366              :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     367              :       {
     368              :     if (__n == 0)
     369              :       return 0;
     370              : #if __cplusplus >= 201703L
     371              :     if (std::__is_constant_evaluated())
     372              :       {
     373              :         for (size_t __i = 0; __i < __n; ++__i)
     374              :           if (lt(__s1[__i], __s2[__i]))
     375              :         return -1;
     376              :           else if (lt(__s2[__i], __s1[__i]))
     377              :         return 1;
     378              :         return 0;
     379              :       }
     380              : #endif
     381              :     return __builtin_memcmp(__s1, __s2, __n);
     382              :       }
     383              : 
     384              :       static _GLIBCXX17_CONSTEXPR size_t
     385         9358 :       length(const char_type* __s)
     386              :       {
     387              : #if __cplusplus >= 201703L
     388         9358 :     if (std::__is_constant_evaluated())
     389            0 :       return __gnu_cxx::char_traits<char_type>::length(__s);
     390              : #endif
     391         9358 :     return __builtin_strlen(__s);
     392              :       }
     393              : 
     394              :       static _GLIBCXX17_CONSTEXPR const char_type*
     395              :       find(const char_type* __s, size_t __n, const char_type& __a)
     396              :       {
     397              :     if (__n == 0)
     398              :       return 0;
     399              : #if __cplusplus >= 201703L
     400              :     if (std::__is_constant_evaluated())
     401              :       return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
     402              : #endif
     403              :     return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
     404              :       }
     405              : 
     406              :       static _GLIBCXX20_CONSTEXPR char_type*
     407              :       move(char_type* __s1, const char_type* __s2, size_t __n)
     408              :       {
     409              :     if (__n == 0)
     410              :       return __s1;
     411              : #if __cplusplus >= 202002L
     412              :     if (std::__is_constant_evaluated())
     413              :       return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     414              : #endif
     415              :     return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
     416              :       }
     417              : 
     418              :       static _GLIBCXX20_CONSTEXPR char_type*
     419            0 :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     420              :       {
     421            0 :     if (__n == 0)
     422            0 :       return __s1;
     423              : #if __cplusplus >= 202002L
     424              :     if (std::__is_constant_evaluated())
     425              :       return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     426              : #endif
     427            0 :     return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
     428              :       }
     429              : 
     430              :       static _GLIBCXX20_CONSTEXPR char_type*
     431              :       assign(char_type* __s, size_t __n, char_type __a)
     432              :       {
     433              :     if (__n == 0)
     434              :       return __s;
     435              : #if __cplusplus >= 202002L
     436              :     if (std::__is_constant_evaluated())
     437              :       return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
     438              : #endif
     439              :     return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
     440              :       }
     441              : 
     442              :       static _GLIBCXX_CONSTEXPR char_type
     443              :       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
     444              :       { return static_cast<char_type>(__c); }
     445              : 
     446              :       // To keep both the byte 0xff and the eof symbol 0xffffffff
     447              :       // from ending up as 0xffffffff.
     448              :       static _GLIBCXX_CONSTEXPR int_type
     449              :       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
     450              :       { return static_cast<int_type>(static_cast<unsigned char>(__c)); }
     451              : 
     452              :       static _GLIBCXX_CONSTEXPR bool
     453              :       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
     454              :       { return __c1 == __c2; }
     455              : 
     456              : #ifdef _GLIBCXX_STDIO_EOF
     457              :       static _GLIBCXX_CONSTEXPR int_type
     458              :       eof() _GLIBCXX_NOEXCEPT
     459              :       { return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
     460              : 
     461              :       static _GLIBCXX_CONSTEXPR int_type
     462              :       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
     463              :       { return (__c == eof()) ? 0 : __c; }
     464              : #endif // defined(_GLIBCXX_STDIO_EOF)
     465              :   };
     466              : 
     467              : 
     468              : #ifdef _GLIBCXX_USE_WCHAR_T
     469              :   /// 21.1.3.2  char_traits specializations
     470              :   template<>
     471              :     struct char_traits<wchar_t>
     472              :     {
     473              :       typedef wchar_t           char_type;
     474              :       typedef wint_t            int_type;
     475              : #if _GLIBCXX_HOSTED
     476              :       typedef streamoff         off_type;
     477              :       typedef wstreampos        pos_type;
     478              :       typedef mbstate_t         state_type;
     479              : #endif // HOSTED
     480              : #if __cpp_lib_three_way_comparison
     481              :       using comparison_category = strong_ordering;
     482              : #endif
     483              : 
     484              :       static _GLIBCXX17_CONSTEXPR void
     485              :       assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     486              :       {
     487              : #if __cpp_constexpr_dynamic_alloc
     488              :     if (std::__is_constant_evaluated())
     489              :       std::construct_at(__builtin_addressof(__c1), __c2);
     490              :     else
     491              : #endif
     492              :     __c1 = __c2;
     493              :       }
     494              : 
     495              :       static _GLIBCXX_CONSTEXPR bool
     496              :       eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     497              :       { return __c1 == __c2; }
     498              : 
     499              :       static _GLIBCXX_CONSTEXPR bool
     500              :       lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
     501              :       { return __c1 < __c2; }
     502              : 
     503              :       static _GLIBCXX17_CONSTEXPR int
     504              :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     505              :       {
     506              :     if (__n == 0)
     507              :       return 0;
     508              : #if __cplusplus >= 201703L
     509              :     if (std::__is_constant_evaluated())
     510              :       return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
     511              : #endif
     512              :     return wmemcmp(__s1, __s2, __n);
     513              :       }
     514              : 
     515              :       static _GLIBCXX17_CONSTEXPR size_t
     516              :       length(const char_type* __s)
     517              :       {
     518              : #if __cplusplus >= 201703L
     519              :     if (std::__is_constant_evaluated())
     520              :       return __gnu_cxx::char_traits<char_type>::length(__s);
     521              : #endif
     522              :     return wcslen(__s);
     523              :       }
     524              : 
     525              :       static _GLIBCXX17_CONSTEXPR const char_type*
     526              :       find(const char_type* __s, size_t __n, const char_type& __a)
     527              :       {
     528              :     if (__n == 0)
     529              :       return 0;
     530              : #if __cplusplus >= 201703L
     531              :     if (std::__is_constant_evaluated())
     532              :       return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
     533              : #endif
     534              :     return wmemchr(__s, __a, __n);
     535              :       }
     536              : 
     537              :       static _GLIBCXX20_CONSTEXPR char_type*
     538              :       move(char_type* __s1, const char_type* __s2, size_t __n)
     539              :       {
     540              :     if (__n == 0)
     541              :       return __s1;
     542              : #if __cplusplus >= 202002L
     543              :     if (std::__is_constant_evaluated())
     544              :       return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     545              : #endif
     546              :     return wmemmove(__s1, __s2, __n);
     547              :       }
     548              : 
     549              :       static _GLIBCXX20_CONSTEXPR char_type*
     550              :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     551              :       {
     552              :     if (__n == 0)
     553              :       return __s1;
     554              : #if __cplusplus >= 202002L
     555              :     if (std::__is_constant_evaluated())
     556              :       return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     557              : #endif
     558              :     return wmemcpy(__s1, __s2, __n);
     559              :       }
     560              : 
     561              :       static _GLIBCXX20_CONSTEXPR char_type*
     562              :       assign(char_type* __s, size_t __n, char_type __a)
     563              :       {
     564              :     if (__n == 0)
     565              :       return __s;
     566              : #if __cplusplus >= 202002L
     567              :     if (std::__is_constant_evaluated())
     568              :       return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
     569              : #endif
     570              :     return wmemset(__s, __a, __n);
     571              :       }
     572              : 
     573              :       static _GLIBCXX_CONSTEXPR char_type
     574              :       to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
     575              :       { return char_type(__c); }
     576              : 
     577              :       static _GLIBCXX_CONSTEXPR int_type
     578              :       to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
     579              :       { return int_type(__c); }
     580              : 
     581              :       static _GLIBCXX_CONSTEXPR bool
     582              :       eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
     583              :       { return __c1 == __c2; }
     584              : 
     585              : #if _GLIBCXX_HOSTED
     586              :       static _GLIBCXX_CONSTEXPR int_type
     587              :       eof() _GLIBCXX_NOEXCEPT
     588              :       { return static_cast<int_type>(WEOF); }
     589              : 
     590              :       static _GLIBCXX_CONSTEXPR int_type
     591              :       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
     592              :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     593              : #endif // HOSTED
     594              :   };
     595              : #else // _GLIBCXX_USE_WCHAR_T
     596              :   template<>
     597              :     struct char_traits<wchar_t> : public __gnu_cxx::char_traits<wchar_t>
     598              :     { };
     599              : #endif //_GLIBCXX_USE_WCHAR_T
     600              : 
     601              : #ifdef _GLIBCXX_USE_CHAR8_T
     602              :   template<>
     603              :     struct char_traits<char8_t>
     604              :     {
     605              :       typedef char8_t           char_type;
     606              :       typedef unsigned int      int_type;
     607              : #if _GLIBCXX_HOSTED
     608              :       typedef u8streampos       pos_type;
     609              :       typedef streamoff         off_type;
     610              :       typedef mbstate_t         state_type;
     611              : #endif // HOSTED
     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              : #if _GLIBCXX_HOSTED
     721              :       static _GLIBCXX_CONSTEXPR int_type
     722              :       eof() _GLIBCXX_NOEXCEPT
     723              :       { return static_cast<int_type>(-1); }
     724              : 
     725              :       static _GLIBCXX_CONSTEXPR int_type
     726              :       not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
     727              :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     728              : #endif // HOSTED
     729              :     };
     730              : #endif //_GLIBCXX_USE_CHAR8_T
     731              : 
     732              : _GLIBCXX_END_NAMESPACE_VERSION
     733              : } // namespace
     734              : 
     735              : #if __cplusplus >= 201103L
     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 __UINT_LEAST16_TYPE__
     746              :       typedef __UINT_LEAST16_TYPE__     int_type;
     747              : #else
     748              :       typedef uint_least16_t    int_type;
     749              : #endif
     750              : #if _GLIBCXX_HOSTED
     751              :       typedef streamoff         off_type;
     752              :       typedef u16streampos      pos_type;
     753              :       typedef mbstate_t         state_type;
     754              : #endif // HOSTED
     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 bool
     846              :       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
     847              :       { return __c1 == __c2; }
     848              : 
     849              : #if _GLIBCXX_HOSTED
     850              :       static constexpr int_type
     851              :       to_int_type(const char_type& __c) noexcept
     852              :       { return __c == eof() ? int_type(0xfffd) : int_type(__c); }
     853              : 
     854              :       static constexpr int_type
     855              :       eof() noexcept
     856              :       { return static_cast<int_type>(-1); }
     857              : 
     858              :       static constexpr int_type
     859              :       not_eof(const int_type& __c) noexcept
     860              :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     861              : #else // !HOSTED
     862              :       static constexpr int_type
     863              :       to_int_type(const char_type& __c) noexcept
     864              :       { return int_type(__c); }
     865              : #endif // !HOSTED
     866              :     };
     867              : 
     868              :   template<>
     869              :     struct char_traits<char32_t>
     870              :     {
     871              :       typedef char32_t          char_type;
     872              : #ifdef __UINT_LEAST32_TYPE__
     873              :       typedef __UINT_LEAST32_TYPE__     int_type;
     874              : #else
     875              :       typedef uint_least32_t    int_type;
     876              : #endif
     877              : #if _GLIBCXX_HOSTED
     878              :       typedef streamoff         off_type;
     879              :       typedef u32streampos      pos_type;
     880              :       typedef mbstate_t         state_type;
     881              : #endif // HOSTED
     882              : #if __cpp_lib_three_way_comparison
     883              :       using comparison_category = strong_ordering;
     884              : #endif
     885              : 
     886              :       static _GLIBCXX17_CONSTEXPR void
     887              :       assign(char_type& __c1, const char_type& __c2) noexcept
     888              :       {
     889              : #if __cpp_constexpr_dynamic_alloc
     890              :     if (std::__is_constant_evaluated())
     891              :       std::construct_at(__builtin_addressof(__c1), __c2);
     892              :     else
     893              : #endif
     894              :     __c1 = __c2;
     895              :       }
     896              : 
     897              :       static constexpr bool
     898              :       eq(const char_type& __c1, const char_type& __c2) noexcept
     899              :       { return __c1 == __c2; }
     900              : 
     901              :       static constexpr bool
     902              :       lt(const char_type& __c1, const char_type& __c2) noexcept
     903              :       { return __c1 < __c2; }
     904              : 
     905              :       static _GLIBCXX17_CONSTEXPR int
     906              :       compare(const char_type* __s1, const char_type* __s2, size_t __n)
     907              :       {
     908              :     for (size_t __i = 0; __i < __n; ++__i)
     909              :       if (lt(__s1[__i], __s2[__i]))
     910              :         return -1;
     911              :       else if (lt(__s2[__i], __s1[__i]))
     912              :         return 1;
     913              :     return 0;
     914              :       }
     915              : 
     916              :       static _GLIBCXX17_CONSTEXPR size_t
     917              :       length(const char_type* __s)
     918              :       {
     919              :     size_t __i = 0;
     920              :     while (!eq(__s[__i], char_type()))
     921              :       ++__i;
     922              :     return __i;
     923              :       }
     924              : 
     925              :       static _GLIBCXX17_CONSTEXPR const char_type*
     926              :       find(const char_type* __s, size_t __n, const char_type& __a)
     927              :       {
     928              :     for (size_t __i = 0; __i < __n; ++__i)
     929              :       if (eq(__s[__i], __a))
     930              :         return __s + __i;
     931              :     return 0;
     932              :       }
     933              : 
     934              :       static _GLIBCXX20_CONSTEXPR char_type*
     935              :       move(char_type* __s1, const char_type* __s2, size_t __n)
     936              :       {
     937              :     if (__n == 0)
     938              :       return __s1;
     939              : #if __cplusplus >= 202002L
     940              :     if (std::__is_constant_evaluated())
     941              :       return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
     942              : #endif
     943              :     return (static_cast<char_type*>
     944              :         (__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
     945              :       }
     946              : 
     947              :       static _GLIBCXX20_CONSTEXPR char_type*
     948              :       copy(char_type* __s1, const char_type* __s2, size_t __n)
     949              :       { 
     950              :     if (__n == 0)
     951              :       return __s1;
     952              : #if __cplusplus >= 202002L
     953              :     if (std::__is_constant_evaluated())
     954              :       return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
     955              : #endif
     956              :     return (static_cast<char_type*>
     957              :         (__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
     958              :       }
     959              : 
     960              :       static _GLIBCXX20_CONSTEXPR char_type*
     961              :       assign(char_type* __s, size_t __n, char_type __a)
     962              :       {
     963              :     for (size_t __i = 0; __i < __n; ++__i)
     964              :       assign(__s[__i], __a);
     965              :     return __s;
     966              :       }
     967              : 
     968              :       static constexpr char_type
     969              :       to_char_type(const int_type& __c) noexcept
     970              :       { return char_type(__c); }
     971              : 
     972              :       static constexpr int_type
     973              :       to_int_type(const char_type& __c) noexcept
     974              :       { return int_type(__c); }
     975              : 
     976              :       static constexpr bool
     977              :       eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
     978              :       { return __c1 == __c2; }
     979              : 
     980              : #if _GLIBCXX_HOSTED
     981              :       static constexpr int_type
     982              :       eof() noexcept
     983              :       { return static_cast<int_type>(-1); }
     984              : 
     985              :       static constexpr int_type
     986              :       not_eof(const int_type& __c) noexcept
     987              :       { return eq_int_type(__c, eof()) ? 0 : __c; }
     988              : #endif // HOSTED
     989              :     };
     990              : 
     991              : #if __cpp_lib_three_way_comparison
     992              :   namespace __detail
     993              :   {
     994              :     template<typename _ChTraits>
     995              :       constexpr auto
     996              :       __char_traits_cmp_cat(int __cmp) noexcept
     997              :       {
     998              :     if constexpr (requires { typename _ChTraits::comparison_category; })
     999              :       {
    1000              :         using _Cat = typename _ChTraits::comparison_category;
    1001              :         static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
    1002              :         return static_cast<_Cat>(__cmp <=> 0);
    1003              :       }
    1004              :     else
    1005              :       return static_cast<weak_ordering>(__cmp <=> 0);
    1006              :       }
    1007              :   } // namespace __detail
    1008              : #endif // C++20
    1009              : 
    1010              : #pragma GCC diagnostic pop
    1011              : 
    1012              : _GLIBCXX_END_NAMESPACE_VERSION
    1013              : } // namespace
    1014              : 
    1015              : #endif  // C++11
    1016              : 
    1017              : #endif // _CHAR_TRAITS_H
        

Generated by: LCOV version 2.0-1