diff --git a/libcxx/include/array b/libcxx/include/array --- a/libcxx/include/array +++ b/libcxx/include/array @@ -231,6 +231,31 @@ const value_type* data() const _NOEXCEPT {return __elems_;} }; +template::value> +union __array_storage_wrapper; + +template +union __array_storage_wrapper<_Tp, true> { + _LIBCPP_CONSTEXPR __array_storage_wrapper() : __b() { } + ~__array_storage_wrapper() = default; + + bool __b; + _Tp __t; +}; + +template +union __array_storage_wrapper<_Tp, false> { + _LIBCPP_CONSTEXPR __array_storage_wrapper() : __b() { } + ~__array_storage_wrapper() = default; + _LIBCPP_CONSTEXPR __array_storage_wrapper(__array_storage_wrapper const& __other) + : __t(__other.__t) { } + _LIBCPP_CONSTEXPR_AFTER_CXX11 __array_storage_wrapper& operator=(__array_storage_wrapper const& __other) + { __t = __other.__t; return *this; } + + bool __b; + _Tp __t; +}; + template struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> { @@ -251,13 +276,32 @@ typedef typename conditional::value, const char, char>::type _CharType; +#if _LIBCPP_STD_VER > 14 + __array_storage_wrapper<_Tp> __w; +#else struct _ArrayInStructT { _Tp __data_[1]; }; _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)]; +#endif // _LIBCPP_STD_VER > 14 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - value_type* data() _NOEXCEPT {return nullptr;} + value_type* data() _NOEXCEPT + { +#if _LIBCPP_STD_VER > 14 + return &__w.__t; +#else + return reinterpret_cast(__elems_); +#endif // _LIBCPP_STD_VER > 14 + } + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - const value_type* data() const _NOEXCEPT {return nullptr;} + const value_type* data() const _NOEXCEPT + { +#if _LIBCPP_STD_VER > 14 + return &__w.__t; +#else + return reinterpret_cast(__elems_); +#endif // _LIBCPP_STD_VER > 14 + } // No explicit construct/copy/destroy for aggregate type _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 diff --git a/libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp b/libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp @@ -49,14 +49,14 @@ typedef std::array C; C c = {}; T* p = c.data(); - (void)p; + assert(p != nullptr); } { typedef double T; typedef std::array C; C c = {{}}; const T* p = c.data(); - (void)p; + assert(p != nullptr); static_assert((std::is_same::value), ""); } { @@ -64,7 +64,7 @@ typedef std::array C; C c = {}; T* p = c.data(); - (void)p; + assert(p != nullptr); } { std::array c = {0, 1, 2, 3, 4}; @@ -92,6 +92,7 @@ typedef std::array C; const C c = {}; const T* p = c.data(); + assert(p != nullptr); std::uintptr_t pint = reinterpret_cast(p); assert(pint % TEST_ALIGNOF(T) == 0); } diff --git a/libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp b/libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp @@ -49,14 +49,14 @@ typedef std::array C; const C c = {}; const T* p = c.data(); - (void)p; + assert(p != nullptr); } { typedef NoDefault T; typedef std::array C; const C c = {}; const T* p = c.data(); - (void)p; + assert(p != nullptr); } { std::array const c = {0, 1, 2, 3, 4}; @@ -84,6 +84,7 @@ typedef std::array C; const C c = {}; const T* p = c.data(); + assert(p != nullptr); std::uintptr_t pint = reinterpret_cast(p); assert(pint % TEST_ALIGNOF(T) == 0); } diff --git a/libcxx/test/std/containers/sequences/array/iterators.pass.cpp b/libcxx/test/std/containers/sequences/array/iterators.pass.cpp --- a/libcxx/test/std/containers/sequences/array/iterators.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/iterators.pass.cpp @@ -52,6 +52,8 @@ typename C::iterator i = array.begin(); typename C::const_iterator j = array.cbegin(); assert(i == j); + assert(i != nullptr); + assert(j != nullptr); } { @@ -61,6 +63,8 @@ typename C::const_iterator j = array.cbegin(); assert(i == array.end()); assert(j == array.cend()); + assert(i != nullptr); + assert(j != nullptr); } { typedef std::array C; @@ -93,10 +97,13 @@ } { typedef std::array C; + static_assert(std::is_trivially_copyable::value, ""); C array = {}; typename C::iterator ib = array.begin(); typename C::iterator ie = array.end(); assert(ib == ie); + assert(ib != nullptr); + assert(ie != nullptr); } #if TEST_STD_VER >= 14