[libcxx-commits] [libcxx] [libc++][NFC] Merge identical char_traits functions into a base class (PR #97700)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 4 02:23:02 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/97700.diff


1 Files Affected:

- (modified) libcxx/include/__string/char_traits.h (+61-202) 


``````````diff
diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h
index 40821f86465b89..e8fa04db224ca4 100644
--- a/libcxx/include/__string/char_traits.h
+++ b/libcxx/include/__string/char_traits.h
@@ -170,105 +170,96 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char> {
   static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); }
 };
 
-// char_traits<wchar_t>
-
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-template <>
-struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> {
-  using char_type  = wchar_t;
-  using int_type   = wint_t;
+template <class _CharT, class _IntT, _IntT _EOFVal>
+struct __char_traits_base {
+  using char_type  = _CharT;
+  using int_type   = _IntT;
   using off_type   = streamoff;
-  using pos_type   = streampos;
   using state_type = mbstate_t;
-#  if _LIBCPP_STD_VER >= 20
+#if _LIBCPP_STD_VER >= 20
   using comparison_category = strong_ordering;
-#  endif
+#endif
 
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
-  assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
-    __c1 = __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
-    return __c1 == __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
-    return __c1 < __c2;
-  }
+  // There are different aliases for the different char types, but they are all aliases to this type
+  using pos_type = fpos<mbstate_t>;
 
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
-  compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    if (__n == 0)
-      return 0;
-    return std::__constexpr_wmemcmp(__s1, __s2, __n);
+  _LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 void
+  assign(char_type& __lhs, const char_type& __rhs) _NOEXCEPT {
+    __lhs = __rhs;
   }
 
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
-    return std::__constexpr_wcslen(__s);
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq(char_type __lhs, char_type __rhs) _NOEXCEPT {
+    return __lhs == __rhs;
   }
 
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
-  find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
-    if (__n == 0)
-      return nullptr;
-    return std::__constexpr_wmemchr(__s, __a, __n);
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool lt(char_type __lhs, char_type __rhs) _NOEXCEPT {
+    return __lhs < __rhs;
   }
 
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
-  move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
+  move(char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
+    return std::__constexpr_memmove(__dest, __src, __element_count(__n));
   }
 
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
-  copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
+  copy(char_type* __dest, const char_type* __src, size_t __n) _NOEXCEPT {
     _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
                                           "char_traits::copy: source and destination ranges overlap");
-    std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-    return __s1;
+    return std::__constexpr_memmove(__dest, __src, __element_count(__n));
   }
 
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
-  assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
-    std::fill_n(__s, __n, __a);
-    return __s;
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
+  assign(char_type* __str, size_t __n, char_type __fill_char) _NOEXCEPT {
+    std::fill_n(__str, __n, __fill_char);
+    return __str;
   }
 
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
-    return eq_int_type(__c, eof()) ? ~eof() : __c;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
     return char_type(__c);
   }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
-    return int_type(__c);
+
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT { return int_type(__c); }
+
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR bool eq_int_type(int_type __lhs, int_type __rhs) _NOEXCEPT {
+    return __lhs == __rhs;
   }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
-    return __c1 == __c2;
+
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return _EOFVal; }
+
+  _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
+    return eq_int_type(__c, eof()) ? ~eof() : __c;
   }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(WEOF); }
 };
-#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
 
-#ifndef _LIBCPP_HAS_NO_CHAR8_T
+// char_traits<wchar_t>
 
+#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <>
-struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> {
-  using char_type  = char8_t;
-  using int_type   = unsigned int;
-  using off_type   = streamoff;
-  using pos_type   = u8streampos;
-  using state_type = mbstate_t;
-#  if _LIBCPP_STD_VER >= 20
-  using comparison_category = strong_ordering;
-#  endif
+struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> : __char_traits_base<wchar_t, wint_t, WEOF> {
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int
+  compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
+    if (__n == 0)
+      return 0;
+    return std::__constexpr_wmemcmp(__s1, __s2, __n);
+  }
 
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr void assign(char_type& __c1, const char_type& __c2) noexcept {
-    __c1 = __c2;
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT {
+    return std::__constexpr_wcslen(__s);
   }
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq(char_type __c1, char_type __c2) noexcept {
-    return __c1 == __c2;
+
+  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const char_type*
+  find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT {
+    if (__n == 0)
+      return nullptr;
+    return std::__constexpr_wmemchr(__s, __a, __n);
   }
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr bool lt(char_type __c1, char_type __c2) noexcept { return __c1 < __c2; }
+};
+#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
+
+#ifndef _LIBCPP_HAS_NO_CHAR8_T
 
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> : __char_traits_base<char8_t, unsigned int, EOF> {
   static _LIBCPP_HIDE_FROM_ABI constexpr int
   compare(const char_type* __s1, const char_type* __s2, size_t __n) noexcept {
     return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
@@ -282,61 +273,12 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> {
   find(const char_type* __s, size_t __n, const char_type& __a) noexcept {
     return std::__constexpr_memchr(__s, __a, __n);
   }
-
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
-  move(char_type* __s1, const char_type* __s2, size_t __n) noexcept {
-    return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-  }
-
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
-  copy(char_type* __s1, const char_type* __s2, size_t __n) noexcept {
-    _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
-                                          "char_traits::copy: source and destination ranges overlap");
-    std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-    return __s1;
-  }
-
-  static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 char_type*
-  assign(char_type* __s, size_t __n, char_type __a) noexcept {
-    std::fill_n(__s, __n, __a);
-    return __s;
-  }
-
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type not_eof(int_type __c) noexcept {
-    return eq_int_type(__c, eof()) ? ~eof() : __c;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr char_type to_char_type(int_type __c) noexcept { return char_type(__c); }
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type to_int_type(char_type __c) noexcept { return int_type(__c); }
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept {
-    return __c1 == __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type eof() noexcept { return int_type(EOF); }
 };
 
 #endif // _LIBCPP_HAS_NO_CHAR8_T
 
 template <>
-struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> {
-  using char_type  = char16_t;
-  using int_type   = uint_least16_t;
-  using off_type   = streamoff;
-  using pos_type   = u16streampos;
-  using state_type = mbstate_t;
-#if _LIBCPP_STD_VER >= 20
-  using comparison_category = strong_ordering;
-#endif
-
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
-  assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
-    __c1 = __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
-    return __c1 == __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
-    return __c1 < __c2;
-  }
-
+struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> : __char_traits_base<char16_t, uint_least16_t, 0xFFFF> {
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
   compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
@@ -349,38 +291,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> {
       return nullptr;
     return __match;
   }
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
-  move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-  }
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
-  copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(!std::__is_pointer_in_range(__s1, __s1 + __n, __s2),
-                                          "char_traits::copy: source and destination ranges overlap");
-    std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-    return __s1;
-  }
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
-  assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
-    std::fill_n(__s, __n, __a);
-    return __s;
-  }
-
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
-    return eq_int_type(__c, eof()) ? ~eof() : __c;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
-    return char_type(__c);
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
-    return int_type(__c);
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
-    return __c1 == __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(0xFFFF); }
 };
 
 inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int
@@ -402,27 +312,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t char_traits<char16_t>::length(const
 }
 
 template <>
-struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> {
-  using char_type  = char32_t;
-  using int_type   = uint_least32_t;
-  using off_type   = streamoff;
-  using pos_type   = u32streampos;
-  using state_type = mbstate_t;
-#if _LIBCPP_STD_VER >= 20
-  using comparison_category = strong_ordering;
-#endif
-
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void
-  assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {
-    __c1 = __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT {
-    return __c1 == __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT {
-    return __c1 < __c2;
-  }
-
+struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> : __char_traits_base<char32_t, uint_least32_t, 0xFFFFFFFF> {
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 int
   compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT;
@@ -435,37 +325,6 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> {
       return nullptr;
     return __match;
   }
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
-  move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    return std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-  }
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
-  copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
-    std::__constexpr_memmove(__s1, __s2, __element_count(__n));
-    return __s1;
-  }
-
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static char_type*
-  assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT {
-    std::fill_n(__s, __n, __a);
-    return __s;
-  }
-
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT {
-    return eq_int_type(__c, eof()) ? ~eof() : __c;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT {
-    return char_type(__c);
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT {
-    return int_type(__c);
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT {
-    return __c1 == __c2;
-  }
-  static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(0xFFFFFFFF); }
 };
 
 inline _LIBCPP_CONSTEXPR_SINCE_CXX17 int

``````````

</details>


https://github.com/llvm/llvm-project/pull/97700


More information about the libcxx-commits mailing list