[libcxx-commits] [libcxx] Improvements to std::array<T, 0>. (PR #75546)
Ryan Nicholl via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Dec 14 16:00:56 PST 2023
https://github.com/rnicholl-google created https://github.com/llvm/llvm-project/pull/75546
It now can be used in constexpr context like std::arary<int, 0> a; a.fill(1); return a;
Also fixes begin() and end() returning nullptr when this is disallowed by the standard.
Requires llvm/llvm-project#56814 fixed first
Fixes #74375
>From 41149d7c6e110ec441b86e30a61cb02e0019a704 Mon Sep 17 00:00:00 2001
From: "Ryan P. Nicholl" <rnicholl at google.com>
Date: Thu, 14 Dec 2023 18:56:52 -0500
Subject: [PATCH] Improvements to std::array<T, 0>.
It now can be used in constexpr context like std::arary<int, 0> a; a.fill(1); return a;
Also fixes begin() and end() returning nullptr when this is disallowed by the standard.
Requires llm/llvm-project#56814 fixed first.
---
libcxx/include/array | 36 ++++++++++++++++---
.../mdspan/extents/CtorTestCombinations.h | 2 +-
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/libcxx/include/array b/libcxx/include/array
index c01d13ef358a55..4ac80eee97df51 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -263,6 +263,8 @@ struct _LIBCPP_TEMPLATE_VIS array
const value_type* data() const _NOEXCEPT {return __elems_;}
};
+struct _EmptyAggregateType {};
+
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
{
@@ -280,15 +282,41 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef __conditional_t<is_const<_Tp>::value, const char, char> _CharType;
+ typedef __conditional_t<is_const<_Tp>::value, const _EmptyAggregateType, _EmptyAggregateType> _EmptyType;
struct _ArrayInStructT { _Tp __data_[1]; };
- _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
+#if _LIBCPP_STD_VER < 17
+ _ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)];
+#else
+ union _EmptyUnion
+ {
+ _EmptyType __empty = {};
+ _Tp _FakeVal;
+ };
+
+ _ALIGNAS_TYPE(_ArrayInStructT) _EmptyUnion __elms_union = {};
+#endif
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
- value_type* data() _NOEXCEPT {return nullptr;}
+ value_type* data() _NOEXCEPT {
+#if _LIBCPP_STD_VER < 17
+ // Not required to be constexpr
+ return reinterpret_cast<value_type*>(this);
+#else
+ // Constexpr as of C++17
+ return &__elms_union._FakeVal;
+#endif
+ }
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
- const value_type* data() const _NOEXCEPT {return nullptr;}
+ const value_type* data() const _NOEXCEPT {
+#if _LIBCPP_STD_VER < 17
+ // Not required to be constexpr
+ return reinterpret_cast<value_type*>(this);
+#else
+ // Constexpr as of C++17
+ return &__elms_union._FakeVal;
+#endif
+ }
// No explicit construct/copy/destroy for aggregate type
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
diff --git a/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h b/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h
index 02731f8895ed8f..62da3e0ca0089c 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h
+++ b/libcxx/test/std/containers/views/mdspan/extents/CtorTestCombinations.h
@@ -45,7 +45,7 @@ constexpr void test_construction(AllExtents all_ext) {
// test construction from just dynamic extents
// create an array of just the extents corresponding to dynamic values
- std::array<typename AllExtents::value_type, E::rank_dynamic()> dyn_ext{0};
+ std::array<typename AllExtents::value_type, E::rank_dynamic()> dyn_ext{};
size_t dynamic_idx = 0;
for (size_t r = 0; r < E::rank(); r++) {
if (E::static_extent(r) == std::dynamic_extent) {
More information about the libcxx-commits
mailing list