From b50ffece002376943f38d03d9679c815eea5e2af Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Sat, 6 Apr 2024 21:15:43 +0200 Subject: [PATCH] [libc++][NFC] Merge identical char_traits functions into a base class --- libcxx/include/__string/char_traits.h | 263 ++++++-------------------- 1 file changed, 61 insertions(+), 202 deletions(-) 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 { static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT { return int_type(EOF); } }; -// char_traits - -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -template <> -struct _LIBCPP_TEMPLATE_VIS char_traits { - using char_type = wchar_t; - using int_type = wint_t; +template +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; - 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 +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> -struct _LIBCPP_TEMPLATE_VIS char_traits { - 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 : __char_traits_base { + 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 : __char_traits_base { 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 { 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 { - 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 : __char_traits_base { _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 { 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::length(const } template <> -struct _LIBCPP_TEMPLATE_VIS char_traits { - 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 : __char_traits_base { _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 { 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