[libcxx-commits] [libcxx] Improvements to std::array<T, 0>. (PR #75546)

Ryan Nicholl via libcxx-commits libcxx-commits at lists.llvm.org
Fri Dec 15 11:18:33 PST 2023


================
@@ -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;
----------------
rnicholl-google wrote:

to be clear, you cannot then do `*myptr`, _that_ would be illegal. but I think returning this value for both `begin()` and `end()` satisfies the standard's uniqueness requirement. I therefore think the standard specified behavior is implementable (assuming we fix the very clear violation of deleted union destructors, since the standard _very clearly_ says they are not deleted if there is a member initializer)

https://github.com/llvm/llvm-project/pull/75546


More information about the libcxx-commits mailing list