diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -168,6 +168,8 @@ ------------------------------------------------- ----------------- **C++ 2a** ------------------------------------------------------------------- + ``__cpp_lib_array_constexpr`` ``201811L`` + ------------------------------------------------- ----------------- ``__cpp_lib_atomic_ref`` *unimplemented* ------------------------------------------------- ----------------- ``__cpp_lib_bind_front`` *unimplemented* diff --git a/libcxx/include/array b/libcxx/include/array --- a/libcxx/include/array +++ b/libcxx/include/array @@ -32,24 +32,24 @@ typedef std::reverse_iterator const_reverse_iterator; // No explicit construct/copy/destroy for aggregate type - void fill(const T& u); - void swap(array& a) noexcept(is_nothrow_swappable_v); + void fill(const T& u); // constexpr in C++20 + void swap(array& a) noexcept(is_nothrow_swappable_v); // constexpr in C++20 // iterators: - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + iterator begin() noexcept; // constexpr in C++17 + const_iterator begin() const noexcept; // constexpr in C++17 + iterator end() noexcept; // constexpr in C++17 + const_iterator end() const noexcept; // constexpr in C++17 - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + reverse_iterator rbegin() noexcept; // constexpr in C++17 + const_reverse_iterator rbegin() const noexcept; // constexpr in C++17 + reverse_iterator rend() noexcept; // constexpr in C++17 + const_reverse_iterator rend() const noexcept; // constexpr in C++17 - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + const_iterator cbegin() const noexcept; // constexpr in C++17 + const_iterator cend() const noexcept; // constexpr in C++17 + const_reverse_iterator crbegin() const noexcept; // constexpr in C++17 + const_reverse_iterator crend() const noexcept; // constexpr in C++17 // capacity: constexpr size_type size() const noexcept; @@ -57,46 +57,51 @@ constexpr bool empty() const noexcept; // element access: - reference operator[](size_type n); - const_reference operator[](size_type n) const; // constexpr in C++14 - const_reference at(size_type n) const; // constexpr in C++14 - reference at(size_type n); - - reference front(); - const_reference front() const; // constexpr in C++14 - reference back(); - const_reference back() const; // constexpr in C++14 - - T* data() noexcept; - const T* data() const noexcept; + reference operator[](size_type n); // constexpr in C++17 + const_reference operator[](size_type n) const; // constexpr in C++14 + reference at(size_type n); // constexpr in C++17 + const_reference at(size_type n) const; // constexpr in C++14 + + reference front(); // constexpr in C++17 + const_reference front() const; // constexpr in C++14 + reference back(); // constexpr in C++17 + const_reference back() const; // constexpr in C++14 + + T* data() noexcept; // constexpr in C++17 + const T* data() const noexcept; // constexpr in C++17 }; - template - array(T, U...) -> array; +template + array(T, U...) -> array; // C++17 template - bool operator==(const array& x, const array& y); + bool operator==(const array& x, const array& y); // constexpr in C++20 template - bool operator!=(const array& x, const array& y); + bool operator!=(const array& x, const array& y); // constexpr in C++20 template - bool operator<(const array& x, const array& y); + bool operator<(const array& x, const array& y); // constexpr in C++20 template - bool operator>(const array& x, const array& y); + bool operator>(const array& x, const array& y); // constexpr in C++20 template - bool operator<=(const array& x, const array& y); + bool operator<=(const array& x, const array& y); // constexpr in C++20 template - bool operator>=(const array& x, const array& y); + bool operator>=(const array& x, const array& y); // constexpr in C++20 template - void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); // C++17 + void swap(array& x, array& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20 + +template + constexpr array, N> to_array(T (&a)[N]); // C++20 +template + constexpr array, N> to_array(T (&&a)[N]); // C++20 template struct tuple_size; template struct tuple_element; template struct tuple_size>; template struct tuple_element>; -template T& get(array&) noexcept; // constexpr in C++14 -template const T& get(const array&) noexcept; // constexpr in C++14 -template T&& get(array&&) noexcept; // constexpr in C++14 +template T& get(array&) noexcept; // constexpr in C++14 +template const T& get(const array&) noexcept; // constexpr in C++14 +template T&& get(array&&) noexcept; // constexpr in C++14 template const T&& get(const array&&) noexcept; // constexpr in C++14 } // std @@ -143,11 +148,12 @@ _Tp __elems_[_Size]; // No explicit construct/copy/destroy for aggregate type - _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void fill(const value_type& __u) { _VSTD::fill_n(__elems_, _Size, __u); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { std::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_); } @@ -236,50 +242,71 @@ typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; +#ifndef _LIBCPP_CXX03_LANG + union __wrapper { + _LIBCPP_CONSTEXPR __wrapper() : __b() { } + ~__wrapper() = default; + + bool __b; + _Tp __t; + } __w; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + value_type* data() _NOEXCEPT {return &__w.__t;} + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 + const value_type* data() const _NOEXCEPT {return &__w.__t;} +#else // C++03 typedef typename conditional::value, const char, char>::type _CharType; struct _ArrayInStructT { _Tp __data_[1]; }; _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)]; + _LIBCPP_INLINE_VISIBILITY + value_type* data() _NOEXCEPT {return reinterpret_cast(__elems_);} + _LIBCPP_INLINE_VISIBILITY + const value_type* data() const _NOEXCEPT {return reinterpret_cast(__elems_);} +#endif + // No explicit construct/copy/destroy for aggregate type - _LIBCPP_INLINE_VISIBILITY void fill(const value_type&) { + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 + void fill(const value_type&) { static_assert(!is_const<_Tp>::value, "cannot fill zero-sized array of type 'const T'"); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(array&) _NOEXCEPT { static_assert(!is_const<_Tp>::value, "cannot swap zero-sized array of type 'const T'"); } // iterators: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 iterator begin() _NOEXCEPT {return iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator begin() const _NOEXCEPT {return const_iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 iterator end() _NOEXCEPT {return iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator end() const _NOEXCEPT {return const_iterator(data());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator cbegin() const _NOEXCEPT {return begin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_iterator cend() const _NOEXCEPT {return end();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 const_reverse_iterator crend() const _NOEXCEPT {return rend();} // capacity: @@ -291,7 +318,7 @@ _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;} // element access: - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator[](size_type) _NOEXCEPT { _LIBCPP_ASSERT(false, "cannot call array::operator[] on a zero-sized array"); _LIBCPP_UNREACHABLE(); @@ -303,46 +330,41 @@ _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference at(size_type) { __throw_out_of_range("array::at"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type) const { __throw_out_of_range("array::at"); _LIBCPP_UNREACHABLE(); } - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 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_CXX11 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_CXX14 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_CXX11 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_);} }; @@ -404,7 +426,7 @@ } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 typename enable_if < _Size == 0 || diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -21,7 +21,8 @@ __cpp_lib_any 201606L __cpp_lib_apply 201603L -__cpp_lib_array_constexpr 201603L +__cpp_lib_array_constexpr 201811L + 201603L // C++17 __cpp_lib_as_const 201510L __cpp_lib_atomic_is_always_lock_free 201603L __cpp_lib_atomic_ref 201806L @@ -212,6 +213,8 @@ #endif #if _LIBCPP_STD_VER > 17 +# undef __cpp_lib_array_constexpr +# define __cpp_lib_array_constexpr 201811L # if !defined(_LIBCPP_HAS_NO_THREADS) // # define __cpp_lib_atomic_ref 201806L # endif diff --git a/libcxx/test/std/containers/sequences/array/aggregate.pass.cpp b/libcxx/test/std/containers/sequences/array/aggregate.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/array/aggregate.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Make sure std::array is an aggregate type. + +#include +#include + +template +void tests() +{ + // Test aggregate initialization + { + std::array a0 = {}; (void)a0; + std::array a1 = {T()}; (void)a1; + std::array a2 = {T(), T()}; (void)a2; + std::array a3 = {T(), T(), T()}; (void)a3; + } + + // Test the is_aggregate trait. +#if TEST_STD_VER >= 17 // The trait is only available in C++17 and above + static_assert(std::is_aggregate >::value, ""); + static_assert(std::is_aggregate >::value, ""); + static_assert(std::is_aggregate >::value, ""); + static_assert(std::is_aggregate >::value, ""); + static_assert(std::is_aggregate >::value, ""); +#endif +} + +struct Empty { }; +struct NonEmpty { int i; int j; }; + +int main(int, char**) +{ + tests(); + tests(); + tests(); + tests(); + tests(); + tests(); + tests(); + tests(); + + return 0; +} diff --git a/libcxx/test/std/containers/sequences/array/array.cons/deduct.pass.cpp b/libcxx/test/std/containers/sequences/array/array.cons/deduct.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.cons/deduct.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.cons/deduct.pass.cpp @@ -30,37 +30,44 @@ #include "test_macros.h" -int main(int, char**) +constexpr bool tests() { -// Test the explicit deduction guides + // Test the explicit deduction guides { - std::array arr{1,2,3}; // array(T, U...) - static_assert(std::is_same_v>, ""); - assert(arr[0] == 1); - assert(arr[1] == 2); - assert(arr[2] == 3); + std::array arr{1,2,3}; // array(T, U...) + static_assert(std::is_same_v>, ""); + assert(arr[0] == 1); + assert(arr[1] == 2); + assert(arr[2] == 3); } { - const long l1 = 42; - std::array arr{1L, 4L, 9L, l1}; // array(T, U...) - static_assert(std::is_same_v, ""); - static_assert(arr.size() == 4, ""); - assert(arr[0] == 1); - assert(arr[1] == 4); - assert(arr[2] == 9); - assert(arr[3] == l1); + const long l1 = 42; + std::array arr{1L, 4L, 9L, l1}; // array(T, U...) + static_assert(std::is_same_v, ""); + static_assert(arr.size() == 4, ""); + assert(arr[0] == 1); + assert(arr[1] == 4); + assert(arr[2] == 9); + assert(arr[3] == l1); } -// Test the implicit deduction guides - { - std::array source = {4.0, 5.0}; - std::array arr(source); // array(array) - static_assert(std::is_same_v, ""); - static_assert(std::is_same_v>, ""); - assert(arr[0] == 4.0); - assert(arr[1] == 5.0); - } + // Test the implicit deduction guides + { + std::array source = {4.0, 5.0}; + std::array arr(source); // array(array) + static_assert(std::is_same_v, ""); + static_assert(std::is_same_v>, ""); + assert(arr[0] == 4.0); + assert(arr[1] == 5.0); + } - return 0; + return true; +} + +int main(int, char**) +{ + tests(); + static_assert(tests(), ""); + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.cons/default.pass.cpp b/libcxx/test/std/containers/sequences/array/array.cons/default.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.cons/default.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.cons/default.pass.cpp @@ -19,32 +19,43 @@ #include "disable_missing_braces_warning.h" struct NoDefault { - NoDefault(int) {} + TEST_CONSTEXPR NoDefault(int) { } }; -int main(int, char**) +struct Default { + TEST_CONSTEXPR Default() { } +}; + +TEST_CONSTEXPR_CXX14 bool tests() { { - typedef double T; - typedef std::array C; - C c; - assert(c.size() == 3); + std::array array; + assert(array.size() == 3); } + { - typedef double T; - typedef std::array C; - C c; - assert(c.size() == 0); + std::array array; + assert(array.size() == 0); } + { - typedef std::array C; - C c; - assert(c.size() == 0); - C c1 = {}; - assert(c1.size() == 0); - C c2 = {{}}; - assert(c2.size() == 0); + typedef std::array C; + C c; + assert(c.size() == 0); + C c1 = {}; + assert(c1.size() == 0); + C c2 = {{}}; + assert(c2.size() == 0); } - return 0; + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp b/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp @@ -23,72 +23,81 @@ // generated operator would be ill-formed; like in the case of a struct with a // const member. #if TEST_STD_VER < 11 -#define TEST_NOT_COPY_ASSIGNABLE(T) ((void)0) +# define TEST_NOT_COPY_ASSIGNABLE(T) ((void)0) #else -#define TEST_NOT_COPY_ASSIGNABLE(T) static_assert(!std::is_copy_assignable::value, "") +# define TEST_NOT_COPY_ASSIGNABLE(T) static_assert(!std::is_copy_assignable::value, "") #endif struct NoDefault { - NoDefault(int) {} + TEST_CONSTEXPR NoDefault(int) { } }; -int main(int, char**) { - { - typedef double T; - typedef std::array C; - C c = {1.1, 2.2, 3.3}; - C c2 = c; - c2 = c; - static_assert(std::is_copy_constructible::value, ""); - static_assert(std::is_copy_assignable::value, ""); - } - { - typedef double T; - typedef std::array C; - C c = {1.1, 2.2, 3.3}; - C c2 = c; - ((void)c2); - static_assert(std::is_copy_constructible::value, ""); - TEST_NOT_COPY_ASSIGNABLE(C); - } - { - typedef double T; - typedef std::array C; - C c = {}; - C c2 = c; - c2 = c; - static_assert(std::is_copy_constructible::value, ""); - static_assert(std::is_copy_assignable::value, ""); - } - { - // const arrays of size 0 should disable the implicit copy assignment operator. - typedef double T; - typedef std::array C; - C c = {{}}; - C c2 = c; - ((void)c2); - static_assert(std::is_copy_constructible::value, ""); - TEST_NOT_COPY_ASSIGNABLE(C); - } - { - typedef NoDefault T; - typedef std::array C; - C c = {}; - C c2 = c; - c2 = c; - static_assert(std::is_copy_constructible::value, ""); - static_assert(std::is_copy_assignable::value, ""); - } - { - typedef NoDefault T; - typedef std::array C; - C c = {{}}; - C c2 = c; - ((void)c2); - static_assert(std::is_copy_constructible::value, ""); - TEST_NOT_COPY_ASSIGNABLE(C); - } +TEST_CONSTEXPR_CXX14 bool tests() +{ + { + typedef double T; + typedef std::array C; + C c = {1.1, 2.2, 3.3}; + C c2 = c; + c2 = c; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); + } + { + typedef double T; + typedef std::array C; + C c = {1.1, 2.2, 3.3}; + C c2 = c; + ((void)c2); + static_assert(std::is_copy_constructible::value, ""); + TEST_NOT_COPY_ASSIGNABLE(C); + } + { + typedef double T; + typedef std::array C; + C c = {}; + C c2 = c; + c2 = c; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); + } + { + // const arrays of size 0 should disable the implicit copy assignment operator. + typedef double T; + typedef std::array C; + C c = {{}}; + C c2 = c; + ((void)c2); + static_assert(std::is_copy_constructible::value, ""); + TEST_NOT_COPY_ASSIGNABLE(C); + } + { + typedef NoDefault T; + typedef std::array C; + C c = {}; + C c2 = c; + c2 = c; + static_assert(std::is_copy_constructible::value, ""); + static_assert(std::is_copy_assignable::value, ""); + } + { + typedef NoDefault T; + typedef std::array C; + C c = {{}}; + C c2 = c; + ((void)c2); + static_assert(std::is_copy_constructible::value, ""); + TEST_NOT_COPY_ASSIGNABLE(C); + } + return true; +} - return 0; +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp b/libcxx/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp @@ -18,12 +18,12 @@ #include "test_macros.h" #include "disable_missing_braces_warning.h" -int main(int, char**) +TEST_CONSTEXPR_CXX14 bool tests() { { typedef double T; typedef std::array C; - C c = {1, 2, 3.5}; + C const c = {1, 2, 3.5}; assert(c.size() == 3); assert(c[0] == 1); assert(c[1] == 2); @@ -32,23 +32,32 @@ { typedef double T; typedef std::array C; - C c = {}; + C const c = {}; assert(c.size() == 0); } { typedef double T; typedef std::array C; - C c = {1}; + C const c = {1}; assert(c.size() == 3.0); assert(c[0] == 1); } { typedef int T; typedef std::array C; - C c = {}; + C const c = {}; assert(c.size() == 1); } - return 0; + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.creation/to_array.pass.cpp b/libcxx/test/std/containers/sequences/array/array.creation/to_array.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.creation/to_array.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.creation/to_array.pass.cpp @@ -23,7 +23,8 @@ #include "test_macros.h" #include "MoveOnly.h" -int main(int, char**) { +constexpr bool tests() +{ // Test deduced type. { auto arr = std::to_array({1, 2, 3}); @@ -110,13 +111,12 @@ assert(arr[0].b == .1); } - // Test constexpr. - { - constexpr std::array arr = std::to_array({1, 2, 3}); - static_assert(arr[0] == 1); - static_assert(arr[1] == 2); - static_assert(arr[2] == 3); - } + return true; +} +int main(int, char**) +{ + tests(); + static_assert(tests(), ""); return 0; } 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 @@ -21,7 +21,7 @@ #include "disable_missing_braces_warning.h" struct NoDefault { - NoDefault(int) {} + TEST_CONSTEXPR NoDefault(int) { } }; #if TEST_STD_VER < 11 @@ -33,7 +33,7 @@ }; #endif -int main(int, char**) +TEST_CONSTEXPR_CXX17 bool tests() { { typedef double T; @@ -52,33 +52,49 @@ LIBCPP_ASSERT(p != nullptr); } { - typedef double T; - typedef std::array C; - C c = {{}}; - const T* p = c.data(); - static_assert((std::is_same::value), ""); - LIBCPP_ASSERT(p != nullptr); + typedef double T; + typedef std::array C; + C c = {{}}; + const T* p = c.data(); + LIBCPP_ASSERT(p != nullptr); + static_assert((std::is_same::value), ""); } - { -#if TEST_STD_VER < 11 - typedef natural_alignment T; -#else - typedef std::max_align_t T; -#endif - typedef std::array C; - const C c = {}; - const T* p = c.data(); - LIBCPP_ASSERT(p != nullptr); - std::uintptr_t pint = reinterpret_cast(p); - assert(pint % TEST_ALIGNOF(T) == 0); + { + typedef NoDefault T; + typedef std::array C; + C c = {}; + T* p = c.data(); + LIBCPP_ASSERT(p != nullptr); } { - typedef NoDefault T; - typedef std::array C; - C c = {}; - T* p = c.data(); - LIBCPP_ASSERT(p != nullptr); + std::array c = {0, 1, 2, 3, 4}; + assert(c.data() == &c[0]); + assert(*c.data() == c[0]); } - return 0; + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 17 + static_assert(tests(), ""); +#endif + + // Test the alignment of data() + { +#if TEST_STD_VER < 11 + typedef natural_alignment T; +#else + typedef std::max_align_t T; +#endif + typedef std::array C; + const C c = {}; + const T* p = c.data(); + LIBCPP_ASSERT(p != nullptr); + std::uintptr_t pint = reinterpret_cast(p); + assert(pint % TEST_ALIGNOF(T) == 0); + } + return 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 @@ -21,7 +21,7 @@ #include "disable_missing_braces_warning.h" struct NoDefault { - NoDefault(int) {} + TEST_CONSTEXPR NoDefault(int) { } }; #if TEST_STD_VER < 11 @@ -33,7 +33,7 @@ }; #endif -int main(int, char**) +TEST_CONSTEXPR_CXX17 bool tests() { { typedef double T; @@ -49,40 +49,45 @@ typedef std::array C; const C c = {}; const T* p = c.data(); - (void)p; // to placate scan-build + LIBCPP_ASSERT(p != nullptr); + } + { + typedef NoDefault T; + typedef std::array C; + const C c = {}; + const T* p = c.data(); + LIBCPP_ASSERT(p != nullptr); } { - typedef NoDefault T; - typedef std::array C; - const C c = {}; - const T* p = c.data(); - LIBCPP_ASSERT(p != nullptr); + std::array const c = {0, 1, 2, 3, 4}; + assert(c.data() == &c[0]); + assert(*c.data() == c[0]); } + + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 17 + static_assert(tests(), ""); +#endif + + // Test the alignment of data() { #if TEST_STD_VER < 11 - typedef natural_alignment T; + typedef natural_alignment T; #else - typedef std::max_align_t T; + typedef std::max_align_t T; #endif - typedef std::array C; - const C c = {}; - const T* p = c.data(); - LIBCPP_ASSERT(p != nullptr); - std::uintptr_t pint = reinterpret_cast(p); - assert(pint % TEST_ALIGNOF(T) == 0); - } -#if TEST_STD_VER > 14 - { - typedef std::array C; - constexpr C c1{0,1,2,3,4}; - constexpr const C c2{0,1,2,3,4}; - - static_assert ( c1.data() == &c1[0], ""); - static_assert ( *c1.data() == c1[0], ""); - static_assert ( c2.data() == &c2[0], ""); - static_assert ( *c2.data() == c2[0], ""); + typedef std::array C; + const C c = {}; + const T* p = c.data(); + LIBCPP_ASSERT(p != nullptr); + std::uintptr_t pint = reinterpret_cast(p); + assert(pint % TEST_ALIGNOF(T) == 0); } -#endif - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.fill/fill.pass.cpp b/libcxx/test/std/containers/sequences/array/array.fill/fill.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.fill/fill.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.fill/fill.pass.cpp @@ -18,7 +18,7 @@ #include "test_macros.h" #include "disable_missing_braces_warning.h" -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool tests() { { typedef double T; @@ -30,6 +30,7 @@ assert(c[1] == 5.5); assert(c[2] == 5.5); } + { typedef double T; typedef std::array C; @@ -37,6 +38,14 @@ c.fill(5.5); assert(c.size() == 0); } + return true; +} - return 0; +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 20 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.size/size.pass.cpp b/libcxx/test/std/containers/sequences/array/array.size/size.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.size/size.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.size/size.pass.cpp @@ -56,5 +56,5 @@ } #endif - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.special/swap.pass.cpp b/libcxx/test/std/containers/sequences/array/array.special/swap.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.special/swap.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.special/swap.pass.cpp @@ -19,10 +19,10 @@ #include "disable_missing_braces_warning.h" struct NonSwappable { - NonSwappable() {} + TEST_CONSTEXPR NonSwappable() { } private: - NonSwappable(NonSwappable const&); - NonSwappable& operator=(NonSwappable const&); + NonSwappable(NonSwappable const&); + NonSwappable& operator=(NonSwappable const&); }; template @@ -33,9 +33,9 @@ std::false_type can_swap_imp(...); template -struct can_swap : std::is_same(0)), void> {}; +struct can_swap : std::is_same(0)), void> { }; -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool tests() { { typedef double T; @@ -82,5 +82,14 @@ } #endif - return 0; + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 20 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.swap/swap.pass.cpp b/libcxx/test/std/containers/sequences/array/array.swap/swap.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.swap/swap.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.swap/swap.pass.cpp @@ -21,13 +21,13 @@ #include "disable_missing_braces_warning.h" struct NonSwappable { - NonSwappable() {} + TEST_CONSTEXPR NonSwappable() { } private: - NonSwappable(NonSwappable const&); - NonSwappable& operator=(NonSwappable const&); + NonSwappable(NonSwappable const&); + NonSwappable& operator=(NonSwappable const&); }; -int main(int, char**) +TEST_CONSTEXPR_CXX20 bool tests() { { typedef double T; @@ -89,6 +89,14 @@ #endif } + return true; +} +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 20 + static_assert(tests(), ""); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.tuple/get.pass.cpp b/libcxx/test/std/containers/sequences/array/array.tuple/get.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.tuple/get.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.tuple/get.pass.cpp @@ -20,41 +20,57 @@ #include "disable_missing_braces_warning.h" -#if TEST_STD_VER > 11 -struct S { - std::array a; - int k; - constexpr S() : a{1,2,3}, k(std::get<2>(a)) {} -}; - -constexpr std::array getArr () { return { 3, 4 }; } -#endif +template +TEST_CONSTEXPR std::array tempArray(T ...args) +{ + return {args...}; +} -int main(int, char**) +TEST_CONSTEXPR_CXX14 bool tests() { { - typedef double T; - typedef std::array C; - C c = {1, 2, 3.5}; - std::get<1>(c) = 5.5; - assert(c[0] == 1); - assert(c[1] == 5.5); - assert(c[2] == 3.5); + std::array array = {3.3}; + assert(std::get<0>(array) == 3.3); + std::get<0>(array) = 99.1; + assert(std::get<0>(array) == 99.1); } -#if TEST_STD_VER > 11 { - typedef double T; - typedef std::array C; - constexpr C c = {1, 2, 3.5}; - static_assert(std::get<0>(c) == 1, ""); - static_assert(std::get<1>(c) == 2, ""); - static_assert(std::get<2>(c) == 3.5, ""); + std::array array = {3.3, 4.4}; + assert(std::get<0>(array) == 3.3); + assert(std::get<1>(array) == 4.4); + std::get<0>(array) = 99.1; + std::get<1>(array) = 99.2; + assert(std::get<0>(array) == 99.1); + assert(std::get<1>(array) == 99.2); } { - static_assert(S().k == 3, ""); - static_assert(std::get<1>(getArr()) == 4, ""); + std::array array = {3.3, 4.4, 5.5}; + assert(std::get<0>(array) == 3.3); + assert(std::get<1>(array) == 4.4); + assert(std::get<2>(array) == 5.5); + std::get<1>(array) = 99.2; + assert(std::get<0>(array) == 3.3); + assert(std::get<1>(array) == 99.2); + assert(std::get<2>(array) == 5.5); } -#endif + { + std::array array = {3.3}; + static_assert(std::is_same(array))>::value, ""); + } + { + assert(std::get<0>(tempArray(1, 2, 3)) == 1); + assert(std::get<1>(tempArray(1, 2, 3)) == 2); + assert(std::get<2>(tempArray(1, 2, 3)) == 3); + } + + return true; +} - return 0; +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp b/libcxx/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp @@ -19,26 +19,36 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" -int main(int, char**) +TEST_CONSTEXPR_CXX14 bool tests() { { - typedef double T; - typedef std::array C; - const C c = {1, 2, 3.5}; - assert(std::get<0>(c) == 1); - assert(std::get<1>(c) == 2); - assert(std::get<2>(c) == 3.5); + std::array const array = {3.3}; + assert(std::get<0>(array) == 3.3); } -#if TEST_STD_VER > 11 { - typedef double T; - typedef std::array C; - constexpr const C c = {1, 2, 3.5}; - static_assert(std::get<0>(c) == 1, ""); - static_assert(std::get<1>(c) == 2, ""); - static_assert(std::get<2>(c) == 3.5, ""); + std::array const array = {3.3, 4.4}; + assert(std::get<0>(array) == 3.3); + assert(std::get<1>(array) == 4.4); + } + { + std::array const array = {3.3, 4.4, 5.5}; + assert(std::get<0>(array) == 3.3); + assert(std::get<1>(array) == 4.4); + assert(std::get<2>(array) == 5.5); + } + { + std::array const array = {3.3}; + static_assert(std::is_same(array))>::value, ""); } -#endif - return 0; + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp b/libcxx/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp @@ -28,25 +28,25 @@ { { - typedef std::unique_ptr T; - typedef std::array C; - const C c = {std::unique_ptr(new double(3.5))}; - static_assert(std::is_same(std::move(c)))>::value, ""); - static_assert(noexcept(std::get<0>(std::move(c))), ""); - const T&& t = std::get<0>(std::move(c)); - assert(*t == 3.5); + typedef std::unique_ptr T; + typedef std::array C; + const C c = {std::unique_ptr(new double(3.5))}; + static_assert(std::is_same(std::move(c)))>::value, ""); + static_assert(noexcept(std::get<0>(std::move(c))), ""); + const T&& t = std::get<0>(std::move(c)); + assert(*t == 3.5); } -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 14 { - typedef double T; - typedef std::array C; - constexpr const C c = {1, 2, 3.5}; - static_assert(std::get<0>(std::move(c)) == 1, ""); - static_assert(std::get<1>(std::move(c)) == 2, ""); - static_assert(std::get<2>(std::move(c)) == 3.5, ""); + typedef double T; + typedef std::array C; + constexpr const C c = {1, 2, 3.5}; + static_assert(std::get<0>(std::move(c)) == 1, ""); + static_assert(std::get<1>(std::move(c)) == 2, ""); + static_assert(std::get<2>(std::move(c)) == 3.5, ""); } #endif - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp b/libcxx/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp --- a/libcxx/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp @@ -33,5 +33,5 @@ assert(*t == 3.5); } - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp b/libcxx/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp --- a/libcxx/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp +++ b/libcxx/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp @@ -18,7 +18,6 @@ #include #include - // std::array is explicitly allowed to be initialized with A a = { init-list };. // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" diff --git a/libcxx/test/std/containers/sequences/array/at.pass.cpp b/libcxx/test/std/containers/sequences/array/at.pass.cpp --- a/libcxx/test/std/containers/sequences/array/at.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/at.pass.cpp @@ -8,10 +8,7 @@ // -// reference operator[] (size_type) -// const_reference operator[] (size_type); // constexpr in C++14 -// reference at (size_type) -// const_reference at (size_type); // constexpr in C++14 +// reference at (size_type); // constexpr in C++17 #include #include @@ -26,100 +23,91 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" -#if TEST_STD_VER > 14 -constexpr bool check_idx( size_t idx, double val ) -{ - std::array arr = {1, 2, 3.5}; - return arr.at(idx) == val; -} -#endif -int main(int, char**) +TEST_CONSTEXPR_CXX17 bool tests() { { typedef double T; typedef std::array C; C c = {1, 2, 3.5}; - C::reference r1 = c.at(0); + typename C::reference r1 = c.at(0); assert(r1 == 1); r1 = 5.5; - assert(c.front() == 5.5); + assert(c[0] == 5.5); - C::reference r2 = c.at(2); + typename C::reference r2 = c.at(2); assert(r2 == 3.5); r2 = 7.5; - assert(c.back() == 7.5); - -#ifndef TEST_HAS_NO_EXCEPTIONS - try - { - TEST_IGNORE_NODISCARD c.at(3); - assert(false); - } - catch (const std::out_of_range &) {} -#endif + assert(c[2] == 7.5); } + return true; +} + +void test_exceptions() +{ #ifndef TEST_HAS_NO_EXCEPTIONS { - typedef double T; - typedef std::array C; - C c = {}; - C const& cc = c; - try - { - TEST_IGNORE_NODISCARD c.at(0); + std::array array = {1, 2, 3, 4}; + + try { + TEST_IGNORE_NODISCARD array.at(4); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { assert(false); } - catch (const std::out_of_range &) {} - try - { - TEST_IGNORE_NODISCARD cc.at(0); + + try { + TEST_IGNORE_NODISCARD array.at(5); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { assert(false); } - catch (const std::out_of_range &) {} - } -#endif - { - typedef double T; - typedef std::array C; - const C c = {1, 2, 3.5}; - C::const_reference r1 = c.at(0); - assert(r1 == 1); - C::const_reference r2 = c.at(2); - assert(r2 == 3.5); + try { + TEST_IGNORE_NODISCARD array.at(6); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } -#ifndef TEST_HAS_NO_EXCEPTIONS - try - { - TEST_IGNORE_NODISCARD c.at(3); + try { + TEST_IGNORE_NODISCARD array.at(-1); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { assert(false); } - catch (const std::out_of_range &) {} -#endif } -#if TEST_STD_VER > 11 { - typedef double T; - typedef std::array C; - constexpr C c = {1, 2, 3.5}; - - constexpr T t1 = c.at(0); - static_assert (t1 == 1, ""); + std::array array = {}; - constexpr T t2 = c.at(2); - static_assert (t2 == 3.5, ""); + try { + TEST_IGNORE_NODISCARD array.at(0); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } } #endif +} -#if TEST_STD_VER > 14 - { - static_assert (check_idx(0, 1), ""); - static_assert (check_idx(1, 2), ""); - static_assert (check_idx(2, 3.5), ""); - } -#endif +int main(int, char**) +{ + tests(); + test_exceptions(); - return 0; +#if TEST_STD_VER >= 17 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/at_const.pass.cpp b/libcxx/test/std/containers/sequences/array/at_const.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/array/at_const.pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// const_reference at (size_type) const; // constexpr in C++14 + +#include +#include + +#ifndef TEST_HAS_NO_EXCEPTIONS +#include +#endif + +#include "test_macros.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + + +TEST_CONSTEXPR_CXX14 bool tests() +{ + { + typedef double T; + typedef std::array C; + C const c = {1, 2, 3.5}; + typename C::const_reference r1 = c.at(0); + assert(r1 == 1); + + typename C::const_reference r2 = c.at(2); + assert(r2 == 3.5); + } + return true; +} + +void test_exceptions() +{ +#ifndef TEST_HAS_NO_EXCEPTIONS + { + std::array const array = {1, 2, 3, 4}; + + try { + TEST_IGNORE_NODISCARD array.at(4); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD array.at(5); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD array.at(6); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD array.at(-1); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } + + { + std::array array = {}; + + try { + TEST_IGNORE_NODISCARD array.at(0); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } +#endif +} + +int main(int, char**) +{ + tests(); + test_exceptions(); + +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; +} diff --git a/libcxx/test/std/containers/sequences/array/begin.pass.cpp b/libcxx/test/std/containers/sequences/array/begin.pass.cpp deleted file mode 100644 --- a/libcxx/test/std/containers/sequences/array/begin.pass.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// - -// iterator begin(); - -#include -#include - -#include "test_macros.h" - -// std::array is explicitly allowed to be initialized with A a = { init-list };. -// Disable the missing braces warning for this reason. -#include "disable_missing_braces_warning.h" - -struct NoDefault { - NoDefault(int) {} -}; - - -int main(int, char**) -{ - { - typedef double T; - typedef std::array C; - C c = {1, 2, 3.5}; - C::iterator i; - i = c.begin(); - assert(*i == 1); - assert(&*i == c.data()); - *i = 5.5; - assert(c[0] == 5.5); - } - { - typedef NoDefault T; - typedef std::array C; - C c = {}; - C::iterator ib, ie; - ib = c.begin(); - ie = c.end(); - assert(ib == ie); - LIBCPP_ASSERT(ib != nullptr); - LIBCPP_ASSERT(ie != nullptr); - } - - return 0; -} diff --git a/libcxx/test/std/containers/sequences/array/compare.pass.cpp b/libcxx/test/std/containers/sequences/array/compare.pass.cpp --- a/libcxx/test/std/containers/sequences/array/compare.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/compare.pass.cpp @@ -8,17 +8,15 @@ // -// These are all constexpr in C++20 -// bool operator==(array const&, array const&); -// bool operator!=(array const&, array const&); -// bool operator<(array const&, array const&); -// bool operator<=(array const&, array const&); -// bool operator>(array const&, array const&); -// bool operator>=(array const&, array const&); +// bool operator==(array const&, array const&); // constexpr in C++20 +// bool operator!=(array const&, array const&); // constexpr in C++20 +// bool operator<(array const&, array const&); // constexpr in C++20 +// bool operator<=(array const&, array const&); // constexpr in C++20 +// bool operator>(array const&, array const&); // constexpr in C++20 +// bool operator>=(array const&, array const&); // constexpr in C++20 #include -#include #include #include "test_macros.h" @@ -28,36 +26,33 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" +TEST_CONSTEXPR_CXX20 bool tests() +{ + { + typedef std::array C; + C c1 = {1, 2, 3}; + C c2 = {1, 2, 3}; + C c3 = {3, 2, 1}; + C c4 = {1, 2, 1}; + assert(testComparisons6(c1, c2, true, false)); + assert(testComparisons6(c1, c3, false, true)); + assert(testComparisons6(c1, c4, false, false)); + } + { + typedef std::array C; + C c1 = {}; + C c2 = {}; + assert(testComparisons6(c1, c2, true, false)); + } + + return true; +} + int main(int, char**) { - { - typedef int T; - typedef std::array C; - C c1 = {1, 2, 3}; - C c2 = {1, 2, 3}; - C c3 = {3, 2, 1}; - C c4 = {1, 2, 1}; - assert(testComparisons6(c1, c2, true, false)); - assert(testComparisons6(c1, c3, false, true)); - assert(testComparisons6(c1, c4, false, false)); - } - { - typedef int T; - typedef std::array C; - C c1 = {}; - C c2 = {}; - assert(testComparisons6(c1, c2, true, false)); - } - -#if TEST_STD_VER > 17 - { - constexpr std::array a1 = {1, 2, 3}; - constexpr std::array a2 = {2, 3, 4}; - static_assert(testComparisons6(a1, a1, true, false), ""); - static_assert(testComparisons6(a1, a2, false, true), ""); - static_assert(testComparisons6(a2, a1, false, false), ""); - } + tests(); +#if TEST_STD_VER >= 20 + static_assert(tests(), ""); #endif - - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp b/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp --- a/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/contiguous.pass.cpp @@ -15,20 +15,33 @@ #include "test_macros.h" -template -void test_contiguous ( const C &c ) +template +TEST_CONSTEXPR_CXX14 void assert_contiguous(Container const& c) { - for ( size_t i = 0; i < c.size(); ++i ) - assert ( *(c.begin() + i) == *(std::addressof(*c.begin()) + i)); + for (size_t i = 0; i < c.size(); ++i) + assert(*(c.begin() + i) == *(std::addressof(*c.begin()) + i)); } -int main(int, char**) +TEST_CONSTEXPR_CXX17 bool tests() { - { - typedef double T; - typedef std::array C; - test_contiguous (C()); - } + assert_contiguous(std::array()); + assert_contiguous(std::array()); + assert_contiguous(std::array()); + assert_contiguous(std::array()); + + assert_contiguous(std::array()); + assert_contiguous(std::array()); + assert_contiguous(std::array()); + assert_contiguous(std::array()); + + return true; +} - return 0; +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 17 // begin() & friends are constexpr in >= C++17 only + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/empty.pass.cpp b/libcxx/test/std/containers/sequences/array/empty.pass.cpp --- a/libcxx/test/std/containers/sequences/array/empty.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/empty.pass.cpp @@ -10,28 +10,45 @@ // class array -// bool empty() const noexcept; +// constexpr bool empty() const noexcept; #include #include #include "test_macros.h" -#include "min_allocator.h" -int main(int, char**) +TEST_CONSTEXPR_CXX14 bool tests() { { - typedef std::array C; - C c; - ASSERT_NOEXCEPT(c.empty()); - assert(!c.empty()); + typedef std::array C; + C c = {}; + ASSERT_NOEXCEPT(c.empty()); + assert(!c.empty()); + } + { + typedef std::array C; + C c = {}; + ASSERT_NOEXCEPT(c.empty()); + assert(c.empty()); } + + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + +#if TEST_STD_VER >= 11 + // Sanity check for constexpr in C++11 { - typedef std::array C; - C c; - ASSERT_NOEXCEPT(c.empty()); - assert( c.empty()); + constexpr std::array array = {}; + static_assert(!array.empty(), ""); } +#endif - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/front_back.pass.cpp b/libcxx/test/std/containers/sequences/array/front_back.pass.cpp --- a/libcxx/test/std/containers/sequences/array/front_back.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/front_back.pass.cpp @@ -8,10 +8,8 @@ // -// reference front(); // constexpr in C++17 -// reference back(); // constexpr in C++17 -// const_reference front(); // constexpr in C++14 -// const_reference back(); // constexpr in C++14 +// reference front(); // constexpr in C++17 +// reference back(); // constexpr in C++17 #include #include @@ -22,21 +20,8 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" -#if TEST_STD_VER > 14 -constexpr bool check_front( double val ) -{ - std::array arr = {1, 2, 3.5}; - return arr.front() == val; -} -constexpr bool check_back( double val ) -{ - std::array arr = {1, 2, 3.5}; - return arr.back() == val; -} -#endif - -int main(int, char**) +TEST_CONSTEXPR_CXX17 bool tests() { { typedef double T; @@ -55,74 +40,39 @@ } { typedef double T; - typedef std::array C; - const C c = {1, 2, 3.5}; - C::const_reference r1 = c.front(); - assert(r1 == 1); - - C::const_reference r2 = c.back(); - assert(r2 == 3.5); - } - { - typedef double T; - typedef std::array C; - C c = {}; - C const& cc = c; - ASSERT_SAME_TYPE(decltype( c.back()), typename C::reference); - ASSERT_SAME_TYPE(decltype(cc.back()), typename C::const_reference); - LIBCPP_ASSERT_NOEXCEPT( c.back()); - LIBCPP_ASSERT_NOEXCEPT( cc.back()); - ASSERT_SAME_TYPE(decltype( c.front()), typename C::reference); - ASSERT_SAME_TYPE(decltype(cc.front()), typename C::const_reference); - LIBCPP_ASSERT_NOEXCEPT( c.front()); - LIBCPP_ASSERT_NOEXCEPT( cc.front()); - if (c.size() > (0)) { // always false - TEST_IGNORE_NODISCARD c.front(); - TEST_IGNORE_NODISCARD c.back(); - TEST_IGNORE_NODISCARD cc.front(); - TEST_IGNORE_NODISCARD cc.back(); - } + typedef std::array C; + C c = {}; + ASSERT_SAME_TYPE(decltype(c.back()), C::reference); + LIBCPP_ASSERT_NOEXCEPT(c.back()); + ASSERT_SAME_TYPE(decltype(c.front()), C::reference); + LIBCPP_ASSERT_NOEXCEPT(c.front()); + if (c.size() > (0)) { // always false + TEST_IGNORE_NODISCARD c.front(); + TEST_IGNORE_NODISCARD c.back(); + } } { - typedef double T; - typedef std::array C; - C c = {{}}; - C const& cc = c; - ASSERT_SAME_TYPE(decltype( c.back()), typename C::reference); - ASSERT_SAME_TYPE(decltype(cc.back()), typename C::const_reference); - LIBCPP_ASSERT_NOEXCEPT( c.back()); - LIBCPP_ASSERT_NOEXCEPT( cc.back()); - ASSERT_SAME_TYPE(decltype( c.front()), typename C::reference); - ASSERT_SAME_TYPE(decltype(cc.front()), typename C::const_reference); - LIBCPP_ASSERT_NOEXCEPT( c.front()); - LIBCPP_ASSERT_NOEXCEPT( cc.front()); - if (c.size() > (0)) { - TEST_IGNORE_NODISCARD c.front(); - TEST_IGNORE_NODISCARD c.back(); - TEST_IGNORE_NODISCARD cc.front(); - TEST_IGNORE_NODISCARD cc.back(); - } - } -#if TEST_STD_VER > 11 - { typedef double T; - typedef std::array C; - constexpr C c = {1, 2, 3.5}; - - constexpr T t1 = c.front(); - static_assert (t1 == 1, ""); - - constexpr T t2 = c.back(); - static_assert (t2 == 3.5, ""); + typedef std::array C; + C c = {}; + ASSERT_SAME_TYPE(decltype( c.back()), C::reference); + LIBCPP_ASSERT_NOEXCEPT( c.back()); + ASSERT_SAME_TYPE(decltype( c.front()), C::reference); + LIBCPP_ASSERT_NOEXCEPT( c.front()); + if (c.size() > (0)) { + TEST_IGNORE_NODISCARD c.front(); + TEST_IGNORE_NODISCARD c.back(); + } } -#endif -#if TEST_STD_VER > 14 - { - static_assert (check_front(1), ""); - static_assert (check_back (3.5), ""); - } -#endif + return true; +} - return 0; +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 17 + static_assert(tests(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/front_back_const.pass.cpp b/libcxx/test/std/containers/sequences/array/front_back_const.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/array/front_back_const.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// const_reference front() const; // constexpr in C++14 +// const_reference back() const; // constexpr in C++14 + +#include +#include + +#include "test_macros.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + + +TEST_CONSTEXPR_CXX14 bool tests() +{ + { + typedef double T; + typedef std::array C; + C const c = {1, 2, 3.5}; + C::const_reference r1 = c.front(); + assert(r1 == 1); + + C::const_reference r2 = c.back(); + assert(r2 == 3.5); + } + { + typedef double T; + typedef std::array C; + C const c = {}; + ASSERT_SAME_TYPE(decltype(c.back()), C::const_reference); + LIBCPP_ASSERT_NOEXCEPT(c.back()); + ASSERT_SAME_TYPE(decltype(c.front()), C::const_reference); + LIBCPP_ASSERT_NOEXCEPT(c.front()); + if (c.size() > (0)) { // always false + TEST_IGNORE_NODISCARD c.front(); + TEST_IGNORE_NODISCARD c.back(); + } + } + { + typedef double T; + typedef std::array C; + C const c = {}; + ASSERT_SAME_TYPE(decltype(c.back()), C::const_reference); + LIBCPP_ASSERT_NOEXCEPT(c.back()); + ASSERT_SAME_TYPE(decltype(c.front()), C::const_reference); + LIBCPP_ASSERT_NOEXCEPT(c.front()); + if (c.size() > (0)) { + TEST_IGNORE_NODISCARD c.front(); + TEST_IGNORE_NODISCARD c.back(); + } + } + + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 0; +} diff --git a/libcxx/test/std/containers/sequences/array/indexing.pass.cpp b/libcxx/test/std/containers/sequences/array/indexing.pass.cpp --- a/libcxx/test/std/containers/sequences/array/indexing.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/indexing.pass.cpp @@ -8,11 +8,8 @@ // -// reference operator[] (size_type) -// const_reference operator[] (size_type); // constexpr in C++14 -// reference at (size_type) -// const_reference at (size_type); // constexpr in C++14 -// Libc++ marks these as noexcept +// reference operator[](size_type); // constexpr in C++17 +// Libc++ marks it as noexcept #include #include @@ -23,15 +20,8 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" -#if TEST_STD_VER > 14 -constexpr bool check_idx( size_t idx, double val ) -{ - std::array arr = {1, 2, 3.5}; - return arr[idx] == val; -} -#endif -int main(int, char**) +TEST_CONSTEXPR_CXX17 bool tests() { { typedef double T; @@ -49,72 +39,41 @@ r2 = 7.5; assert(c.back() == 7.5); } + + // Test operator[] "works" on zero sized arrays { - typedef double T; - typedef std::array C; - const C c = {1, 2, 3.5}; - LIBCPP_ASSERT_NOEXCEPT(c[0]); - ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); - C::const_reference r1 = c[0]; - assert(r1 == 1); - C::const_reference r2 = c[2]; - assert(r2 == 3.5); - } - { // Test operator[] "works" on zero sized arrays - typedef double T; - typedef std::array C; - C c = {}; - C const& cc = c; - LIBCPP_ASSERT_NOEXCEPT(c[0]); - LIBCPP_ASSERT_NOEXCEPT(cc[0]); - ASSERT_SAME_TYPE(C::reference, decltype(c[0])); - ASSERT_SAME_TYPE(C::const_reference, decltype(cc[0])); - if (c.size() > (0)) { // always false - C::reference r1 = c[0]; - C::const_reference r2 = cc[0]; - ((void)r1); - ((void)r2); + { + typedef double T; + typedef std::array C; + C c = {}; + LIBCPP_ASSERT_NOEXCEPT(c[0]); + ASSERT_SAME_TYPE(C::reference, decltype(c[0])); + if (c.size() > (0)) { // always false + C::reference r = c[0]; + (void)r; + } } - } - { // Test operator[] "works" on zero sized arrays - typedef double T; - typedef std::array C; - C c = {{}}; - C const& cc = c; - LIBCPP_ASSERT_NOEXCEPT(c[0]); - LIBCPP_ASSERT_NOEXCEPT(cc[0]); - ASSERT_SAME_TYPE(C::reference, decltype(c[0])); - ASSERT_SAME_TYPE(C::const_reference, decltype(cc[0])); - if (c.size() > (0)) { // always false - C::reference r1 = c[0]; - C::const_reference r2 = cc[0]; - ((void)r1); - ((void)r2); + { + typedef double T; + typedef std::array C; + C c = {}; + LIBCPP_ASSERT_NOEXCEPT(c[0]); + ASSERT_SAME_TYPE(C::reference, decltype(c[0])); + if (c.size() > (0)) { // always false + C::reference r = c[0]; + (void)r; + } } } -#if TEST_STD_VER > 11 - { - typedef double T; - typedef std::array C; - constexpr C c = {1, 2, 3.5}; - LIBCPP_ASSERT_NOEXCEPT(c[0]); - ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); - constexpr T t1 = c[0]; - static_assert (t1 == 1, ""); - - constexpr T t2 = c[2]; - static_assert (t2 == 3.5, ""); - } -#endif + return true; +} -#if TEST_STD_VER > 14 - { - static_assert (check_idx(0, 1), ""); - static_assert (check_idx(1, 2), ""); - static_assert (check_idx(2, 3.5), ""); - } +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 17 + static_assert(tests(), ""); #endif - - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/indexing_const.pass.cpp b/libcxx/test/std/containers/sequences/array/indexing_const.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/array/indexing_const.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// const_reference operator[](size_type) const; // constexpr in C++14 +// Libc++ marks it as noexcept + +#include +#include + +#include "test_macros.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + + +TEST_CONSTEXPR_CXX14 bool tests() +{ + { + typedef double T; + typedef std::array C; + C const c = {1, 2, 3.5}; + LIBCPP_ASSERT_NOEXCEPT(c[0]); + ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); + C::const_reference r1 = c[0]; + assert(r1 == 1); + C::const_reference r2 = c[2]; + assert(r2 == 3.5); + } + // Test operator[] "works" on zero sized arrays + { + { + typedef double T; + typedef std::array C; + C const c = {}; + LIBCPP_ASSERT_NOEXCEPT(c[0]); + ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); + if (c.size() > (0)) { // always false + C::const_reference r = c[0]; + (void)r; + } + } + { + typedef double T; + typedef std::array C; + C const c = {}; + LIBCPP_ASSERT_NOEXCEPT(c[0]); + ASSERT_SAME_TYPE(C::const_reference, decltype(c[0])); + if (c.size() > (0)) { // always false + C::const_reference r = c[0]; + (void)r; + } + } + } + + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + return 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 @@ -8,7 +8,20 @@ // -// iterator, const_iterator +// iterator begin() noexcept; // constexpr in C++17 +// const_iterator begin() const noexcept; // constexpr in C++17 +// iterator end() noexcept; // constexpr in C++17 +// const_iterator end() const noexcept; // constexpr in C++17 +// +// reverse_iterator rbegin() noexcept; // constexpr in C++17 +// const_reverse_iterator rbegin() const noexcept; // constexpr in C++17 +// reverse_iterator rend() noexcept; // constexpr in C++17 +// const_reverse_iterator rend() const noexcept; // constexpr in C++17 +// +// const_iterator cbegin() const noexcept; // constexpr in C++17 +// const_iterator cend() const noexcept; // constexpr in C++17 +// const_reverse_iterator crbegin() const noexcept; // constexpr in C++17 +// const_reverse_iterator crend() const noexcept; // constexpr in C++17 #include #include @@ -20,127 +33,157 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" -int main(int, char**) +struct NoDefault { + TEST_CONSTEXPR NoDefault(int) { } +}; + +TEST_CONSTEXPR_CXX17 bool tests() { { - typedef std::array C; - C c; - C::iterator i; - i = c.begin(); - C::const_iterator j; - j = c.cbegin(); - assert(i == j); + typedef std::array C; + C array = {}; + typename C::iterator i = array.begin(); + typename C::const_iterator j = array.cbegin(); + assert(i == j); + } + { + typedef std::array C; + C array = {}; + typename C::iterator i = array.begin(); + typename C::const_iterator j = array.cbegin(); + assert(i == j); + LIBCPP_ASSERT(i != nullptr); + LIBCPP_ASSERT(j != nullptr); + } + + { + typedef std::array C; + C array = {}; + typename C::iterator i = array.begin(); + typename C::const_iterator j = array.cbegin(); + assert(i == array.end()); + assert(j == array.cend()); + LIBCPP_ASSERT(i != nullptr); + LIBCPP_ASSERT(j != nullptr); + } + { + typedef std::array C; + C array = {1}; + typename C::iterator i = array.begin(); + assert(*i == 1); + assert(&*i == array.data()); + *i = 99; + assert(array[0] == 99); } { - typedef std::array C; - C c; - C::iterator i; - i = c.begin(); - C::const_iterator j; - j = c.cbegin(); - assert(i == j); + typedef std::array C; + C array = {1, 2}; + typename C::iterator i = array.begin(); + assert(*i == 1); + assert(&*i == array.data()); + *i = 99; + assert(array[0] == 99); + assert(array[1] == 2); + } + { + typedef std::array C; + C array = {1, 2, 3.5}; + typename C::iterator i = array.begin(); + assert(*i == 1); + assert(&*i == array.data()); + *i = 5.5; + assert(array[0] == 5.5); + assert(array[1] == 2.0); + } + { + typedef std::array C; + C array = {}; + typename C::iterator ib = array.begin(); + typename C::iterator ie = array.end(); + assert(ib == ie); + LIBCPP_ASSERT(ib != nullptr); + LIBCPP_ASSERT(ie != nullptr); } -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 14 { // N3644 testing { - typedef std::array C; - C::iterator ii1{}, ii2{}; - C::iterator ii4 = ii1; - C::const_iterator cii{}; - assert ( ii1 == ii2 ); - assert ( ii1 == ii4 ); - assert ( ii1 == cii ); - - assert ( !(ii1 != ii2 )); - assert ( !(ii1 != cii )); - - C c; - assert ( c.begin() == std::begin(c)); - assert ( c.cbegin() == std::cbegin(c)); - assert ( c.rbegin() == std::rbegin(c)); - assert ( c.crbegin() == std::crbegin(c)); - assert ( c.end() == std::end(c)); - assert ( c.cend() == std::cend(c)); - assert ( c.rend() == std::rend(c)); - assert ( c.crend() == std::crend(c)); - - assert ( std::begin(c) != std::end(c)); - assert ( std::rbegin(c) != std::rend(c)); - assert ( std::cbegin(c) != std::cend(c)); - assert ( std::crbegin(c) != std::crend(c)); + typedef std::array C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert(ii1 == ii2); + assert(ii1 == ii4); + assert(ii1 == cii); + + assert(!(ii1 != ii2)); + assert(!(ii1 != cii)); + + C c = {}; + assert(c.begin() == std::begin(c)); + assert(c.cbegin() == std::cbegin(c)); + assert(c.rbegin() == std::rbegin(c)); + assert(c.crbegin() == std::crbegin(c)); + assert(c.end() == std::end(c)); + assert(c.cend() == std::cend(c)); + assert(c.rend() == std::rend(c)); + assert(c.crend() == std::crend(c)); + + assert(std::begin(c) != std::end(c)); + assert(std::rbegin(c) != std::rend(c)); + assert(std::cbegin(c) != std::cend(c)); + assert(std::crbegin(c) != std::crend(c)); } { - typedef std::array C; - C::iterator ii1{}, ii2{}; - C::iterator ii4 = ii1; - C::const_iterator cii{}; - assert ( ii1 == ii2 ); - assert ( ii1 == ii4 ); - - assert (!(ii1 != ii2 )); - - assert ( (ii1 == cii )); - assert ( (cii == ii1 )); - assert (!(ii1 != cii )); - assert (!(cii != ii1 )); - assert (!(ii1 < cii )); - assert (!(cii < ii1 )); - assert ( (ii1 <= cii )); - assert ( (cii <= ii1 )); - assert (!(ii1 > cii )); - assert (!(cii > ii1 )); - assert ( (ii1 >= cii )); - assert ( (cii >= ii1 )); - assert (cii - ii1 == 0); - assert (ii1 - cii == 0); - - C c; - assert ( c.begin() == std::begin(c)); - assert ( c.cbegin() == std::cbegin(c)); - assert ( c.rbegin() == std::rbegin(c)); - assert ( c.crbegin() == std::crbegin(c)); - assert ( c.end() == std::end(c)); - assert ( c.cend() == std::cend(c)); - assert ( c.rend() == std::rend(c)); - assert ( c.crend() == std::crend(c)); - - assert ( std::begin(c) == std::end(c)); - assert ( std::rbegin(c) == std::rend(c)); - assert ( std::cbegin(c) == std::cend(c)); - assert ( std::crbegin(c) == std::crend(c)); + typedef std::array C; + C::iterator ii1{}, ii2{}; + C::iterator ii4 = ii1; + C::const_iterator cii{}; + assert(ii1 == ii2); + assert(ii1 == ii4); + + assert(!(ii1 != ii2)); + + assert( (ii1 == cii)); + assert( (cii == ii1)); + assert(!(ii1 != cii)); + assert(!(cii != ii1)); + assert(!(ii1 < cii)); + assert(!(cii < ii1)); + assert( (ii1 <= cii)); + assert( (cii <= ii1)); + assert(!(ii1 > cii)); + assert(!(cii > ii1)); + assert( (ii1 >= cii)); + assert( (cii >= ii1)); + assert(cii - ii1 == 0); + assert(ii1 - cii == 0); + + C c = {}; + assert(c.begin() == std::begin(c)); + assert(c.cbegin() == std::cbegin(c)); + assert(c.rbegin() == std::rbegin(c)); + assert(c.crbegin() == std::crbegin(c)); + assert(c.end() == std::end(c)); + assert(c.cend() == std::cend(c)); + assert(c.rend() == std::rend(c)); + assert(c.crend() == std::crend(c)); + + assert(std::begin(c) == std::end(c)); + assert(std::rbegin(c) == std::rend(c)); + assert(std::cbegin(c) == std::cend(c)); + assert(std::crbegin(c) == std::crend(c)); } } #endif -#if TEST_STD_VER > 14 - { - typedef std::array C; - constexpr C c{0,1,2,3,4}; - - static_assert ( c.begin() == std::begin(c), ""); - static_assert ( c.cbegin() == std::cbegin(c), ""); - static_assert ( c.end() == std::end(c), ""); - static_assert ( c.cend() == std::cend(c), ""); - - static_assert ( c.rbegin() == std::rbegin(c), ""); - static_assert ( c.crbegin() == std::crbegin(c), ""); - static_assert ( c.rend() == std::rend(c), ""); - static_assert ( c.crend() == std::crend(c), ""); - - static_assert ( std::begin(c) != std::end(c), ""); - static_assert ( std::rbegin(c) != std::rend(c), ""); - static_assert ( std::cbegin(c) != std::cend(c), ""); - static_assert ( std::crbegin(c) != std::crend(c), ""); - - static_assert ( *c.begin() == 0, ""); - static_assert ( *c.rbegin() == 4, ""); - - static_assert ( *std::begin(c) == 0, "" ); - static_assert ( *std::cbegin(c) == 0, "" ); - static_assert ( *std::rbegin(c) == 4, "" ); - static_assert ( *std::crbegin(c) == 4, "" ); - } -#endif + return true; +} +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 17 + static_assert(tests(), ""); +#endif return 0; } diff --git a/libcxx/test/std/containers/sequences/array/max_size.pass.cpp b/libcxx/test/std/containers/sequences/array/max_size.pass.cpp --- a/libcxx/test/std/containers/sequences/array/max_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/max_size.pass.cpp @@ -10,28 +10,45 @@ // class array -// bool max_size() const noexcept; +// constexpr bool max_size() const noexcept; #include #include #include "test_macros.h" -#include "min_allocator.h" -int main(int, char**) +TEST_CONSTEXPR_CXX14 bool tests() { { - typedef std::array C; - C c; - ASSERT_NOEXCEPT(c.max_size()); - assert(c.max_size() == 2); + typedef std::array C; + C c = {}; + ASSERT_NOEXCEPT(c.max_size()); + assert(c.max_size() == 2); + } + { + typedef std::array C; + C c = {}; + ASSERT_NOEXCEPT(c.max_size()); + assert(c.max_size() == 0); } + + return true; +} + +int main(int, char**) +{ + tests(); +#if TEST_STD_VER >= 14 + static_assert(tests(), ""); +#endif + +#if TEST_STD_VER >= 11 + // Sanity check for constexpr in C++11 { - typedef std::array C; - C c; - ASSERT_NOEXCEPT(c.max_size()); - assert(c.max_size() == 0); + constexpr std::array array = {}; + static_assert(array.max_size() == 3, ""); } +#endif - return 0; + return 0; } diff --git a/libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp b/libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp --- a/libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp +++ b/libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp @@ -34,12 +34,6 @@ static_assert(sizeof(ArrayT) == sizeof(CArrayT), ""); static_assert(sizeof(ArrayT) == sizeof(MyArrayT), ""); static_assert(TEST_ALIGNOF(ArrayT) == TEST_ALIGNOF(MyArrayT), ""); -#if defined(_LIBCPP_VERSION) - ArrayT a; - ((void)a); - static_assert(sizeof(ArrayT) == sizeof(a.__elems_), ""); - static_assert(TEST_ALIGNOF(ArrayT) == __alignof__(a.__elems_), ""); -#endif } template @@ -67,8 +61,6 @@ }; #endif -//static_assert(sizeof(void*) == 4, ""); - int main(int, char**) { test_type(); test_type(); diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp @@ -15,6 +15,7 @@ /* Constant Value __cpp_lib_array_constexpr 201603L [C++17] + 201811L [C++2a] __cpp_lib_constexpr_misc 201811L [C++2a] __cpp_lib_nonmember_container_access 201411L [C++17] __cpp_lib_to_array 201907L [C++2a] @@ -88,8 +89,8 @@ # ifndef __cpp_lib_array_constexpr # error "__cpp_lib_array_constexpr should be defined in c++2a" # endif -# if __cpp_lib_array_constexpr != 201603L -# error "__cpp_lib_array_constexpr should have the value 201603L in c++2a" +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++2a" # endif # if !defined(_LIBCPP_VERSION) diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp @@ -15,6 +15,7 @@ /* Constant Value __cpp_lib_array_constexpr 201603L [C++17] + 201811L [C++2a] __cpp_lib_constexpr_misc 201811L [C++2a] __cpp_lib_make_reverse_iterator 201402L [C++14] __cpp_lib_nonmember_container_access 201411L [C++17] @@ -126,8 +127,8 @@ # ifndef __cpp_lib_array_constexpr # error "__cpp_lib_array_constexpr should be defined in c++2a" # endif -# if __cpp_lib_array_constexpr != 201603L -# error "__cpp_lib_array_constexpr should have the value 201603L in c++2a" +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++2a" # endif # if !defined(_LIBCPP_VERSION) diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -19,6 +19,7 @@ __cpp_lib_any 201606L [C++17] __cpp_lib_apply 201603L [C++17] __cpp_lib_array_constexpr 201603L [C++17] + 201811L [C++2a] __cpp_lib_as_const 201510L [C++17] __cpp_lib_atomic_is_always_lock_free 201603L [C++17] __cpp_lib_atomic_ref 201806L [C++2a] @@ -1537,8 +1538,8 @@ # ifndef __cpp_lib_array_constexpr # error "__cpp_lib_array_constexpr should be defined in c++2a" # endif -# if __cpp_lib_array_constexpr != 201603L -# error "__cpp_lib_array_constexpr should have the value 201603L in c++2a" +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++2a" # endif # ifndef __cpp_lib_as_const diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -149,6 +149,12 @@ # define TEST_CONSTEXPR_CXX14 #endif +#if TEST_STD_VER >= 17 +# define TEST_CONSTEXPR_CXX17 constexpr +#else +# define TEST_CONSTEXPR_CXX17 +#endif + #if TEST_STD_VER >= 20 # define TEST_CONSTEXPR_CXX20 constexpr #else diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -409,6 +409,7 @@ {"name": "__cpp_lib_array_constexpr", "values": { "c++17": int(201603), + "c++2a": int(201811), }, "headers": ["iterator", "array"], },