aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/cstring
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/cstring')
-rw-r--r--libcxx/include/cstring57
1 files changed, 57 insertions, 0 deletions
diff --git a/libcxx/include/cstring b/libcxx/include/cstring
index 37c92e149b8f..c88d97739f74 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -58,8 +58,18 @@ size_t strlen(const char* s);
#include <__assert> // all public C++ headers provide the assertion handler
#include <__config>
+#include <__type_traits/is_constant_evaluated.h>
+
#include <string.h>
+#ifndef _LIBCPP_STRING_H
+# error <cstring> tried including <string.h> but didn't find libc++'s <string.h> header. \
+ This usually means that your header search paths are not configured properly. \
+ The header search paths should contain the C++ Standard Library headers before \
+ any C Standard Library, and you are probably using compiler flags that make that \
+ not be the case.
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -90,6 +100,53 @@ using ::memset _LIBCPP_USING_IF_EXISTS;
using ::strerror _LIBCPP_USING_IF_EXISTS;
using ::strlen _LIBCPP_USING_IF_EXISTS;
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
+ // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
+#ifdef _LIBCPP_COMPILER_GCC
+ if (__libcpp_is_constant_evaluated()) {
+ size_t __i = 0;
+ for (; __str[__i] != '\0'; ++__i)
+ ;
+ return __i;
+ }
+#endif
+ return __builtin_strlen(__str);
+}
+
+template <class _Tp>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
+__constexpr_memcmp(const _Tp* __lhs, const _Tp* __rhs, size_t __count) {
+#ifdef _LIBCPP_COMPILER_GCC
+ if (__libcpp_is_constant_evaluated()) {
+ for (; __count; --__count, ++__lhs, ++__rhs) {
+ if (*__lhs < *__rhs)
+ return -1;
+ if (*__rhs < *__lhs)
+ return 1;
+ }
+ return 0;
+ }
+#endif
+ return __builtin_memcmp(__lhs, __rhs, __count);
+}
+
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const char*
+__constexpr_char_memchr(const char* __str, int __char, size_t __count) {
+#if __has_builtin(__builtin_char_memchr)
+ return __builtin_char_memchr(__str, __char, __count);
+#else
+ if (!__libcpp_is_constant_evaluated())
+ return static_cast<const char*>(std::memchr(__str, __char, __count));
+ for (; __count; --__count) {
+ if (*__str == __char)
+ return __str;
+ ++__str;
+ }
+ return nullptr;
+#endif
+}
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_CSTRING