• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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