diff options
Diffstat (limited to 'libcxx/include/cstring')
| -rw-r--r-- | libcxx/include/cstring | 57 |
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 |
