1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
10 #define _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
11
12 #include <__config>
13 #include <__type_traits/is_constant_evaluated.h>
14 #include <__type_traits/is_equality_comparable.h>
15 #include <__type_traits/is_same.h>
16 #include <cstddef>
17
18 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19 # pragma GCC system_header
20 #endif
21
22 _LIBCPP_BEGIN_NAMESPACE_STD
23
__constexpr_strlen(const char * __str)24 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) {
25 // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation.
26 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816
27 #ifdef _LIBCPP_COMPILER_GCC
28 if (__libcpp_is_constant_evaluated()) {
29 size_t __i = 0;
30 for (; __str[__i] != '\0'; ++__i)
31 ;
32 return __i;
33 }
34 #endif
35 return __builtin_strlen(__str);
36 }
37
38 template <class _Tp, class _Up>
39 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
__constexpr_memcmp(const _Tp * __lhs,const _Up * __rhs,size_t __count)40 __constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, size_t __count) {
41 static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
42 "_Tp and _Up have to be trivially equality comparable");
43
44 if (__libcpp_is_constant_evaluated()) {
45 #ifdef _LIBCPP_COMPILER_CLANG_BASED
46 if (sizeof(_Tp) == 1 && !is_same<_Tp, bool>::value)
47 return __builtin_memcmp(__lhs, __rhs, __count);
48 #endif
49
50 while (__count != 0) {
51 if (*__lhs < *__rhs)
52 return -1;
53 if (*__rhs < *__lhs)
54 return 1;
55
56 __count -= sizeof(_Tp);
57 ++__lhs;
58 ++__rhs;
59 }
60 return 0;
61 } else {
62 return __builtin_memcmp(__lhs, __rhs, __count);
63 }
64 }
65
66 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const char*
__constexpr_char_memchr(const char * __str,int __char,size_t __count)67 __constexpr_char_memchr(const char* __str, int __char, size_t __count) {
68 #if __has_builtin(__builtin_char_memchr)
69 return __builtin_char_memchr(__str, __char, __count);
70 #else
71 if (!__libcpp_is_constant_evaluated())
72 return static_cast<const char*>(__builtin_memchr(__str, __char, __count));
73 for (; __count; --__count) {
74 if (*__str == __char)
75 return __str;
76 ++__str;
77 }
78 return nullptr;
79 #endif
80 }
81
82 _LIBCPP_END_NAMESPACE_STD
83
84 #endif // _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H
85