Index: include/array =================================================================== --- include/array +++ include/array @@ -247,11 +247,13 @@ typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; - typedef typename conditional::value, const char, - char>::type _CharType; + union __wrapper { + constexpr __wrapper(): __b() {} + ~__wrapper() = default; - struct _ArrayInStructT { _Tp __data_[1]; }; - _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)]; + bool __b; + _Tp __t; + } __w; // No explicit construct/copy/destroy for aggregate type _LIBCPP_INLINE_VISIBILITY void fill(const value_type&) { @@ -266,31 +268,31 @@ } // iterators: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator begin() _NOEXCEPT {return iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator begin() const _NOEXCEPT {return const_iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 iterator end() _NOEXCEPT {return iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator end() const _NOEXCEPT {return const_iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 const_reverse_iterator crend() const _NOEXCEPT {return rend();} // capacity: @@ -302,7 +304,7 @@ _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;} // element access: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference operator[](size_type) _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::operator[] on a zero-sized array"); _LIBCPP_UNREACHABLE(); @@ -314,46 +316,46 @@ _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference at(size_type) { __throw_out_of_range("array::at"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reference at(size_type) const { __throw_out_of_range("array::at"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference front() _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::front() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reference front() const _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::front() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 reference back() _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::back() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reference back() const _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::back() on a zero-sized array"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY - value_type* data() _NOEXCEPT {return reinterpret_cast(__elems_);} - _LIBCPP_INLINE_VISIBILITY - const value_type* data() const _NOEXCEPT {return reinterpret_cast(__elems_);} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + value_type* data() _NOEXCEPT {return &__w.__t;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + const value_type* data() const _NOEXCEPT {return &__w.__t;} }; Index: test/std/containers/sequences/array/size_and_alignment.pass.cpp =================================================================== --- test/std/containers/sequences/array/size_and_alignment.pass.cpp +++ test/std/containers/sequences/array/size_and_alignment.pass.cpp @@ -20,6 +20,12 @@ #include "test_macros.h" +template +inline constexpr bool has_consexpr_members(const A& arr) { + return arr.begin() && + arr.end() && + arr.data(); +} template struct MyArray { @@ -34,12 +40,15 @@ static_assert(sizeof(ArrayT) == sizeof(CArrayT), ""); static_assert(sizeof(ArrayT) == sizeof(MyArrayT), ""); static_assert(TEST_ALIGNOF(ArrayT) == TEST_ALIGNOF(MyArrayT), ""); -#if defined(_LIBCPP_VERSION) +#if defined(_LIBCPP_VERSION) && Size > 0 ArrayT a; ((void)a); static_assert(sizeof(ArrayT) == sizeof(a.__elems_), ""); static_assert(TEST_ALIGNOF(ArrayT) == __alignof__(a.__elems_), ""); #endif +#if TEST_STD_VER > 17 + static_assert(has_consexpr_members(ArrayT { })); +#endif } template