LCOV - code coverage report
Current view: top level - v1/__string - char_traits.h (source / functions) Coverage Total Hit
Test: vrml_testfiles.info Lines: 91.4 % 81 74
Test Date: 2024-03-08 16:12:17 Functions: 100.0 % 14 14

            Line data    Source code
       1              : //===----------------------------------------------------------------------===//
       2              : //
       3              : // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4              : // See https://llvm.org/LICENSE.txt for license information.
       5              : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6              : //
       7              : //===----------------------------------------------------------------------===//
       8              : 
       9              : #ifndef _LIBCPP___STRING_CHAR_TRAITS_H
      10              : #define _LIBCPP___STRING_CHAR_TRAITS_H
      11              : 
      12              : #include <__algorithm/copy_n.h>
      13              : #include <__algorithm/fill_n.h>
      14              : #include <__algorithm/find_end.h>
      15              : #include <__algorithm/find_first_of.h>
      16              : #include <__algorithm/min.h>
      17              : #include <__compare/ordering.h>
      18              : #include <__config>
      19              : #include <__functional/hash.h>
      20              : #include <__iterator/iterator_traits.h>
      21              : #include <__type_traits/is_constant_evaluated.h>
      22              : #include <cstddef>
      23              : #include <cstdint>
      24              : #include <cstdio>
      25              : #include <cstring>
      26              : #include <iosfwd>
      27              : 
      28              : #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
      29              : #   include <cwchar> // for wmemcpy
      30              : #endif
      31              : 
      32              : #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
      33              : #  pragma GCC system_header
      34              : #endif
      35              : 
      36              : _LIBCPP_PUSH_MACROS
      37              : #include <__undef_macros>
      38              : 
      39              : _LIBCPP_BEGIN_NAMESPACE_STD
      40              : 
      41              : template <class _CharT>
      42              : struct char_traits;
      43              : /*
      44              : The Standard does not define the base template for char_traits because it is impossible to provide
      45              : a correct definition for arbitrary character types. Instead, it requires implementations to provide
      46              : specializations for predefined character types like `char`, `wchar_t` and others. We provide this as
      47              : exposition-only to document what members a char_traits specialization should provide:
      48              : {
      49              :     using char_type  = _CharT;
      50              :     using int_type   = ...;
      51              :     using off_type   = ...;
      52              :     using pos_type   = ...;
      53              :     using state_type = ...;
      54              : 
      55              :     static void assign(char_type&, const char_type&);
      56              :     static bool eq(char_type, char_type);
      57              :     static bool lt(char_type, char_type);
      58              : 
      59              :     static int              compare(const char_type*, const char_type*, size_t);
      60              :     static size_t           length(const char_type*);
      61              :     static const char_type* find(const char_type*, size_t, const char_type&);
      62              :     static char_type*       move(char_type*, const char_type*, size_t);
      63              :     static char_type*       copy(char_type*, const char_type*, size_t);
      64              :     static char_type*       assign(char_type*, size_t, char_type);
      65              : 
      66              :     static int_type  not_eof(int_type);
      67              :     static char_type to_char_type(int_type);
      68              :     static int_type  to_int_type(char_type);
      69              :     static bool      eq_int_type(int_type, int_type);
      70              :     static int_type  eof();
      71              : };
      72              : */
      73              : 
      74              : //
      75              : // Temporary extension to provide a base template for std::char_traits.
      76              : // TODO: Remove in LLVM 18.
      77              : //
      78              : template <class _CharT>
      79              : struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it.")
      80              :     char_traits
      81              : {
      82              :     using char_type  = _CharT;
      83              :     using int_type   = int;
      84              :     using off_type   = streamoff;
      85              :     using pos_type   = streampos;
      86              :     using state_type = mbstate_t;
      87              : 
      88              :     static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17
      89              :         assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
      90              :     static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
      91              :         {return __c1 == __c2;}
      92              :     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
      93              :         {return __c1 < __c2;}
      94              : 
      95              :     static _LIBCPP_CONSTEXPR_SINCE_CXX17
      96              :     int compare(const char_type* __s1, const char_type* __s2, size_t __n) {
      97              :         for (; __n; --__n, ++__s1, ++__s2)
      98              :         {
      99              :             if (lt(*__s1, *__s2))
     100              :                 return -1;
     101              :             if (lt(*__s2, *__s1))
     102              :                 return 1;
     103              :         }
     104              :         return 0;
     105              :     }
     106              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     107              :     size_t length(const char_type* __s) {
     108              :         size_t __len = 0;
     109              :         for (; !eq(*__s, char_type(0)); ++__s)
     110              :             ++__len;
     111              :         return __len;
     112              :     }
     113              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     114              :     const char_type* find(const char_type* __s, size_t __n, const char_type& __a) {
     115              :         for (; __n; --__n)
     116              :         {
     117              :             if (eq(*__s, __a))
     118              :                 return __s;
     119              :             ++__s;
     120              :         }
     121              :         return nullptr;
     122              :     }
     123              :     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     124              :     char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) {
     125              :         if (__n == 0) return __s1;
     126              :         char_type* __r = __s1;
     127              :         if (__s1 < __s2)
     128              :         {
     129              :             for (; __n; --__n, ++__s1, ++__s2)
     130              :                 assign(*__s1, *__s2);
     131              :         }
     132              :         else if (__s2 < __s1)
     133              :         {
     134              :             __s1 += __n;
     135              :             __s2 += __n;
     136              :             for (; __n; --__n)
     137              :                 assign(*--__s1, *--__s2);
     138              :         }
     139              :         return __r;
     140              :     }
     141              :     _LIBCPP_INLINE_VISIBILITY
     142              :     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     143              :     char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) {
     144              :         if (!__libcpp_is_constant_evaluated()) {
     145              :             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     146              :         }
     147              :         char_type* __r = __s1;
     148              :         for (; __n; --__n, ++__s1, ++__s2)
     149              :             assign(*__s1, *__s2);
     150              :         return __r;
     151              :     }
     152              :     _LIBCPP_INLINE_VISIBILITY
     153              :     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     154              :     char_type*       assign(char_type* __s, size_t __n, char_type __a) {
     155              :         char_type* __r = __s;
     156              :         for (; __n; --__n, ++__s)
     157              :             assign(*__s, __a);
     158              :         return __r;
     159              :     }
     160              : 
     161              :     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
     162              :         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
     163              :     static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
     164              :         {return char_type(__c);}
     165              :     static inline _LIBCPP_CONSTEXPR int_type  to_int_type(char_type __c) _NOEXCEPT
     166              :         {return int_type(__c);}
     167              :     static inline _LIBCPP_CONSTEXPR bool      eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
     168              :         {return __c1 == __c2;}
     169              :     static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
     170              :         {return int_type(EOF);}
     171              : };
     172              : 
     173              : template <class _CharT>
     174              : _LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     175              : _CharT* __char_traits_move(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT
     176              : {
     177              : #ifdef _LIBCPP_COMPILER_GCC
     178              :   if (__libcpp_is_constant_evaluated()) {
     179              :     if (__n == 0)
     180              :       return __dest;
     181              :     _CharT* __allocation = new _CharT[__n];
     182              :     std::copy_n(__source, __n, __allocation);
     183              :     std::copy_n(static_cast<const _CharT*>(__allocation), __n, __dest);
     184              :     delete[] __allocation;
     185              :     return __dest;
     186              :   }
     187              : #endif
     188              :   ::__builtin_memmove(__dest, __source, __n * sizeof(_CharT));
     189              :   return __dest;
     190              : }
     191              : 
     192              : // char_traits<char>
     193              : 
     194              : template <>
     195              : struct _LIBCPP_TEMPLATE_VIS char_traits<char>
     196              : {
     197              :     using char_type           = char;
     198              :     using int_type            = int;
     199              :     using off_type            = streamoff;
     200              :     using pos_type            = streampos;
     201              :     using state_type          = mbstate_t;
     202              : #if _LIBCPP_STD_VER > 17
     203              :     using comparison_category = strong_ordering;
     204              : #endif
     205              : 
     206              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     207          749 :     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
     208       111678 :     static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
     209       111678 :             {return __c1 == __c2;}
     210              :     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
     211              :         {return (unsigned char)__c1 < (unsigned char)__c2;}
     212              : 
     213        13597 :   static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     214        13597 :     if (__n == 0)
     215           10 :       return 0;
     216        13587 :     return std::__constexpr_memcmp(__s1, __s2, __n);
     217        13597 :   }
     218              : 
     219        23365 :   static inline size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s)  _NOEXCEPT {
     220        23365 :     return std::__constexpr_strlen(__s);
     221            0 :   }
     222              : 
     223              :   static _LIBCPP_CONSTEXPR_SINCE_CXX17
     224        24207 :   const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
     225        24207 :     if (__n == 0)
     226            0 :         return nullptr;
     227        24207 :     return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n);
     228        24207 :   }
     229              : 
     230              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     231              :     char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     232              :         return std::__char_traits_move(__s1, __s2, __n);
     233              :     }
     234              : 
     235              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     236              :     char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     237              :         if (!__libcpp_is_constant_evaluated())
     238              :             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     239              :         std::copy_n(__s2, __n, __s1);
     240              :         return __s1;
     241              :     }
     242              : 
     243              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     244              :     char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
     245              :         std::fill_n(__s, __n, __a);
     246              :         return __s;
     247              :     }
     248              : 
     249              :     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
     250              :         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
     251        37593 :     static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
     252        37593 :         {return char_type(__c);}
     253        37582 :     static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
     254        37582 :         {return int_type((unsigned char)__c);}
     255        37718 :     static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
     256        37718 :         {return __c1 == __c2;}
     257        37721 :     static inline _LIBCPP_CONSTEXPR int_type  eof() _NOEXCEPT
     258        37721 :         {return int_type(EOF);}
     259              : };
     260              : 
     261              : // char_traits<wchar_t>
     262              : 
     263              : #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
     264              : template <>
     265              : struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
     266              : {
     267              :     using char_type           = wchar_t;
     268              :     using int_type            = wint_t;
     269              :     using off_type            = streamoff;
     270              :     using pos_type            = streampos;
     271              :     using state_type          = mbstate_t;
     272              : #if _LIBCPP_STD_VER > 17
     273              :     using comparison_category = strong_ordering;
     274              : #endif
     275              : 
     276              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     277              :     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
     278              :     static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
     279              :         {return __c1 == __c2;}
     280              :     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
     281              :         {return __c1 < __c2;}
     282              : 
     283              :   static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     284              :     if (__n == 0)
     285              :         return 0;
     286              :     return std::__constexpr_wmemcmp(__s1, __s2, __n);
     287              :   }
     288              : 
     289              :   static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
     290              :     return std::__constexpr_wcslen(__s);
     291              :   }
     292              : 
     293              :   static _LIBCPP_CONSTEXPR_SINCE_CXX17
     294              :   const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
     295              :     if (__n == 0)
     296              :         return nullptr;
     297              :     return std::__constexpr_wmemchr(__s, __a, __n);
     298              :   }
     299              : 
     300              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     301              :     char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     302              :         return std::__char_traits_move(__s1, __s2, __n);
     303              :     }
     304              : 
     305              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     306              :     char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     307              :         if (!__libcpp_is_constant_evaluated())
     308              :             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     309              :         std::copy_n(__s2, __n, __s1);
     310              :         return __s1;
     311              :     }
     312              : 
     313              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX20
     314              :     char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
     315              :         std::fill_n(__s, __n, __a);
     316              :         return __s;
     317              :     }
     318              : 
     319              :     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
     320              :         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
     321              :     static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
     322              :         {return char_type(__c);}
     323              :     static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
     324              :         {return int_type(__c);}
     325              :     static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
     326              :         {return __c1 == __c2;}
     327              :     static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
     328              :         {return int_type(WEOF);}
     329              : };
     330              : #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
     331              : 
     332              : #ifndef _LIBCPP_HAS_NO_CHAR8_T
     333              : 
     334              : template <>
     335              : struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
     336              : {
     337              :     using char_type           = char8_t;
     338              :     using int_type            = unsigned int;
     339              :     using off_type            = streamoff;
     340              :     using pos_type            = u8streampos;
     341              :     using state_type          = mbstate_t;
     342              : #if _LIBCPP_STD_VER > 17
     343              :     using comparison_category = strong_ordering;
     344              : #endif
     345              : 
     346              :     static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
     347              :         {__c1 = __c2;}
     348              :     static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
     349              :         {return __c1 == __c2;}
     350              :     static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
     351              :         {return __c1 < __c2;}
     352              : 
     353              :   static _LIBCPP_HIDE_FROM_ABI constexpr int
     354              :   compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     355              :       return std::__constexpr_memcmp(__s1, __s2, __n);
     356              :   }
     357              : 
     358              :     static constexpr
     359              :     size_t           length(const char_type* __s) _NOEXCEPT;
     360              : 
     361              :     _LIBCPP_INLINE_VISIBILITY static constexpr
     362              :     const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
     363              : 
     364              :     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     365              :     char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     366              :         return std::__char_traits_move(__s1, __s2, __n);
     367              :     }
     368              : 
     369              :     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     370              :     char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     371              :         if (!__libcpp_is_constant_evaluated())
     372              :             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     373              :         std::copy_n(__s2, __n, __s1);
     374              :         return __s1;
     375              :     }
     376              : 
     377              :     static _LIBCPP_CONSTEXPR_SINCE_CXX20
     378              :     char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
     379              :         std::fill_n(__s, __n, __a);
     380              :         return __s;
     381              :     }
     382              : 
     383              :     static inline constexpr int_type  not_eof(int_type __c) noexcept
     384              :         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
     385              :     static inline constexpr char_type to_char_type(int_type __c) noexcept
     386              :         {return char_type(__c);}
     387              :     static inline constexpr int_type to_int_type(char_type __c) noexcept
     388              :         {return int_type(__c);}
     389              :     static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
     390              :         {return __c1 == __c2;}
     391              :     static inline constexpr int_type eof() noexcept
     392              :         {return int_type(EOF);}
     393              : };
     394              : 
     395              : // TODO use '__builtin_strlen' if it ever supports char8_t ??
     396              : inline constexpr
     397              : size_t
     398              : char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
     399              : {
     400              :     size_t __len = 0;
     401              :     for (; !eq(*__s, char_type(0)); ++__s)
     402              :         ++__len;
     403              :     return __len;
     404              : }
     405              : 
     406              : // TODO use '__builtin_char_memchr' if it ever supports char8_t ??
     407              : inline constexpr
     408              : const char8_t*
     409              : char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
     410              : {
     411              :     for (; __n; --__n)
     412              :     {
     413              :         if (eq(*__s, __a))
     414              :             return __s;
     415              :         ++__s;
     416              :     }
     417              :     return nullptr;
     418              : }
     419              : 
     420              : #endif // _LIBCPP_HAS_NO_CHAR8_T
     421              : 
     422              : template <>
     423              : struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
     424              : {
     425              :     using char_type           = char16_t;
     426              :     using int_type            = uint_least16_t;
     427              :     using off_type            = streamoff;
     428              :     using pos_type            = u16streampos;
     429              :     using state_type          = mbstate_t;
     430              : #if _LIBCPP_STD_VER > 17
     431              :     using comparison_category = strong_ordering;
     432              : #endif
     433              : 
     434              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     435              :     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
     436              :     static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
     437              :         {return __c1 == __c2;}
     438              :     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
     439              :         {return __c1 < __c2;}
     440              : 
     441              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     442              :     int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
     443              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     444              :     size_t           length(const char_type* __s) _NOEXCEPT;
     445              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     446              :     const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
     447              : 
     448              :     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     449              :     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     450              :         return std::__char_traits_move(__s1, __s2, __n);
     451              :     }
     452              : 
     453              :     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     454              :     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     455              :         if (!__libcpp_is_constant_evaluated())
     456              :             _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
     457              :         std::copy_n(__s2, __n, __s1);
     458              :         return __s1;
     459              :     }
     460              : 
     461              :     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     462              :     static char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
     463              :         std::fill_n(__s, __n, __a);
     464              :         return __s;
     465              :     }
     466              : 
     467              :     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
     468              :         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
     469              :     static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
     470              :         {return char_type(__c);}
     471              :     static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
     472              :         {return int_type(__c);}
     473              :     static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
     474              :         {return __c1 == __c2;}
     475              :     static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
     476              :         {return int_type(0xFFFF);}
     477              : };
     478              : 
     479              : inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     480              : int
     481              : char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
     482              : {
     483              :     for (; __n; --__n, ++__s1, ++__s2)
     484              :     {
     485              :         if (lt(*__s1, *__s2))
     486              :             return -1;
     487              :         if (lt(*__s2, *__s1))
     488              :             return 1;
     489              :     }
     490              :     return 0;
     491              : }
     492              : 
     493              : inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     494              : size_t
     495              : char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
     496              : {
     497              :     size_t __len = 0;
     498              :     for (; !eq(*__s, char_type(0)); ++__s)
     499              :         ++__len;
     500              :     return __len;
     501              : }
     502              : 
     503              : inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     504              : const char16_t*
     505              : char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
     506              : {
     507              :     for (; __n; --__n)
     508              :     {
     509              :         if (eq(*__s, __a))
     510              :             return __s;
     511              :         ++__s;
     512              :     }
     513              :     return nullptr;
     514              : }
     515              : 
     516              : template <>
     517              : struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
     518              : {
     519              :     using char_type           = char32_t;
     520              :     using int_type            = uint_least32_t;
     521              :     using off_type            = streamoff;
     522              :     using pos_type            = u32streampos;
     523              :     using state_type          = mbstate_t;
     524              : #if _LIBCPP_STD_VER > 17
     525              :     using comparison_category = strong_ordering;
     526              : #endif
     527              : 
     528              :     static inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     529              :     void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
     530              :     static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
     531              :         {return __c1 == __c2;}
     532              :     static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
     533              :         {return __c1 < __c2;}
     534              : 
     535              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     536              :     int              compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
     537              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     538              :     size_t           length(const char_type* __s) _NOEXCEPT;
     539              :     _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17
     540              :     const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
     541              : 
     542              :     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     543              :     static char_type*       move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     544              :         return std::__char_traits_move(__s1, __s2, __n);
     545              :     }
     546              : 
     547              :     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     548              :     static char_type*       copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
     549              :         std::copy_n(__s2, __n, __s1);
     550              :         return __s1;
     551              :     }
     552              : 
     553              :     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
     554              :     static char_type*       assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
     555              :         std::fill_n(__s, __n, __a);
     556              :         return __s;
     557              :     }
     558              : 
     559              :     static inline _LIBCPP_CONSTEXPR int_type  not_eof(int_type __c) _NOEXCEPT
     560              :         {return eq_int_type(__c, eof()) ? ~eof() : __c;}
     561              :     static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
     562              :         {return char_type(__c);}
     563              :     static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
     564              :         {return int_type(__c);}
     565              :     static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
     566              :         {return __c1 == __c2;}
     567              :     static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
     568              :         {return int_type(0xFFFFFFFF);}
     569              : };
     570              : 
     571              : inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     572              : int
     573              : char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
     574              : {
     575              :     for (; __n; --__n, ++__s1, ++__s2)
     576              :     {
     577              :         if (lt(*__s1, *__s2))
     578              :             return -1;
     579              :         if (lt(*__s2, *__s1))
     580              :             return 1;
     581              :     }
     582              :     return 0;
     583              : }
     584              : 
     585              : inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     586              : size_t
     587              : char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
     588              : {
     589              :     size_t __len = 0;
     590              :     for (; !eq(*__s, char_type(0)); ++__s)
     591              :         ++__len;
     592              :     return __len;
     593              : }
     594              : 
     595              : inline _LIBCPP_CONSTEXPR_SINCE_CXX17
     596              : const char32_t*
     597              : char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
     598              : {
     599              :     for (; __n; --__n)
     600              :     {
     601              :         if (eq(*__s, __a))
     602              :             return __s;
     603              :         ++__s;
     604              :     }
     605              :     return nullptr;
     606              : }
     607              : 
     608              : // helper fns for basic_string and string_view
     609              : 
     610              : // __str_find
     611              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     612              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     613              : __str_find(const _CharT *__p, _SizeT __sz,
     614              :              _CharT __c, _SizeT __pos) _NOEXCEPT
     615              : {
     616              :     if (__pos >= __sz)
     617              :         return __npos;
     618              :     const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
     619              :     if (__r == nullptr)
     620              :         return __npos;
     621              :     return static_cast<_SizeT>(__r - __p);
     622              : }
     623              : 
     624              : template <class _CharT, class _Traits>
     625              : _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 const _CharT *
     626        13945 : __search_substring(const _CharT *__first1, const _CharT *__last1,
     627              :                    const _CharT *__first2, const _CharT *__last2) _NOEXCEPT {
     628              :   // Take advantage of knowing source and pattern lengths.
     629              :   // Stop short when source is smaller than pattern.
     630        13945 :   const ptrdiff_t __len2 = __last2 - __first2;
     631        13945 :   if (__len2 == 0)
     632            0 :     return __first1;
     633              : 
     634        13945 :   ptrdiff_t __len1 = __last1 - __first1;
     635        13945 :   if (__len1 < __len2)
     636          686 :     return __last1;
     637              : 
     638              :   // First element of __first2 is loop invariant.
     639        13259 :   _CharT __f2 = *__first2;
     640        13263 :   while (true) {
     641        13263 :     __len1 = __last1 - __first1;
     642              :     // Check whether __first1 still has at least __len2 bytes.
     643        13263 :     if (__len1 < __len2)
     644            1 :       return __last1;
     645              : 
     646              :     // Find __f2 the first byte matching in __first1.
     647        13262 :     __first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
     648        13262 :     if (__first1 == nullptr)
     649        13208 :       return __last1;
     650              : 
     651              :     // It is faster to compare from the first byte of __first1 even if we
     652              :     // already know that it matches the first byte of __first2: this is because
     653              :     // __first2 is most likely aligned, as it is user's "pattern" string, and
     654              :     // __first1 + 1 is most likely not aligned, as the match is in the middle of
     655              :     // the string.
     656           54 :     if (_Traits::compare(__first1, __first2, __len2) == 0)
     657           50 :       return __first1;
     658              : 
     659            4 :     ++__first1;
     660              :   }
     661        13945 : }
     662              : 
     663              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     664              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     665        13945 : __str_find(const _CharT *__p, _SizeT __sz,
     666              :        const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     667              : {
     668        13945 :     if (__pos > __sz)
     669            0 :         return __npos;
     670              : 
     671        13945 :     if (__n == 0) // There is nothing to search, just return __pos.
     672            0 :         return __pos;
     673              : 
     674        13945 :     const _CharT *__r = std::__search_substring<_CharT, _Traits>(
     675        13945 :         __p + __pos, __p + __sz, __s, __s + __n);
     676              : 
     677        13945 :     if (__r == __p + __sz)
     678        13895 :         return __npos;
     679           50 :     return static_cast<_SizeT>(__r - __p);
     680        13945 : }
     681              : 
     682              : 
     683              : // __str_rfind
     684              : 
     685              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     686              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     687              : __str_rfind(const _CharT *__p, _SizeT __sz,
     688              :               _CharT __c, _SizeT __pos) _NOEXCEPT
     689              : {
     690              :     if (__sz < 1)
     691              :         return __npos;
     692              :     if (__pos < __sz)
     693              :         ++__pos;
     694              :     else
     695              :         __pos = __sz;
     696              :     for (const _CharT* __ps = __p + __pos; __ps != __p;)
     697              :     {
     698              :         if (_Traits::eq(*--__ps, __c))
     699              :             return static_cast<_SizeT>(__ps - __p);
     700              :     }
     701              :     return __npos;
     702              : }
     703              : 
     704              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     705              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     706              : __str_rfind(const _CharT *__p, _SizeT __sz,
     707              :         const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     708              : {
     709              :     __pos = _VSTD::min(__pos, __sz);
     710              :     if (__n < __sz - __pos)
     711              :         __pos += __n;
     712              :     else
     713              :         __pos = __sz;
     714              :     const _CharT* __r = std::__find_end_classic(__p, __p + __pos, __s, __s + __n, _Traits::eq);
     715              :     if (__n > 0 && __r == __p + __pos)
     716              :         return __npos;
     717              :     return static_cast<_SizeT>(__r - __p);
     718              : }
     719              : 
     720              : // __str_find_first_of
     721              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     722              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     723        12296 : __str_find_first_of(const _CharT *__p, _SizeT __sz,
     724              :                 const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     725              : {
     726        12296 :     if (__pos >= __sz || __n == 0)
     727            1 :         return __npos;
     728        12295 :     const _CharT* __r = _VSTD::__find_first_of_ce
     729        12295 :         (__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
     730        12295 :     if (__r == __p + __sz)
     731         5255 :         return __npos;
     732         7040 :     return static_cast<_SizeT>(__r - __p);
     733        12296 : }
     734              : 
     735              : 
     736              : // __str_find_last_of
     737              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     738              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     739              : __str_find_last_of(const _CharT *__p, _SizeT __sz,
     740              :                const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     741              :     {
     742              :     if (__n != 0)
     743              :     {
     744              :         if (__pos < __sz)
     745              :             ++__pos;
     746              :         else
     747              :             __pos = __sz;
     748              :         for (const _CharT* __ps = __p + __pos; __ps != __p;)
     749              :         {
     750              :             const _CharT* __r = _Traits::find(__s, __n, *--__ps);
     751              :             if (__r)
     752              :                 return static_cast<_SizeT>(__ps - __p);
     753              :         }
     754              :     }
     755              :     return __npos;
     756              : }
     757              : 
     758              : 
     759              : // __str_find_first_not_of
     760              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     761              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     762         3209 : __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
     763              :                     const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     764              : {
     765         3209 :     if (__pos < __sz)
     766              :     {
     767         3208 :         const _CharT* __pe = __p + __sz;
     768        10197 :         for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
     769        10197 :             if (_Traits::find(__s, __n, *__ps) == nullptr)
     770         3208 :                 return static_cast<_SizeT>(__ps - __p);
     771            0 :     }
     772            1 :     return __npos;
     773         3209 : }
     774              : 
     775              : 
     776              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     777              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     778              : __str_find_first_not_of(const _CharT *__p, _SizeT __sz,
     779              :                           _CharT __c, _SizeT __pos) _NOEXCEPT
     780              : {
     781              :     if (__pos < __sz)
     782              :     {
     783              :         const _CharT* __pe = __p + __sz;
     784              :         for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
     785              :             if (!_Traits::eq(*__ps, __c))
     786              :                 return static_cast<_SizeT>(__ps - __p);
     787              :     }
     788              :     return __npos;
     789              : }
     790              : 
     791              : 
     792              : // __str_find_last_not_of
     793              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     794              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     795          749 : __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
     796              :                    const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
     797              : {
     798          749 :     if (__pos < __sz)
     799            0 :         ++__pos;
     800              :     else
     801          749 :         __pos = __sz;
     802          749 :     for (const _CharT* __ps = __p + __pos; __ps != __p;)
     803          748 :         if (_Traits::find(__s, __n, *--__ps) == nullptr)
     804          748 :             return static_cast<_SizeT>(__ps - __p);
     805            1 :     return __npos;
     806          749 : }
     807              : 
     808              : 
     809              : template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
     810              : inline _SizeT _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY
     811              : __str_find_last_not_of(const _CharT *__p, _SizeT __sz,
     812              :                          _CharT __c, _SizeT __pos) _NOEXCEPT
     813              : {
     814              :     if (__pos < __sz)
     815              :         ++__pos;
     816              :     else
     817              :         __pos = __sz;
     818              :     for (const _CharT* __ps = __p + __pos; __ps != __p;)
     819              :         if (!_Traits::eq(*--__ps, __c))
     820              :             return static_cast<_SizeT>(__ps - __p);
     821              :     return __npos;
     822              : }
     823              : 
     824              : template<class _Ptr>
     825              : inline _LIBCPP_INLINE_VISIBILITY
     826              : size_t __do_string_hash(_Ptr __p, _Ptr __e)
     827              : {
     828              :     typedef typename iterator_traits<_Ptr>::value_type value_type;
     829              :     return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
     830              : }
     831              : 
     832              : _LIBCPP_END_NAMESPACE_STD
     833              : 
     834              : _LIBCPP_POP_MACROS
     835              : 
     836              : #endif // _LIBCPP___STRING_CHAR_TRAITS_H
        

Generated by: LCOV version 2.0-1