[libcxx-commits] [libcxx] 090b656 - [libc++] Make __has_array_cookie a variable template (#212767)
via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jul 31 04:24:10 PDT 2026
Author: Nikolas Klauser
Date: 2026-07-31T13:24:04+02:00
New Revision: 090b6569b6ed5cabfc84284542c5ce8b51735015
URL: https://github.com/llvm/llvm-project/commit/090b6569b6ed5cabfc84284542c5ce8b51735015
DIFF: https://github.com/llvm/llvm-project/commit/090b6569b6ed5cabfc84284542c5ce8b51735015.diff
LOG: [libc++] Make __has_array_cookie a variable template (#212767)
Using variable templates is slightly faster to compile and more
readable, so we might as well use them.
Added:
Modified:
libcxx/include/__memory/array_cookie.h
libcxx/include/__memory/unique_ptr.h
libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__memory/array_cookie.h b/libcxx/include/__memory/array_cookie.h
index be59f365aa80c..1869ef0244489 100644
--- a/libcxx/include/__memory/array_cookie.h
+++ b/libcxx/include/__memory/array_cookie.h
@@ -14,9 +14,7 @@
#include <__configuration/abi.h>
#include <__cstddef/size_t.h>
#include <__memory/addressof.h>
-#include <__type_traits/integral_constant.h>
#include <__type_traits/is_trivially_destructible.h>
-#include <__type_traits/negation.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -37,10 +35,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
// TODO: We should factor in the choice of the usual deallocation function in this determination:
// a cookie may be available in more cases but we ignore those for now.
template <class _Tp>
-struct __has_array_cookie : _Not<is_trivially_destructible<_Tp> > {};
+inline const bool __has_array_cookie_v = !is_trivially_destructible<_Tp>::value;
#else
template <class _Tp>
-struct __has_array_cookie : false_type {};
+inline const bool __has_array_cookie_v = false;
#endif
struct __itanium_array_cookie {
@@ -97,7 +95,7 @@ template <class _Tp>
// Avoid failures when -fsanitize-address-poison-custom-array-cookie is enabled
_LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") size_t __get_array_cookie([[__maybe_unused__]] _Tp const* __ptr) {
static_assert(
- __has_array_cookie<_Tp>::value, "Trying to access the array cookie of a type that is not guaranteed to have one");
+ __has_array_cookie_v<_Tp>, "Trying to access the array cookie of a type that is not guaranteed to have one");
#if defined(_LIBCPP_ABI_ITANIUM)
using _ArrayCookie = __itanium_array_cookie;
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 46256b8fa8805..d9155773b5f44 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -319,7 +319,7 @@ struct __unique_ptr_array_bounds_stateless {
template <class _Deleter,
class _Tp,
- __enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie<_Tp>::value, int> = 0>
+ __enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
// In constant expressions, we can't check the array cookie so we just pretend that the index
// is in-bounds. The compiler catches invalid accesses anyway.
@@ -331,7 +331,7 @@ struct __unique_ptr_array_bounds_stateless {
template <class _Deleter,
class _Tp,
- __enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie<_Tp>::value, int> = 0>
+ __enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t) const {
return true; // If we don't have an array cookie, we assume the access is in-bounds
}
@@ -349,7 +349,7 @@ struct __unique_ptr_array_bounds_stored {
// Use the array cookie if there's one
template <class _Deleter,
class _Tp,
- __enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie<_Tp>::value, int> = 0>
+ __enable_if_t<__is_default_deleter_v<_Deleter> && __has_array_cookie_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp* __ptr, size_t __index) const {
if (__libcpp_is_constant_evaluated())
return true;
@@ -360,7 +360,7 @@ struct __unique_ptr_array_bounds_stored {
// Otherwise, fall back on the stored size (if any)
template <class _Deleter,
class _Tp,
- __enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie<_Tp>::value, int> = 0>
+ __enable_if_t<!__is_default_deleter_v<_Deleter> || !__has_array_cookie_v<_Tp>, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Tp*, size_t __index) const {
return __index < __size_;
}
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp
index f7390ef5eb5d2..43c89a84663e7 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.observers/assert.subscript.pass.cpp
@@ -49,8 +49,8 @@ struct MyDeleter {
template <class WithCookie, class NoCookie>
void test() {
- LIBCPP_STATIC_ASSERT(std::__has_array_cookie<WithCookie>::value);
- LIBCPP_STATIC_ASSERT(!std::__has_array_cookie<NoCookie>::value);
+ LIBCPP_STATIC_ASSERT(std::__has_array_cookie_v<WithCookie>);
+ LIBCPP_STATIC_ASSERT(!std::__has_array_cookie_v<NoCookie>);
// For types with an array cookie, we can always detect OOB accesses. Note that reliance on an array
// cookie is limited to the default deleter, since a unique_ptr with a custom deleter may not have
More information about the libcxx-commits
mailing list