Second part of P0482 - char8_t. Reviewed as https://reviews.llvm.org/D55308
llvm-svn: 348828
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 7dad0bd68bf780b08b70c02a3b88374abfa6c152
diff --git a/include/__string b/include/__string
index 44c5598..1ddeec7 100644
--- a/include/__string
+++ b/include/__string
@@ -47,6 +47,7 @@
template <> struct char_traits<char>;
template <> struct char_traits<wchar_t>;
+template <> struct char_traits<char8_t>; // c++20
} // std
@@ -389,6 +390,102 @@
}
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+
+template <>
+struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
+{
+ typedef char8_t char_type;
+ typedef unsigned int int_type;
+ typedef streamoff off_type;
+ typedef u8streampos pos_type;
+ typedef mbstate_t state_type;
+
+ static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept
+ {__c1 = __c2;}
+ static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept
+ {return __c1 == __c2;}
+ static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept
+ {return __c1 < __c2;}
+
+ static constexpr
+ int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
+
+ static constexpr
+ size_t length(const char_type* __s) _NOEXCEPT;
+
+ _LIBCPP_INLINE_VISIBILITY static constexpr
+ const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
+
+ static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+ {return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
+
+ static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+ {
+ _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
+ return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
+ }
+
+ static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
+ {return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
+
+ static inline constexpr int_type not_eof(int_type __c) noexcept
+ {return eq_int_type(__c, eof()) ? ~eof() : __c;}
+ static inline constexpr char_type to_char_type(int_type __c) noexcept
+ {return char_type(__c);}
+ static inline constexpr int_type to_int_type(char_type __c) noexcept
+ {return int_type(__c);}
+ static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept
+ {return __c1 == __c2;}
+ static inline constexpr int_type eof() noexcept
+ {return int_type(EOF);}
+};
+
+// TODO use '__builtin_strlen' if it ever supports char8_t ??
+inline constexpr
+size_t
+char_traits<char8_t>::length(const char_type* __s) _NOEXCEPT
+{
+ size_t __len = 0;
+ for (; !eq(*__s, char_type(0)); ++__s)
+ ++__len;
+ return __len;
+}
+
+inline constexpr
+int
+char_traits<char8_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
+{
+#if __has_feature(cxx_constexpr_string_builtins)
+ return __builtin_memcmp(__s1, __s2, __n);
+#else
+ for (; __n; --__n, ++__s1, ++__s2)
+ {
+ if (lt(*__s1, *__s2))
+ return -1;
+ if (lt(*__s2, *__s1))
+ return 1;
+ }
+ return 0;
+#endif
+}
+
+// TODO use '__builtin_char_memchr' if it ever supports char8_t ??
+inline constexpr
+const char8_t*
+char_traits<char8_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
+{
+ for (; __n; --__n)
+ {
+ if (eq(*__s, __a))
+ return __s;
+ ++__s;
+ }
+ return 0;
+}
+
+#endif // #_LIBCPP_NO_HAS_CHAR8_T
+
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <>