[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:08:54 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:
I'm pretty sure getting the address isn't an "access" though. It does work in clang though, which makes this a legal solution.
My understanding is that you can get the address, then assign to it later, and that's valid/allowed. Actually, getting the address without the structure being initialized **must** be allowed, because you cannot assign to the union without taking the address of the member _first_.
https://github.com/llvm/llvm-project/pull/75546
More information about the libcxx-commits
mailing list