[libcxx-commits] [libcxx] 355f466 - [libc++][NFC] Add __element_count and use it in the constexpr C functions
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jun 5 15:08:06 PDT 2023
Author: Nikolas Klauser
Date: 2023-06-05T15:08:01-07:00
New Revision: 355f4667446bf3ef38d3b52485b64d1a71a47507
URL: https://github.com/llvm/llvm-project/commit/355f4667446bf3ef38d3b52485b64d1a71a47507
DIFF: https://github.com/llvm/llvm-project/commit/355f4667446bf3ef38d3b52485b64d1a71a47507.diff
LOG: [libc++][NFC] Add __element_count and use it in the constexpr C functions
This makes it less ambiguous what the parameter is meant to get.
Reviewed By: #libc, ldionne
Spies: ldionne, libcxx-commits
Differential Revision: https://reviews.llvm.org/D152040
Added:
Modified:
libcxx/include/__algorithm/equal.h
libcxx/include/__string/char_traits.h
libcxx/include/__string/constexpr_c_functions.h
libcxx/test/libcxx/strings/c.strings/constexpr.cstring.compile.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index c07d4e2082c73..b69aeff92bb92 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -50,7 +50,7 @@ template <
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
__equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) {
- return std::__constexpr_memcmp_equal(__first1, __first2, (__last1 - __first1) * sizeof(_Tp));
+ return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
}
template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
@@ -100,7 +100,7 @@ template <class _Tp,
int> = 0>
_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
- return std::__constexpr_memcmp_equal(__first1, __first2, (__last1 - __first1) * sizeof(_Tp));
+ return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
}
template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2>
diff --git a/libcxx/include/__string/char_traits.h b/libcxx/include/__string/char_traits.h
index 61975ccec4f6c..5c441df98c934 100644
--- a/libcxx/include/__string/char_traits.h
+++ b/libcxx/include/__string/char_traits.h
@@ -373,7 +373,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t>
static _LIBCPP_HIDE_FROM_ABI constexpr int
compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT {
- return std::__constexpr_memcmp(__s1, __s2, __n);
+ return std::__constexpr_memcmp(__s1, __s2, __element_count(__n));
}
static _LIBCPP_HIDE_FROM_ABI constexpr
diff --git a/libcxx/include/__string/constexpr_c_functions.h b/libcxx/include/__string/constexpr_c_functions.h
index 9a768cf2db87b..13084e67ec4d6 100644
--- a/libcxx/include/__string/constexpr_c_functions.h
+++ b/libcxx/include/__string/constexpr_c_functions.h
@@ -23,6 +23,10 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+// Type used to encode that a function takes an integer that represents a number
+// of elements as opposed to a number of bytes.
+enum class __element_count : size_t {};
+
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
@@ -42,14 +46,16 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_st
// of invoking it on every object individually.
template <class _Tp, class _Up>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int
-__constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, size_t __count) {
+__constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
static_assert(__libcpp_is_trivially_lexicographically_comparable<_Tp, _Up>::value,
"_Tp and _Up have to be trivially lexicographically comparable");
+ auto __count = static_cast<size_t>(__n);
+
if (__libcpp_is_constant_evaluated()) {
#ifdef _LIBCPP_COMPILER_CLANG_BASED
if (sizeof(_Tp) == 1 && !is_same<_Tp, bool>::value)
- return __builtin_memcmp(__lhs, __rhs, __count);
+ return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp));
#endif
while (__count != 0) {
@@ -58,13 +64,13 @@ __constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, size_t __count) {
if (*__rhs < *__lhs)
return 1;
- __count -= sizeof(_Tp);
+ --__count;
++__lhs;
++__rhs;
}
return 0;
} else {
- return __builtin_memcmp(__lhs, __rhs, __count);
+ return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp));
}
}
@@ -73,26 +79,28 @@ __constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, size_t __count) {
// of invoking it on every object individually.
template <class _Tp, class _Up>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
-__constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, size_t __count) {
+__constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n) {
static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
"_Tp and _Up have to be trivially equality comparable");
+ auto __count = static_cast<size_t>(__n);
+
if (__libcpp_is_constant_evaluated()) {
#ifdef _LIBCPP_COMPILER_CLANG_BASED
if (sizeof(_Tp) == 1 && is_integral<_Tp>::value && !is_same<_Tp, bool>::value)
- return __builtin_memcmp(__lhs, __rhs, __count) == 0;
+ return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0;
#endif
while (__count != 0) {
if (*__lhs != *__rhs)
return false;
- __count -= sizeof(_Tp);
+ --__count;
++__lhs;
++__rhs;
}
return true;
} else {
- return __builtin_memcmp(__lhs, __rhs, __count) == 0;
+ return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0;
}
}
diff --git a/libcxx/test/libcxx/strings/c.strings/constexpr.cstring.compile.pass.cpp b/libcxx/test/libcxx/strings/c.strings/constexpr.cstring.compile.pass.cpp
index 9c941dd51f0ee..0739e754a61b3 100644
--- a/libcxx/test/libcxx/strings/c.strings/constexpr.cstring.compile.pass.cpp
+++ b/libcxx/test/libcxx/strings/c.strings/constexpr.cstring.compile.pass.cpp
@@ -19,12 +19,12 @@ constexpr unsigned char Banane[] = "Banane";
constexpr unsigned char Bananf[] = "Bananf";
static_assert(std::__constexpr_strlen("Banane") == 6, "");
-static_assert(std::__constexpr_memcmp(Banane, Banand, 6) == 1, "");
-static_assert(std::__constexpr_memcmp(Banane, Banane, 6) == 0, "");
-static_assert(std::__constexpr_memcmp(Banane, Bananf, 6) == -1, "");
+static_assert(std::__constexpr_memcmp(Banane, Banand, std::__element_count(6)) == 1, "");
+static_assert(std::__constexpr_memcmp(Banane, Banane, std::__element_count(6)) == 0, "");
+static_assert(std::__constexpr_memcmp(Banane, Bananf, std::__element_count(6)) == -1, "");
-static_assert(!std::__constexpr_memcmp_equal(Banane, Banand, 6), "");
-static_assert(std::__constexpr_memcmp_equal(Banane, Banane, 6), "");
+static_assert(!std::__constexpr_memcmp_equal(Banane, Banand, std::__element_count(6)), "");
+static_assert(std::__constexpr_memcmp_equal(Banane, Banane, std::__element_count(6)), "");
constexpr bool test_constexpr_wmemchr() {
More information about the libcxx-commits
mailing list