[libcxx-commits] [libcxx] 77b9abf - [libc++] Complete overhaul of constexpr support in std::array
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu May 28 09:31:32 PDT 2020
Author: Louis Dionne
Date: 2020-05-28T12:31:06-04:00
New Revision: 77b9abfc8e89ca627e4f9a1cc206bea131db6db1
URL: https://github.com/llvm/llvm-project/commit/77b9abfc8e89ca627e4f9a1cc206bea131db6db1
DIFF: https://github.com/llvm/llvm-project/commit/77b9abfc8e89ca627e4f9a1cc206bea131db6db1.diff
LOG: [libc++] Complete overhaul of constexpr support in std::array
This commit adds missing support for constexpr in std::array under all
standard modes up to and including C++20. It also transforms the <array>
tests to check for constexpr-friendliness under the right standard modes.
Fixes https://llvm.org/PR40124
Fixes rdar://57522096
Supersedes https://reviews.llvm.org/D60666
Differential Revision: https://reviews.llvm.org/D80452
Added:
libcxx/test/std/containers/sequences/array/aggregate.pass.cpp
libcxx/test/std/containers/sequences/array/at_const.pass.cpp
libcxx/test/std/containers/sequences/array/front_back_const.pass.cpp
libcxx/test/std/containers/sequences/array/indexing_const.pass.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/include/array
libcxx/include/version
libcxx/test/std/containers/sequences/array/array.cons/deduct.pass.cpp
libcxx/test/std/containers/sequences/array/array.cons/default.pass.cpp
libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp
libcxx/test/std/containers/sequences/array/array.cons/initializer_list.pass.cpp
libcxx/test/std/containers/sequences/array/array.creation/to_array.pass.cpp
libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp
libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp
libcxx/test/std/containers/sequences/array/array.fill/fill.pass.cpp
libcxx/test/std/containers/sequences/array/array.size/size.pass.cpp
libcxx/test/std/containers/sequences/array/array.special/swap.pass.cpp
libcxx/test/std/containers/sequences/array/array.swap/swap.pass.cpp
libcxx/test/std/containers/sequences/array/array.tuple/get.pass.cpp
libcxx/test/std/containers/sequences/array/array.tuple/get_const.pass.cpp
libcxx/test/std/containers/sequences/array/array.tuple/get_const_rv.pass.cpp
libcxx/test/std/containers/sequences/array/array.tuple/get_rv.pass.cpp
libcxx/test/std/containers/sequences/array/array.tuple/tuple_element.fail.cpp
libcxx/test/std/containers/sequences/array/at.pass.cpp
libcxx/test/std/containers/sequences/array/compare.pass.cpp
libcxx/test/std/containers/sequences/array/contiguous.pass.cpp
libcxx/test/std/containers/sequences/array/empty.pass.cpp
libcxx/test/std/containers/sequences/array/front_back.pass.cpp
libcxx/test/std/containers/sequences/array/indexing.pass.cpp
libcxx/test/std/containers/sequences/array/iterators.pass.cpp
libcxx/test/std/containers/sequences/array/max_size.pass.cpp
libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/array.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
libcxx/test/support/test_macros.h
libcxx/utils/generate_feature_test_macro_components.py
Removed:
libcxx/test/std/containers/sequences/array/begin.pass.cpp
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index e8628408afd0..c04a883de179 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -168,6 +168,8 @@ Status
------------------------------------------------- -----------------
**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
index 7ffa825a9652..215d4e89f0ea 100644
--- a/libcxx/include/array
+++ b/libcxx/include/array
@@ -32,24 +32,24 @@ struct array
typedef std::reverse_iterator<const_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<T>);
+ void fill(const T& u); // constexpr in C++20
+ void swap(array& a) noexcept(is_nothrow_swappable_v<T>); // 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 @@ struct array
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 <class T, class... U>
- array(T, U...) -> array<T, 1 + sizeof...(U)>;
+template <class T, class... U>
+ array(T, U...) -> array<T, 1 + sizeof...(U)>; // C++17
template <class T, size_t N>
- bool operator==(const array<T,N>& x, const array<T,N>& y);
+ bool operator==(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
- bool operator!=(const array<T,N>& x, const array<T,N>& y);
+ bool operator!=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
- bool operator<(const array<T,N>& x, const array<T,N>& y);
+ bool operator<(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
- bool operator>(const array<T,N>& x, const array<T,N>& y);
+ bool operator>(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
- bool operator<=(const array<T,N>& x, const array<T,N>& y);
+ bool operator<=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N>
- bool operator>=(const array<T,N>& x, const array<T,N>& y);
+ bool operator>=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20
template <class T, size_t N >
- void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17
+ void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
+
+template <class T, size_t N>
+ constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]); // C++20
+template <class T, size_t N>
+ constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20
template <class T> struct tuple_size;
template <size_t I, class T> struct tuple_element;
template <class T, size_t N> struct tuple_size<array<T, N>>;
template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
-template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
-template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
-template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
+template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
} // std
@@ -143,11 +148,12 @@ struct _LIBCPP_TEMPLATE_VIS array
_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 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_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<is_const<_Tp>::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<value_type*>(__elems_);}
+ _LIBCPP_INLINE_VISIBILITY
+ const value_type* data() const _NOEXCEPT {return reinterpret_cast<const value_type*>(__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 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_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<T, 0>::operator[] on a zero-sized array");
_LIBCPP_UNREACHABLE();
@@ -303,46 +330,41 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
_LIBCPP_UNREACHABLE();
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference at(size_type) {
__throw_out_of_range("array<T, 0>::at");
_LIBCPP_UNREACHABLE();
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
const_reference at(size_type) const {
__throw_out_of_range("array<T, 0>::at");
_LIBCPP_UNREACHABLE();
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
reference front() _NOEXCEPT {
_LIBCPP_ASSERT(false, "cannot call array<T, 0>::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<T, 0>::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<T, 0>::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<T, 0>::back() on a zero-sized array");
_LIBCPP_UNREACHABLE();
}
-
- _LIBCPP_INLINE_VISIBILITY
- value_type* data() _NOEXCEPT {return reinterpret_cast<value_type*>(__elems_);}
- _LIBCPP_INLINE_VISIBILITY
- const value_type* data() const _NOEXCEPT {return reinterpret_cast<const value_type*>(__elems_);}
};
@@ -404,7 +426,7 @@ operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
}
template <class _Tp, size_t _Size>
-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
index 3951693ea826..5a250471a03e 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -21,7 +21,8 @@ __cpp_lib_allocator_traits_is_always_equal 201411L <memory> <scoped
<unordered_map> <unordered_set>
__cpp_lib_any 201606L <any>
__cpp_lib_apply 201603L <tuple>
-__cpp_lib_array_constexpr 201603L <iterator> <array>
+__cpp_lib_array_constexpr 201811L <iterator> <array>
+ 201603L // C++17
__cpp_lib_as_const 201510L <utility>
__cpp_lib_atomic_is_always_lock_free 201603L <atomic>
__cpp_lib_atomic_ref 201806L <atomic>
@@ -212,6 +213,8 @@ __cpp_lib_void_t 201411L <type_traits>
#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
index 000000000000..dd4064bb2fe8
--- /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 <array>
+#include <type_traits>
+
+template <typename T>
+void tests()
+{
+ // Test aggregate initialization
+ {
+ std::array<T, 0> a0 = {}; (void)a0;
+ std::array<T, 1> a1 = {T()}; (void)a1;
+ std::array<T, 2> a2 = {T(), T()}; (void)a2;
+ std::array<T, 3> 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<std::array<T, 0> >::value, "");
+ static_assert(std::is_aggregate<std::array<T, 1> >::value, "");
+ static_assert(std::is_aggregate<std::array<T, 2> >::value, "");
+ static_assert(std::is_aggregate<std::array<T, 3> >::value, "");
+ static_assert(std::is_aggregate<std::array<T, 4> >::value, "");
+#endif
+}
+
+struct Empty { };
+struct NonEmpty { int i; int j; };
+
+int main(int, char**)
+{
+ tests<char>();
+ tests<int>();
+ tests<long>();
+ tests<float>();
+ tests<double>();
+ tests<long double>();
+ tests<NonEmpty>();
+ tests<Empty>();
+
+ 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
index 141aafc2a318..42ebef6ddc44 100644
--- 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<decltype(arr), std::array<int, 3>>, "");
- 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<decltype(arr), std::array<int, 3>>, "");
+ 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<decltype(arr)::value_type, long>, "");
- 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<decltype(arr)::value_type, long>, "");
+ 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<double, 2> source = {4.0, 5.0};
- std::array arr(source); // array(array)
- static_assert(std::is_same_v<decltype(arr), decltype(source)>, "");
- static_assert(std::is_same_v<decltype(arr), std::array<double, 2>>, "");
- assert(arr[0] == 4.0);
- assert(arr[1] == 5.0);
- }
+ // Test the implicit deduction guides
+ {
+ std::array<double, 2> source = {4.0, 5.0};
+ std::array arr(source); // array(array)
+ static_assert(std::is_same_v<decltype(arr), decltype(source)>, "");
+ static_assert(std::is_same_v<decltype(arr), std::array<double, 2>>, "");
+ 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
index 16671e3b5d1b..e73a9671f478 100644
--- 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<T, 3> C;
- C c;
- assert(c.size() == 3);
+ std::array<Default, 3> array;
+ assert(array.size() == 3);
}
+
{
- typedef double T;
- typedef std::array<T, 0> C;
- C c;
- assert(c.size() == 0);
+ std::array<Default, 0> array;
+ assert(array.size() == 0);
}
+
{
- typedef std::array<NoDefault, 0> C;
- C c;
- assert(c.size() == 0);
- C c1 = {};
- assert(c1.size() == 0);
- C c2 = {{}};
- assert(c2.size() == 0);
+ typedef std::array<NoDefault, 0> 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
index c0e205c8322a..cb9a18298031 100644
--- 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<T>::value, "")
+# define TEST_NOT_COPY_ASSIGNABLE(T) static_assert(!std::is_copy_assignable<T>::value, "")
#endif
struct NoDefault {
- NoDefault(int) {}
+ TEST_CONSTEXPR NoDefault(int) { }
};
-int main(int, char**) {
- {
- typedef double T;
- typedef std::array<T, 3> C;
- C c = {1.1, 2.2, 3.3};
- C c2 = c;
- c2 = c;
- static_assert(std::is_copy_constructible<C>::value, "");
- static_assert(std::is_copy_assignable<C>::value, "");
- }
- {
- typedef double T;
- typedef std::array<const T, 3> C;
- C c = {1.1, 2.2, 3.3};
- C c2 = c;
- ((void)c2);
- static_assert(std::is_copy_constructible<C>::value, "");
- TEST_NOT_COPY_ASSIGNABLE(C);
- }
- {
- typedef double T;
- typedef std::array<T, 0> C;
- C c = {};
- C c2 = c;
- c2 = c;
- static_assert(std::is_copy_constructible<C>::value, "");
- static_assert(std::is_copy_assignable<C>::value, "");
- }
- {
- // const arrays of size 0 should disable the implicit copy assignment operator.
- typedef double T;
- typedef std::array<const T, 0> C;
- C c = {{}};
- C c2 = c;
- ((void)c2);
- static_assert(std::is_copy_constructible<C>::value, "");
- TEST_NOT_COPY_ASSIGNABLE(C);
- }
- {
- typedef NoDefault T;
- typedef std::array<T, 0> C;
- C c = {};
- C c2 = c;
- c2 = c;
- static_assert(std::is_copy_constructible<C>::value, "");
- static_assert(std::is_copy_assignable<C>::value, "");
- }
- {
- typedef NoDefault T;
- typedef std::array<const T, 0> C;
- C c = {{}};
- C c2 = c;
- ((void)c2);
- static_assert(std::is_copy_constructible<C>::value, "");
- TEST_NOT_COPY_ASSIGNABLE(C);
- }
+TEST_CONSTEXPR_CXX14 bool tests()
+{
+ {
+ typedef double T;
+ typedef std::array<T, 3> C;
+ C c = {1.1, 2.2, 3.3};
+ C c2 = c;
+ c2 = c;
+ static_assert(std::is_copy_constructible<C>::value, "");
+ static_assert(std::is_copy_assignable<C>::value, "");
+ }
+ {
+ typedef double T;
+ typedef std::array<const T, 3> C;
+ C c = {1.1, 2.2, 3.3};
+ C c2 = c;
+ ((void)c2);
+ static_assert(std::is_copy_constructible<C>::value, "");
+ TEST_NOT_COPY_ASSIGNABLE(C);
+ }
+ {
+ typedef double T;
+ typedef std::array<T, 0> C;
+ C c = {};
+ C c2 = c;
+ c2 = c;
+ static_assert(std::is_copy_constructible<C>::value, "");
+ static_assert(std::is_copy_assignable<C>::value, "");
+ }
+ {
+ // const arrays of size 0 should disable the implicit copy assignment operator.
+ typedef double T;
+ typedef std::array<const T, 0> C;
+ C c = {{}};
+ C c2 = c;
+ ((void)c2);
+ static_assert(std::is_copy_constructible<C>::value, "");
+ TEST_NOT_COPY_ASSIGNABLE(C);
+ }
+ {
+ typedef NoDefault T;
+ typedef std::array<T, 0> C;
+ C c = {};
+ C c2 = c;
+ c2 = c;
+ static_assert(std::is_copy_constructible<C>::value, "");
+ static_assert(std::is_copy_assignable<C>::value, "");
+ }
+ {
+ typedef NoDefault T;
+ typedef std::array<const T, 0> C;
+ C c = {{}};
+ C c2 = c;
+ ((void)c2);
+ static_assert(std::is_copy_constructible<C>::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
index cdc04b18d24f..49437546a8f7 100644
--- 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<T, 3> 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 @@ int main(int, char**)
{
typedef double T;
typedef std::array<T, 0> C;
- C c = {};
+ C const c = {};
assert(c.size() == 0);
}
{
typedef double T;
typedef std::array<T, 3> C;
- C c = {1};
+ C const c = {1};
assert(c.size() == 3.0);
assert(c[0] == 1);
}
{
typedef int T;
typedef std::array<T, 1> 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
index d5df96a27005..87165498416b 100644
--- 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 @@ int main(int, char**) {
assert(arr[0].b == .1);
}
- // Test constexpr.
- {
- constexpr std::array<int, 3> 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
index 434cbc5fe4e9..a41409f8df1c 100644
--- 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 @@ struct natural_alignment {
};
#endif
-int main(int, char**)
+TEST_CONSTEXPR_CXX17 bool tests()
{
{
typedef double T;
@@ -52,33 +52,49 @@ int main(int, char**)
LIBCPP_ASSERT(p != nullptr);
}
{
- typedef double T;
- typedef std::array<const T, 0> C;
- C c = {{}};
- const T* p = c.data();
- static_assert((std::is_same<decltype(c.data()), const T*>::value), "");
- LIBCPP_ASSERT(p != nullptr);
+ typedef double T;
+ typedef std::array<const T, 0> C;
+ C c = {{}};
+ const T* p = c.data();
+ LIBCPP_ASSERT(p != nullptr);
+ static_assert((std::is_same<decltype(c.data()), const T*>::value), "");
}
- {
-#if TEST_STD_VER < 11
- typedef natural_alignment T;
-#else
- typedef std::max_align_t T;
-#endif
- typedef std::array<T, 0> C;
- const C c = {};
- const T* p = c.data();
- LIBCPP_ASSERT(p != nullptr);
- std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
- assert(pint % TEST_ALIGNOF(T) == 0);
+ {
+ typedef NoDefault T;
+ typedef std::array<T, 0> C;
+ C c = {};
+ T* p = c.data();
+ LIBCPP_ASSERT(p != nullptr);
}
{
- typedef NoDefault T;
- typedef std::array<T, 0> C;
- C c = {};
- T* p = c.data();
- LIBCPP_ASSERT(p != nullptr);
+ std::array<int, 5> 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<T, 0> C;
+ const C c = {};
+ const T* p = c.data();
+ LIBCPP_ASSERT(p != nullptr);
+ std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(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
index 92828eef0711..0f79237b48a6 100644
--- 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 @@ struct natural_alignment {
};
#endif
-int main(int, char**)
+TEST_CONSTEXPR_CXX17 bool tests()
{
{
typedef double T;
@@ -49,40 +49,45 @@ int main(int, char**)
typedef std::array<T, 0> 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<T, 0> C;
+ const C c = {};
+ const T* p = c.data();
+ LIBCPP_ASSERT(p != nullptr);
}
{
- typedef NoDefault T;
- typedef std::array<T, 0> C;
- const C c = {};
- const T* p = c.data();
- LIBCPP_ASSERT(p != nullptr);
+ std::array<int, 5> 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<T, 0> C;
- const C c = {};
- const T* p = c.data();
- LIBCPP_ASSERT(p != nullptr);
- std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(p);
- assert(pint % TEST_ALIGNOF(T) == 0);
- }
-#if TEST_STD_VER > 14
- {
- typedef std::array<int, 5> 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<T, 0> C;
+ const C c = {};
+ const T* p = c.data();
+ LIBCPP_ASSERT(p != nullptr);
+ std::uintptr_t pint = reinterpret_cast<std::uintptr_t>(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
index f480d17393d4..3a185110a91e 100644
--- 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 @@ int main(int, char**)
assert(c[1] == 5.5);
assert(c[2] == 5.5);
}
+
{
typedef double T;
typedef std::array<T, 0> C;
@@ -37,6 +38,14 @@ int main(int, char**)
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
index f837bdcf8fb8..e55030015b03 100644
--- 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 @@ int main(int, char**)
}
#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
index 6c9ed957b836..788f0ed486b8 100644
--- 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 <class Tp>
@@ -33,9 +33,9 @@ template <class Tp>
std::false_type can_swap_imp(...);
template <class Tp>
-struct can_swap : std::is_same<decltype(can_swap_imp<Tp>(0)), void> {};
+struct can_swap : std::is_same<decltype(can_swap_imp<Tp>(0)), void> { };
-int main(int, char**)
+TEST_CONSTEXPR_CXX20 bool tests()
{
{
typedef double T;
@@ -82,5 +82,14 @@ int main(int, char**)
}
#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
index aac8a13b29a3..1f2d8e7de35f 100644
--- 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 @@ int main(int, char**)
#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
index 9e94417ac973..1b13d773b0de 100644
--- 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<int, 3> a;
- int k;
- constexpr S() : a{1,2,3}, k(std::get<2>(a)) {}
-};
-
-constexpr std::array<int, 2> getArr () { return { 3, 4 }; }
-#endif
+template <typename ...T>
+TEST_CONSTEXPR std::array<int, sizeof...(T)> tempArray(T ...args)
+{
+ return {args...};
+}
-int main(int, char**)
+TEST_CONSTEXPR_CXX14 bool tests()
{
{
- typedef double T;
- typedef std::array<T, 3> 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<double, 1> 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<T, 3> 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<double, 2> 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<double, 3> 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<double, 1> array = {3.3};
+ static_assert(std::is_same<double&, decltype(std::get<0>(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
index b22a76185b6f..3c1941c031fb 100644
--- 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<T, 3> 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<double, 1> const array = {3.3};
+ assert(std::get<0>(array) == 3.3);
}
-#if TEST_STD_VER > 11
{
- typedef double T;
- typedef std::array<T, 3> 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<double, 2> const array = {3.3, 4.4};
+ assert(std::get<0>(array) == 3.3);
+ assert(std::get<1>(array) == 4.4);
+ }
+ {
+ std::array<double, 3> 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<double, 1> const array = {3.3};
+ static_assert(std::is_same<double const&, decltype(std::get<0>(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
index ce8fc4fd3651..346978008c84 100644
--- 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 @@ int main(int, char**)
{
{
- typedef std::unique_ptr<double> T;
- typedef std::array<T, 1> C;
- const C c = {std::unique_ptr<double>(new double(3.5))};
- static_assert(std::is_same<const T&&, decltype(std::get<0>(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<double> T;
+ typedef std::array<T, 1> C;
+ const C c = {std::unique_ptr<double>(new double(3.5))};
+ static_assert(std::is_same<const T&&, decltype(std::get<0>(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<T, 3> 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<T, 3> 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
index d1d8b28f4c9d..e557c19ba2a4 100644
--- 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 @@ int main(int, char**)
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
index a4fbd3ab4c21..cde4ba7c759f 100644
--- 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 <array>
#include <cassert>
-
// 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
index 0454643541c9..ed4ab80fb0cd 100644
--- a/libcxx/test/std/containers/sequences/array/at.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/at.pass.cpp
@@ -8,10 +8,7 @@
// <array>
-// 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 <array>
#include <cassert>
@@ -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<double, 3> 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<T, 3> 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<T, 0> C;
- C c = {};
- C const& cc = c;
- try
- {
- TEST_IGNORE_NODISCARD c.at(0);
+ std::array<int, 4> 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<T, 3> 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<T, 3> C;
- constexpr C c = {1, 2, 3.5};
-
- constexpr T t1 = c.at(0);
- static_assert (t1 == 1, "");
+ std::array<int, 0> 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
index 000000000000..d79c5054ae83
--- /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
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// const_reference at (size_type) const; // constexpr in C++14
+
+#include <array>
+#include <cassert>
+
+#ifndef TEST_HAS_NO_EXCEPTIONS
+#include <stdexcept>
+#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<T, 3> 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<int, 4> 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<int, 0> 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
index 7b26d231dbdd..000000000000
--- 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
-//
-//===----------------------------------------------------------------------===//
-
-// <array>
-
-// iterator begin();
-
-#include <array>
-#include <cassert>
-
-#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<T, 3> 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<T, 0> 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
index c05dd19405bf..c89216c8bb87 100644
--- a/libcxx/test/std/containers/sequences/array/compare.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/compare.pass.cpp
@@ -8,17 +8,15 @@
// <array>
-// These are all constexpr in C++20
-// bool operator==(array<T, N> const&, array<T, N> const&);
-// bool operator!=(array<T, N> const&, array<T, N> const&);
-// bool operator<(array<T, N> const&, array<T, N> const&);
-// bool operator<=(array<T, N> const&, array<T, N> const&);
-// bool operator>(array<T, N> const&, array<T, N> const&);
-// bool operator>=(array<T, N> const&, array<T, N> const&);
+// bool operator==(array<T, N> const&, array<T, N> const&); // constexpr in C++20
+// bool operator!=(array<T, N> const&, array<T, N> const&); // constexpr in C++20
+// bool operator<(array<T, N> const&, array<T, N> const&); // constexpr in C++20
+// bool operator<=(array<T, N> const&, array<T, N> const&); // constexpr in C++20
+// bool operator>(array<T, N> const&, array<T, N> const&); // constexpr in C++20
+// bool operator>=(array<T, N> const&, array<T, N> const&); // constexpr in C++20
#include <array>
-#include <vector>
#include <cassert>
#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<int, 3> 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<int, 0> C;
+ C c1 = {};
+ C c2 = {};
+ assert(testComparisons6(c1, c2, true, false));
+ }
+
+ return true;
+}
+
int main(int, char**)
{
- {
- typedef int T;
- typedef std::array<T, 3> 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<T, 0> C;
- C c1 = {};
- C c2 = {};
- assert(testComparisons6(c1, c2, true, false));
- }
-
-#if TEST_STD_VER > 17
- {
- constexpr std::array<int, 3> a1 = {1, 2, 3};
- constexpr std::array<int, 3> 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
index 41a7153e88d4..9589e6364394 100644
--- 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 <class C>
-void test_contiguous ( const C &c )
+template <class Container>
+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<T, 3> C;
- test_contiguous (C());
- }
+ assert_contiguous(std::array<double, 0>());
+ assert_contiguous(std::array<double, 1>());
+ assert_contiguous(std::array<double, 2>());
+ assert_contiguous(std::array<double, 3>());
+
+ assert_contiguous(std::array<char, 0>());
+ assert_contiguous(std::array<char, 1>());
+ assert_contiguous(std::array<char, 2>());
+ assert_contiguous(std::array<char, 3>());
+
+ 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
index a17aa50c5b21..8b61575c2e73 100644
--- 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 <array>
#include <cassert>
#include "test_macros.h"
-#include "min_allocator.h"
-int main(int, char**)
+TEST_CONSTEXPR_CXX14 bool tests()
{
{
- typedef std::array<int, 2> C;
- C c;
- ASSERT_NOEXCEPT(c.empty());
- assert(!c.empty());
+ typedef std::array<int, 2> C;
+ C c = {};
+ ASSERT_NOEXCEPT(c.empty());
+ assert(!c.empty());
+ }
+ {
+ typedef std::array<int, 0> 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<int, 0> C;
- C c;
- ASSERT_NOEXCEPT(c.empty());
- assert( c.empty());
+ constexpr std::array<int, 3> 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
index 5e0cb08ede07..18985e90a89e 100644
--- 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 @@
// <array>
-// 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 <array>
#include <cassert>
@@ -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<double, 3> arr = {1, 2, 3.5};
- return arr.front() == val;
-}
-constexpr bool check_back( double val )
-{
- std::array<double, 3> 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 @@ int main(int, char**)
}
{
typedef double T;
- typedef std::array<T, 3> 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<T, 0> 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<T, 0> 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<const T, 0> 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<T, 3> 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<const T, 0> 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
index 000000000000..af519127bed5
--- /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
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// const_reference front() const; // constexpr in C++14
+// const_reference back() const; // constexpr in C++14
+
+#include <array>
+#include <cassert>
+
+#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<T, 3> 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<T, 0> 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<const T, 0> 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
index 0df672d8b019..6b5d8486fda2 100644
--- a/libcxx/test/std/containers/sequences/array/indexing.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/indexing.pass.cpp
@@ -8,11 +8,8 @@
// <array>
-// 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 <array>
#include <cassert>
@@ -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<double, 3> 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 @@ int main(int, char**)
r2 = 7.5;
assert(c.back() == 7.5);
}
+
+ // Test operator[] "works" on zero sized arrays
{
- typedef double T;
- typedef std::array<T, 3> 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<T, 0> 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<T, 0> 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<const T, 0> 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<const T, 0> 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<T, 3> 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
index 000000000000..3f34dfe7dd32
--- /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
+//
+//===----------------------------------------------------------------------===//
+
+// <array>
+
+// const_reference operator[](size_type) const; // constexpr in C++14
+// Libc++ marks it as noexcept
+
+#include <array>
+#include <cassert>
+
+#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<T, 3> 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<T, 0> 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<T const, 0> 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
index 71fad183ff73..39d8a1a5dfa4 100644
--- a/libcxx/test/std/containers/sequences/array/iterators.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/iterators.pass.cpp
@@ -8,7 +8,20 @@
// <array>
-// 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 <array>
#include <iterator>
@@ -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<int, 5> C;
- C c;
- C::iterator i;
- i = c.begin();
- C::const_iterator j;
- j = c.cbegin();
- assert(i == j);
+ typedef std::array<int, 5> C;
+ C array = {};
+ typename C::iterator i = array.begin();
+ typename C::const_iterator j = array.cbegin();
+ assert(i == j);
+ }
+ {
+ typedef std::array<int, 0> 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<int, 0> 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<int, 1> 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<int, 0> C;
- C c;
- C::iterator i;
- i = c.begin();
- C::const_iterator j;
- j = c.cbegin();
- assert(i == j);
+ typedef std::array<int, 2> 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<double, 3> 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<NoDefault, 0> 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<int, 5> 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<int, 5> 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<int, 0> 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<int, 0> 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<int, 5> 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
index a0b77392ee80..8ca8cd44725e 100644
--- 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 <array>
#include <cassert>
#include "test_macros.h"
-#include "min_allocator.h"
-int main(int, char**)
+TEST_CONSTEXPR_CXX14 bool tests()
{
{
- typedef std::array<int, 2> C;
- C c;
- ASSERT_NOEXCEPT(c.max_size());
- assert(c.max_size() == 2);
+ typedef std::array<int, 2> C;
+ C c = {};
+ ASSERT_NOEXCEPT(c.max_size());
+ assert(c.max_size() == 2);
+ }
+ {
+ typedef std::array<int, 0> 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<int, 0> C;
- C c;
- ASSERT_NOEXCEPT(c.max_size());
- assert(c.max_size() == 0);
+ constexpr std::array<int, 3> 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
index 51982ea5cab1..11eac5cc825b 100644
--- 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 @@ void test() {
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 <class T>
@@ -67,8 +61,6 @@ struct TEST_ALIGNAS(TEST_ALIGNOF(std::max_align_t) * 2) TestType2 {
};
#endif
-//static_assert(sizeof(void*) == 4, "");
-
int main(int, char**) {
test_type<char>();
test_type<int>();
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
index 152458908e7d..933420be50c9 100644
--- 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
index 9c1719b53cfe..4e68cf9a7232 100644
--- 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
index 0c2cd5375758..901cb2539635 100644
--- 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
index 79ee5ddace8c..63aa4f47a70f 100644
--- 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
index 4a9772cfc66d..7a3f441c1cab 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -409,6 +409,7 @@ def add_version_header(tc):
{"name": "__cpp_lib_array_constexpr",
"values": {
"c++17": int(201603),
+ "c++2a": int(201811),
},
"headers": ["iterator", "array"],
},
More information about the libcxx-commits
mailing list