[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
This commit is contained in:
@@ -168,6 +168,8 @@ Status
|
||||
------------------------------------------------- -----------------
|
||||
**C++ 2a**
|
||||
-------------------------------------------------------------------
|
||||
``__cpp_lib_array_constexpr`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_ref`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bind_front`` *unimplemented*
|
||||
|
||||
@@ -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 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();
|
||||
const_reference front() const; // constexpr in C++14
|
||||
reference back();
|
||||
const_reference back() 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;
|
||||
const T* data() const noexcept;
|
||||
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 ||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -30,37 +30,44 @@
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
constexpr bool tests()
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
tests();
|
||||
static_assert(tests(), "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -19,32 +19,43 @@
|
||||
#include "disable_missing_braces_warning.h"
|
||||
|
||||
struct NoDefault {
|
||||
NoDefault(int) {}
|
||||
TEST_CONSTEXPR NoDefault(int) { }
|
||||
};
|
||||
|
||||
struct Default {
|
||||
TEST_CONSTEXPR Default() { }
|
||||
};
|
||||
|
||||
TEST_CONSTEXPR_CXX14 bool tests()
|
||||
{
|
||||
{
|
||||
std::array<Default, 3> array;
|
||||
assert(array.size() == 3);
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
typedef double T;
|
||||
typedef std::array<T, 3> C;
|
||||
C c;
|
||||
assert(c.size() == 3);
|
||||
}
|
||||
{
|
||||
typedef double T;
|
||||
typedef std::array<T, 0> C;
|
||||
C c;
|
||||
assert(c.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;
|
||||
tests();
|
||||
#if TEST_STD_VER >= 14
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
tests();
|
||||
#if TEST_STD_VER >= 14
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
{
|
||||
#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 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), "");
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
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], "");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
tests();
|
||||
#if TEST_STD_VER >= 20
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,5 +56,5 @@ int main(int, char**)
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)) {}
|
||||
};
|
||||
template <typename ...T>
|
||||
TEST_CONSTEXPR std::array<int, sizeof...(T)> tempArray(T ...args)
|
||||
{
|
||||
return {args...};
|
||||
}
|
||||
|
||||
constexpr std::array<int, 2> getArr () { return { 3, 4 }; }
|
||||
#endif
|
||||
TEST_CONSTEXPR_CXX14 bool tests()
|
||||
{
|
||||
{
|
||||
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);
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
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);
|
||||
}
|
||||
#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, "");
|
||||
}
|
||||
{
|
||||
static_assert(S().k == 3, "");
|
||||
static_assert(std::get<1>(getArr()) == 4, "");
|
||||
}
|
||||
tests();
|
||||
#if TEST_STD_VER >= 14
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -33,5 +33,5 @@ int main(int, char**)
|
||||
assert(*t == 3.5);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
#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);
|
||||
assert(false);
|
||||
}
|
||||
catch (const std::out_of_range &) {}
|
||||
try
|
||||
{
|
||||
TEST_IGNORE_NODISCARD cc.at(0);
|
||||
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);
|
||||
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
TEST_IGNORE_NODISCARD c.at(3);
|
||||
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, "");
|
||||
|
||||
constexpr T t2 = c.at(2);
|
||||
static_assert (t2 == 3.5, "");
|
||||
}
|
||||
#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
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void test_exceptions()
|
||||
{
|
||||
#ifndef TEST_HAS_NO_EXCEPTIONS
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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 >= 17
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
109
libcxx/test/std/containers/sequences/array/at_const.pass.cpp
Normal file
109
libcxx/test/std/containers/sequences/array/at_const.pass.cpp
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
TEST_CONSTEXPR_CXX17 bool tests()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
typedef double T;
|
||||
typedef std::array<T, 3> C;
|
||||
test_contiguous (C());
|
||||
}
|
||||
|
||||
return 0;
|
||||
tests();
|
||||
#if TEST_STD_VER >= 17 // begin() & friends are constexpr in >= C++17 only
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
TEST_CONSTEXPR_CXX14 bool tests()
|
||||
{
|
||||
{
|
||||
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**)
|
||||
{
|
||||
{
|
||||
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());
|
||||
}
|
||||
tests();
|
||||
#if TEST_STD_VER >= 14
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
#if TEST_STD_VER >= 11
|
||||
// Sanity check for constexpr in C++11
|
||||
{
|
||||
constexpr std::array<int, 3> array = {};
|
||||
static_assert(!array.empty(), "");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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 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<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 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 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
tests();
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // 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);
|
||||
}
|
||||
}
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
tests();
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 c;
|
||||
C::iterator i;
|
||||
i = c.begin();
|
||||
C::const_iterator j;
|
||||
j = c.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);
|
||||
}
|
||||
|
||||
#if TEST_STD_VER > 11
|
||||
{
|
||||
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, 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 >= 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 );
|
||||
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 ));
|
||||
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));
|
||||
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));
|
||||
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 );
|
||||
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 != 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);
|
||||
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));
|
||||
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));
|
||||
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};
|
||||
return true;
|
||||
}
|
||||
|
||||
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, "" );
|
||||
}
|
||||
int main(int, char**)
|
||||
{
|
||||
tests();
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
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, 0> C;
|
||||
C c = {};
|
||||
ASSERT_NOEXCEPT(c.max_size());
|
||||
assert(c.max_size() == 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
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);
|
||||
}
|
||||
tests();
|
||||
#if TEST_STD_VER >= 14
|
||||
static_assert(tests(), "");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
#if TEST_STD_VER >= 11
|
||||
// Sanity check for constexpr in C++11
|
||||
{
|
||||
constexpr std::array<int, 3> array = {};
|
||||
static_assert(array.max_size() == 3, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -409,6 +409,7 @@ feature_test_macros = sorted([ add_version_header(x) for x in [
|
||||
{"name": "__cpp_lib_array_constexpr",
|
||||
"values": {
|
||||
"c++17": int(201603),
|
||||
"c++2a": int(201811),
|
||||
},
|
||||
"headers": ["iterator", "array"],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user