summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2024-03-12 22:05:42 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-03-12 22:05:42 +0000
commit506a3060cf962c4696d95e331451df266e5c656d (patch)
tree8dc3179a8ed204a449a34dbc16dd661f4bb4ddc1
parent73f58095014650e8fe83c3701b4ebf2e62b0a223 (diff)
parentfa7cec59452e65bd77a54f3b979bf962e7612f1f (diff)
downloadlibcxx-506a3060cf962c4696d95e331451df266e5c656d.tar.gz
Merge "Revert "Remove std::char_traits for non-standard types"" into main
-rw-r--r--include/__string149
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>