diff options
author | Ryan Prichard <rprichard@google.com> | 2024-03-12 22:44:12 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-03-12 22:44:12 +0000 |
commit | f9260c622bc6ec3d8cf95dc7ccd627131bc59bbb (patch) | |
tree | 42dd426a59782d3275e322f1a44a410820b73562 | |
parent | 0b515bc6f182c44f94958bb5895e842e6acd1fb8 (diff) | |
parent | 506a3060cf962c4696d95e331451df266e5c656d (diff) | |
download | libcxx-f9260c622bc6ec3d8cf95dc7ccd627131bc59bbb.tar.gz |
Merge "Revert "Remove std::char_traits for non-standard types"" into main am: 506a3060cf
Original change: https://android-review.googlesource.com/c/platform/external/libcxx/+/3001098
Change-Id: I0b673e94d304243fdf8db44641cdaf9b37c44c44
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | include/__string | 149 |
1 files changed, 119 insertions, 30 deletions
diff --git a/include/__string b/include/__string index b7c0767f9..1ddeec714 100644 --- a/include/__string +++ b/include/__string @@ -73,37 +73,126 @@ _LIBCPP_BEGIN_NAMESPACE_STD // char_traits template <class _CharT> -struct char_traits; -/* -The Standard does not define the base template for char_traits because it is impossible to provide -a correct definition for arbitrary character types. Instead, it requires implementations to provide -specializations for predefined character types like `char`, `wchar_t` and others. We provide this as -exposition-only to document what members a char_traits specialization should provide: -{ - using char_type = _CharT; - using int_type = ...; - using off_type = ...; - using pos_type = ...; - using state_type = ...; - - static void assign(char_type&, const char_type&); - static bool eq(char_type, char_type); - static bool lt(char_type, char_type); - - static int compare(const char_type*, const char_type*, size_t); - static size_t length(const char_type*); - static const char_type* find(const char_type*, size_t, const char_type&); - static char_type* move(char_type*, const char_type*, size_t); - static char_type* copy(char_type*, const char_type*, size_t); - static char_type* assign(char_type*, size_t, char_type); - - static int_type not_eof(int_type); - static char_type to_char_type(int_type); - static int_type to_int_type(char_type); - static bool eq_int_type(int_type, int_type); - static int_type eof(); +struct _LIBCPP_TEMPLATE_VIS char_traits +{ + typedef _CharT char_type; + typedef int int_type; + typedef streamoff off_type; + typedef streampos pos_type; + typedef mbstate_t state_type; + + static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14 + assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} + static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT + {return __c1 < __c2;} + + static _LIBCPP_CONSTEXPR_AFTER_CXX14 + int compare(const char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + size_t length(const char_type* __s); + _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14 + const char_type* find(const char_type* __s, size_t __n, const char_type& __a); + static char_type* move(char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n); + _LIBCPP_INLINE_VISIBILITY + static char_type* assign(char_type* __s, size_t __n, char_type __a); + + static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT + {return eq_int_type(__c, eof()) ? ~eof() : __c;} + static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT + {return char_type(__c);} + static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT + {return int_type(__c);} + static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT + {return __c1 == __c2;} + static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT + {return int_type(EOF);} }; -*/ + +template <class _CharT> +_LIBCPP_CONSTEXPR_AFTER_CXX14 int +char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n) +{ + for (; __n; --__n, ++__s1, ++__s2) + { + if (lt(*__s1, *__s2)) + return -1; + if (lt(*__s2, *__s1)) + return 1; + } + return 0; +} + +template <class _CharT> +inline +_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t +char_traits<_CharT>::length(const char_type* __s) +{ + size_t __len = 0; + for (; !eq(*__s, char_type(0)); ++__s) + ++__len; + return __len; +} + +template <class _CharT> +inline +_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT* +char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a) +{ + for (; __n; --__n) + { + if (eq(*__s, __a)) + return __s; + ++__s; + } + return 0; +} + +template <class _CharT> +_CharT* +char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n) +{ + char_type* __r = __s1; + if (__s1 < __s2) + { + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + } + else if (__s2 < __s1) + { + __s1 += __n; + __s2 += __n; + for (; __n; --__n) + assign(*--__s1, *--__s2); + } + return __r; +} + +template <class _CharT> +inline +_CharT* +char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n) +{ + _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); + char_type* __r = __s1; + for (; __n; --__n, ++__s1, ++__s2) + assign(*__s1, *__s2); + return __r; +} + +template <class _CharT> +inline +_CharT* +char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a) +{ + char_type* __r = __s; + for (; __n; --__n, ++__s) + assign(*__s, __a); + return __r; +} // char_traits<char> |