[libc++] [P1032] Misc constexpr bits in <iterator>, <string_view>, <tuple>, <utility>.

This completes the implementation of P1032's changes to <iterator>,
<string_view>, <tuple>, and <utility> in C++20.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1032r1.html

Drive-by fix a couple of unintended rvalues in "*iterators*/*.fail.cpp".

Differential Revision: https://reviews.llvm.org/D96385
This commit is contained in:
Arthur O'Dwyer 2021-02-09 19:12:16 -05:00
parent 1f46499690
commit 06e2b737aa
43 changed files with 642 additions and 489 deletions

View File

@ -68,7 +68,7 @@
"`P1006R1 <https://wg21.link/P1006R1>`__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0" "`P1006R1 <https://wg21.link/P1006R1>`__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0"
"`P1007R3 <https://wg21.link/P1007R3>`__","LWG","``std::assume_aligned``\ ","San Diego","* *","" "`P1007R3 <https://wg21.link/P1007R3>`__","LWG","``std::assume_aligned``\ ","San Diego","* *",""
"`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","* *","" "`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","* *",""
"`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","* *","" "`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0"
"`P1085R2 <https://wg21.link/P1085R2>`__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0" "`P1085R2 <https://wg21.link/P1085R2>`__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0"
"`P1123R0 <https://wg21.link/P1123R0>`__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *","" "`P1123R0 <https://wg21.link/P1123R0>`__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *",""
"`P1148R0 <https://wg21.link/P1148R0>`__","LWG","Cleaning up Clause 20","San Diego","* *","" "`P1148R0 <https://wg21.link/P1148R0>`__","LWG","Cleaning up Clause 20","San Diego","* *",""

1 Paper # Group Paper Name Meeting Status First released version
68 `P1006R1 <https://wg21.link/P1006R1>`__ LWG Constexpr in std::pointer_traits San Diego |Complete| 8.0
69 `P1007R3 <https://wg21.link/P1007R3>`__ LWG ``std::assume_aligned``\ San Diego * *
70 `P1020R1 <https://wg21.link/P1020R1>`__ LWG Smart pointer creation with default initialization San Diego * *
71 `P1032R1 <https://wg21.link/P1032R1>`__ LWG Misc constexpr bits San Diego * * |Complete| 13.0
72 `P1085R2 <https://wg21.link/P1085R2>`__ LWG Should Span be Regular? San Diego |Complete| 8.0
73 `P1123R0 <https://wg21.link/P1123R0>`__ LWG Editorial Guidance for merging P0019r8 and P0528r3 San Diego * *
74 `P1148R0 <https://wg21.link/P1148R0>`__ LWG Cleaning up Clause 20 San Diego * *

View File

@ -208,17 +208,17 @@ Status
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_functional`` ``201907L`` ``__cpp_lib_constexpr_functional`` ``201907L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_iterator`` *unimplemented* ``__cpp_lib_constexpr_iterator`` ``201811L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_memory`` ``201811L`` ``__cpp_lib_constexpr_memory`` ``201811L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_numeric`` ``201911L`` ``__cpp_lib_constexpr_numeric`` ``201911L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_string`` *unimplemented* ``__cpp_lib_constexpr_string`` ``201811L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_string_view`` *unimplemented* ``__cpp_lib_constexpr_string_view`` ``201811L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_tuple`` *unimplemented* ``__cpp_lib_constexpr_tuple`` ``201811L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------
``__cpp_lib_constexpr_utility`` ``201811L`` ``__cpp_lib_constexpr_utility`` ``201811L``
------------------------------------------------- ----------------- ------------------------------------------------- -----------------

View File

@ -152,14 +152,14 @@ public:
typedef void reference; typedef void reference;
typedef void pointer; typedef void pointer;
explicit back_insert_iterator(Container& x); explicit back_insert_iterator(Container& x); // constexpr in C++20
back_insert_iterator& operator=(const typename Container::value_type& value); back_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
back_insert_iterator& operator*(); back_insert_iterator& operator*(); // constexpr in C++20
back_insert_iterator& operator++(); back_insert_iterator& operator++(); // constexpr in C++20
back_insert_iterator operator++(int); back_insert_iterator operator++(int); // constexpr in C++20
}; };
template <class Container> back_insert_iterator<Container> back_inserter(Container& x); template <class Container> back_insert_iterator<Container> back_inserter(Container& x); // constexpr in C++20
template <class Container> template <class Container>
class front_insert_iterator class front_insert_iterator
@ -173,14 +173,14 @@ public:
typedef void reference; typedef void reference;
typedef void pointer; typedef void pointer;
explicit front_insert_iterator(Container& x); explicit front_insert_iterator(Container& x); // constexpr in C++20
front_insert_iterator& operator=(const typename Container::value_type& value); front_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
front_insert_iterator& operator*(); front_insert_iterator& operator*(); // constexpr in C++20
front_insert_iterator& operator++(); front_insert_iterator& operator++(); // constexpr in C++20
front_insert_iterator operator++(int); front_insert_iterator operator++(int); // constexpr in C++20
}; };
template <class Container> front_insert_iterator<Container> front_inserter(Container& x); template <class Container> front_insert_iterator<Container> front_inserter(Container& x); // constexpr in C++20
template <class Container> template <class Container>
class insert_iterator class insert_iterator
@ -195,15 +195,15 @@ public:
typedef void reference; typedef void reference;
typedef void pointer; typedef void pointer;
insert_iterator(Container& x, typename Container::iterator i); insert_iterator(Container& x, typename Container::iterator i); // constexpr in C++20
insert_iterator& operator=(const typename Container::value_type& value); insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
insert_iterator& operator*(); insert_iterator& operator*(); // constexpr in C++20
insert_iterator& operator++(); insert_iterator& operator++(); // constexpr in C++20
insert_iterator& operator++(int); insert_iterator& operator++(int); // constexpr in C++20
}; };
template <class Container, class Iterator> template <class Container, class Iterator>
insert_iterator<Container> inserter(Container& x, Iterator i); insert_iterator<Container> inserter(Container& x, Iterator i); // constexpr in C++20
template <class Iterator> template <class Iterator>
class move_iterator { class move_iterator {
@ -932,20 +932,20 @@ protected:
public: public:
typedef _Container container_type; typedef _Container container_type;
_LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
{container->push_back(__value_); return *this;} {container->push_back(__value_); return *this;}
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_)
{container->push_back(_VSTD::move(__value_)); return *this;} {container->push_back(_VSTD::move(__value_)); return *this;}
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY back_insert_iterator operator++(int) {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator operator++(int) {return *this;}
}; };
template <class _Container> template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
back_insert_iterator<_Container> back_insert_iterator<_Container>
back_inserter(_Container& __x) back_inserter(_Container& __x)
{ {
@ -965,20 +965,20 @@ protected:
public: public:
typedef _Container container_type; typedef _Container container_type;
_LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
{container->push_front(__value_); return *this;} {container->push_front(__value_); return *this;}
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_)
{container->push_front(_VSTD::move(__value_)); return *this;} {container->push_front(_VSTD::move(__value_)); return *this;}
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY front_insert_iterator operator++(int) {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator operator++(int) {return *this;}
}; };
template <class _Container> template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
front_insert_iterator<_Container> front_insert_iterator<_Container>
front_inserter(_Container& __x) front_inserter(_Container& __x)
{ {
@ -999,21 +999,21 @@ protected:
public: public:
typedef _Container container_type; typedef _Container container_type;
_LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
: container(_VSTD::addressof(__x)), iter(__i) {} : container(_VSTD::addressof(__x)), iter(__i) {}
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
{iter = container->insert(iter, __value_); ++iter; return *this;} {iter = container->insert(iter, __value_); ++iter; return *this;}
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_) _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_)
{iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;} {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator*() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*() {return *this;}
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator++() {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++() {return *this;}
_LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int) {return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int) {return *this;}
}; };
template <class _Container> template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
insert_iterator<_Container> insert_iterator<_Container>
inserter(_Container& __x, typename _Container::iterator __i) inserter(_Container& __x, typename _Container::iterator __i)
{ {

View File

@ -107,7 +107,7 @@ namespace std {
constexpr void remove_suffix(size_type n); constexpr void remove_suffix(size_type n);
constexpr void swap(basic_string_view& s) noexcept; constexpr void swap(basic_string_view& s) noexcept;
size_type copy(charT* s, size_type n, size_type pos = 0) const; size_type copy(charT* s, size_type n, size_type pos = 0) const; // constexpr in C++20
constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const; constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
constexpr int compare(basic_string_view s) const noexcept; constexpr int compare(basic_string_view s) const noexcept;
@ -359,7 +359,7 @@ public:
__other.__size = __sz; __other.__size = __sz;
} }
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
{ {
if (__pos > size()) if (__pos > size())

View File

@ -38,39 +38,39 @@ public:
template <class Alloc> template <class Alloc>
tuple(allocator_arg_t, const Alloc& a); tuple(allocator_arg_t, const Alloc& a);
template <class Alloc> template <class Alloc>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...); // constexpr in C++20
template <class Alloc, class... U> template <class Alloc, class... U>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...); // constexpr in C++20
template <class Alloc> template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, const tuple&); tuple(allocator_arg_t, const Alloc& a, const tuple&); // constexpr in C++20
template <class Alloc> template <class Alloc>
tuple(allocator_arg_t, const Alloc& a, tuple&&); tuple(allocator_arg_t, const Alloc& a, tuple&&); // constexpr in C++20
template <class Alloc, class... U> template <class Alloc, class... U>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); // constexpr in C++20
template <class Alloc, class... U> template <class Alloc, class... U>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); // constexpr in C++20
template <class Alloc, class U1, class U2> template <class Alloc, class U1, class U2>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); // constexpr in C++20
template <class Alloc, class U1, class U2> template <class Alloc, class U1, class U2>
explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); // constexpr in C++20
tuple& operator=(const tuple&); tuple& operator=(const tuple&); // constexpr in C++20
tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...); // constexpr in C++20
template <class... U> template <class... U>
tuple& operator=(const tuple<U...>&); tuple& operator=(const tuple<U...>&); // constexpr in C++20
template <class... U> template <class... U>
tuple& operator=(tuple<U...>&&); tuple& operator=(tuple<U...>&&); // constexpr in C++20
template <class U1, class U2> template <class U1, class U2>
tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++20
template <class U1, class U2> template <class U1, class U2>
tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2 // constexpr in C++20
template<class U, size_t N> template<class U, size_t N>
tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
template<class U, size_t N> template<class U, size_t N>
tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); // constexpr in C++20
}; };
template <class ...T> template <class ...T>
@ -174,7 +174,7 @@ template <size_t _Ip, class _Hp,
class __tuple_leaf; class __tuple_leaf;
template <size_t _Ip, class _Hp, bool _Ep> template <size_t _Ip, class _Hp, bool _Ep>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
_NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
{ {
@ -195,29 +195,30 @@ class __tuple_leaf
#endif #endif
} }
_LIBCPP_CONSTEXPR_AFTER_CXX11
__tuple_leaf& operator=(const __tuple_leaf&); __tuple_leaf& operator=(const __tuple_leaf&);
public: public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf() _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
_NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_() _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
{static_assert(!is_reference<_Hp>::value, {static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");} "Attempted to default construct a reference element in a tuple");}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
__tuple_leaf(integral_constant<int, 0>, const _Alloc&) __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
: __value_() : __value_()
{static_assert(!is_reference<_Hp>::value, {static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");} "Attempted to default construct a reference element in a tuple");}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
__tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
: __value_(allocator_arg_t(), __a) : __value_(allocator_arg_t(), __a)
{static_assert(!is_reference<_Hp>::value, {static_assert(!is_reference<_Hp>::value,
"Attempted to default construct a reference element in a tuple");} "Attempted to default construct a reference element in a tuple");}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
__tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
: __value_(__a) : __value_(__a)
{static_assert(!is_reference<_Hp>::value, {static_assert(!is_reference<_Hp>::value,
@ -238,21 +239,21 @@ public:
"Attempted construction of reference element binds to a temporary whose lifetime has ended");} "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
template <class _Tp, class _Alloc> template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
: __value_(_VSTD::forward<_Tp>(__t)) : __value_(_VSTD::forward<_Tp>(__t))
{static_assert(__can_bind_reference<_Tp&&>(), {static_assert(__can_bind_reference<_Tp&&>(),
"Attempted construction of reference element binds to a temporary whose lifetime has ended");} "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
template <class _Tp, class _Alloc> template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
: __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
{static_assert(!is_reference<_Hp>::value, {static_assert(!is_reference<_Hp>::value,
"Attempted to uses-allocator construct a reference element in a tuple");} "Attempted to uses-allocator construct a reference element in a tuple");}
template <class _Tp, class _Alloc> template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
: __value_(_VSTD::forward<_Tp>(__t), __a) : __value_(_VSTD::forward<_Tp>(__t), __a)
{static_assert(!is_reference<_Hp>::value, {static_assert(!is_reference<_Hp>::value,
@ -261,7 +262,7 @@ public:
__tuple_leaf(const __tuple_leaf& __t) = default; __tuple_leaf(const __tuple_leaf& __t) = default;
__tuple_leaf(__tuple_leaf&& __t) = default; __tuple_leaf(__tuple_leaf&& __t) = default;
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
{ {
_VSTD::swap(*this, __t); _VSTD::swap(*this, __t);
@ -276,23 +277,23 @@ template <size_t _Ip, class _Hp>
class __tuple_leaf<_Ip, _Hp, true> class __tuple_leaf<_Ip, _Hp, true>
: private _Hp : private _Hp
{ {
_LIBCPP_CONSTEXPR_AFTER_CXX11
__tuple_leaf& operator=(const __tuple_leaf&); __tuple_leaf& operator=(const __tuple_leaf&);
public: public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf() _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
_NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {} _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
__tuple_leaf(integral_constant<int, 0>, const _Alloc&) {} __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
__tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
: _Hp(allocator_arg_t(), __a) {} : _Hp(allocator_arg_t(), __a) {}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
__tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
: _Hp(__a) {} : _Hp(__a) {}
@ -309,24 +310,24 @@ public:
: _Hp(_VSTD::forward<_Tp>(__t)) {} : _Hp(_VSTD::forward<_Tp>(__t)) {}
template <class _Tp, class _Alloc> template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
: _Hp(_VSTD::forward<_Tp>(__t)) {} : _Hp(_VSTD::forward<_Tp>(__t)) {}
template <class _Tp, class _Alloc> template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
: _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {} : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
template <class _Tp, class _Alloc> template <class _Tp, class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
: _Hp(_VSTD::forward<_Tp>(__t), __a) {} : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
__tuple_leaf(__tuple_leaf const &) = default; __tuple_leaf(__tuple_leaf const &) = default;
__tuple_leaf(__tuple_leaf &&) = default; __tuple_leaf(__tuple_leaf &&) = default;
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
int int
swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
{ {
@ -339,7 +340,7 @@ public:
}; };
template <class ..._Tp> template <class ..._Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
void __swallow(_Tp&&...) _NOEXCEPT {} void __swallow(_Tp&&...) _NOEXCEPT {}
template <class _Tp> template <class _Tp>
@ -359,7 +360,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
: public __tuple_leaf<_Indx, _Tp>... : public __tuple_leaf<_Indx, _Tp>...
{ {
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
_LIBCPP_CONSTEXPR __tuple_impl() constexpr __tuple_impl()
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
template <size_t ..._Uf, class ..._Tf, template <size_t ..._Uf, class ..._Tf,
@ -377,7 +378,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
template <class _Alloc, size_t ..._Uf, class ..._Tf, template <class _Alloc, size_t ..._Uf, class ..._Tf,
size_t ..._Ul, class ..._Tl, class ..._Up> size_t ..._Ul, class ..._Tl, class ..._Up>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
explicit explicit
__tuple_impl(allocator_arg_t, const _Alloc& __a, __tuple_impl(allocator_arg_t, const _Alloc& __a,
__tuple_indices<_Uf...>, __tuple_types<_Tf...>, __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
@ -407,7 +408,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
__tuple_constructible<_Tuple, tuple<_Tp...> >::value __tuple_constructible<_Tuple, tuple<_Tp...> >::value
>::type >::type
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
__tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
: __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx, : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
typename __make_tuple_types<_Tuple>::type>::type>(), __a, typename __make_tuple_types<_Tuple>::type>::type>(), __a,
@ -418,7 +419,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
__tuple_impl(const __tuple_impl&) = default; __tuple_impl(const __tuple_impl&) = default;
__tuple_impl(__tuple_impl&&) = default; __tuple_impl(__tuple_impl&&) = default;
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
void swap(__tuple_impl& __t) void swap(__tuple_impl& __t)
_NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{ {
@ -427,13 +428,13 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
}; };
template<class _Dest, class _Source, size_t ..._Np> template<class _Dest, class _Source, size_t ..._Np>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) { void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
_VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...); _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
} }
template<class _Dest, class _Source, class ..._Up, size_t ..._Np> template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) { void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
_VSTD::__swallow((( _VSTD::__swallow(((
_VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source)) _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
@ -619,14 +620,14 @@ public:
template <bool _Dummy = true, _EnableIf< template <bool _Dummy = true, _EnableIf<
_CheckArgsConstructor<_Dummy>::__enable_implicit_default() _CheckArgsConstructor<_Dummy>::__enable_implicit_default()
, void*> = nullptr> , void*> = nullptr>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY constexpr
tuple() tuple()
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
template <bool _Dummy = true, _EnableIf< template <bool _Dummy = true, _EnableIf<
_CheckArgsConstructor<_Dummy>::__enable_explicit_default() _CheckArgsConstructor<_Dummy>::__enable_explicit_default()
, void*> = nullptr> , void*> = nullptr>
explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit _LIBCPP_INLINE_VISIBILITY constexpr
tuple() tuple()
_NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {} _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
@ -637,7 +638,7 @@ public:
_CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default() _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default()
, void*> = nullptr , void*> = nullptr
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(_AllocArgT, _Alloc const& __a) tuple(_AllocArgT, _Alloc const& __a)
: __base_(allocator_arg_t(), __a, : __base_(allocator_arg_t(), __a,
__tuple_indices<>(), __tuple_types<>(), __tuple_indices<>(), __tuple_types<>(),
@ -648,7 +649,7 @@ public:
_CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value>::__enable_explicit_default() _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value>::__enable_explicit_default()
, void*> = nullptr , void*> = nullptr
> >
explicit _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(_AllocArgT, _Alloc const& __a) tuple(_AllocArgT, _Alloc const& __a)
: __base_(allocator_arg_t(), __a, : __base_(allocator_arg_t(), __a,
__tuple_indices<>(), __tuple_types<>(), __tuple_indices<>(), __tuple_types<>(),
@ -700,7 +701,7 @@ public:
bool bool
>::type = false >::type = false
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
: __base_(allocator_arg_t(), __a, : __base_(allocator_arg_t(), __a,
typename __make_tuple_indices<sizeof...(_Tp)>::type(), typename __make_tuple_indices<sizeof...(_Tp)>::type(),
@ -719,7 +720,7 @@ public:
bool bool
>::type = false >::type = false
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
explicit explicit
tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
: __base_(allocator_arg_t(), __a, : __base_(allocator_arg_t(), __a,
@ -806,7 +807,7 @@ public:
bool bool
>::type = false >::type = false
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
: __base_(allocator_arg_t(), __a, : __base_(allocator_arg_t(), __a,
typename __make_tuple_indices<sizeof...(_Up)>::type(), typename __make_tuple_indices<sizeof...(_Up)>::type(),
@ -825,7 +826,7 @@ public:
bool bool
>::type = false >::type = false
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
explicit explicit
tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
: __base_(allocator_arg_t(), __a, : __base_(allocator_arg_t(), __a,
@ -865,7 +866,7 @@ public:
bool bool
>::type = false >::type = false
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
: __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
@ -878,13 +879,13 @@ public:
bool bool
>::type = false >::type = false
> >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
explicit explicit
tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
: __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
// [tuple.assign] // [tuple.assign]
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple) tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
_NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value)) _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
{ {
@ -893,7 +894,7 @@ public:
return *this; return *this;
} }
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
_NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value)) _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
{ {
@ -909,7 +910,7 @@ public:
is_assignable<_Tp&, _Up const&>... is_assignable<_Tp&, _Up const&>...
>::value >::value
,int> = 0> ,int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(tuple<_Up...> const& __tuple) tuple& operator=(tuple<_Up...> const& __tuple)
_NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value)) _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
{ {
@ -924,7 +925,7 @@ public:
is_assignable<_Tp&, _Up>... is_assignable<_Tp&, _Up>...
>::value >::value
,int> = 0> ,int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(tuple<_Up...>&& __tuple) tuple& operator=(tuple<_Up...>&& __tuple)
_NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value)) _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
{ {
@ -941,7 +942,7 @@ public:
is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&> is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
>::value >::value
,int> = 0> ,int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(pair<_Up1, _Up2> const& __pair) tuple& operator=(pair<_Up1, _Up2> const& __pair)
_NOEXCEPT_((_And< _NOEXCEPT_((_And<
is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>, is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
@ -960,7 +961,7 @@ public:
is_assignable<_SecondType<_Tp..., _Dep>&, _Up2> is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
>::value >::value
,int> = 0> ,int> = 0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(pair<_Up1, _Up2>&& __pair) tuple& operator=(pair<_Up1, _Up2>&& __pair)
_NOEXCEPT_((_And< _NOEXCEPT_((_And<
is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>, is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
@ -979,7 +980,7 @@ public:
is_assignable<_Tp&, _Up const&>... is_assignable<_Tp&, _Up const&>...
>::value >::value
> > > >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(array<_Up, _Np> const& __array) tuple& operator=(array<_Up, _Np> const& __array)
_NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value)) _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
{ {
@ -995,7 +996,7 @@ public:
is_assignable<_Tp&, _Up>... is_assignable<_Tp&, _Up>...
>::value >::value
> > > >
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple& operator=(array<_Up, _Np>&& __array) tuple& operator=(array<_Up, _Np>&& __array)
_NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value)) _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
{ {
@ -1006,7 +1007,7 @@ public:
} }
// [tuple.swap] // [tuple.swap]
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{__base_.swap(__t.__base_);} {__base_.swap(__t.__base_);}
}; };
@ -1015,21 +1016,21 @@ template <>
class _LIBCPP_TEMPLATE_VIS tuple<> class _LIBCPP_TEMPLATE_VIS tuple<>
{ {
public: public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY constexpr
_LIBCPP_CONSTEXPR tuple() _NOEXCEPT = default; tuple() _NOEXCEPT = default;
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {} tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
template <class _Alloc> template <class _Alloc>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {} tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
template <class _Up> template <class _Up>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(array<_Up, 0>) _NOEXCEPT {} tuple(array<_Up, 0>) _NOEXCEPT {}
template <class _Alloc, class _Up> template <class _Alloc, class _Up>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {} tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
void swap(tuple&) _NOEXCEPT {} void swap(tuple&) _NOEXCEPT {}
}; };
@ -1047,7 +1048,7 @@ tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
#endif #endif
template <class ..._Tp> template <class ..._Tp>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
typename enable_if typename enable_if
< <
__all<__is_swappable<_Tp>::value...>::value, __all<__is_swappable<_Tp>::value...>::value,

View File

@ -76,15 +76,15 @@ struct pair
template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14 template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14
template <class... Args1, class... Args2> template <class... Args1, class... Args2>
pair(piecewise_construct_t, tuple<Args1...> first_args, pair(piecewise_construct_t, tuple<Args1...> first_args,
tuple<Args2...> second_args); tuple<Args2...> second_args); // constexpr in C++20
template <class U, class V> pair& operator=(const pair<U, V>& p); template <class U, class V> pair& operator=(const pair<U, V>& p); // constexpr in C++20
pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value && pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
is_nothrow_move_assignable<T2>::value); is_nothrow_move_assignable<T2>::value); // constexpr in C++20
template <class U, class V> pair& operator=(pair<U, V>&& p); template <class U, class V> pair& operator=(pair<U, V>&& p); // constexpr in C++20
void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> && void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
is_nothrow_swappable_v<T2>); is_nothrow_swappable_v<T2>); // constexpr in C++20
}; };
template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14 template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
@ -94,10 +94,10 @@ template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,
template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14 template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14 template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14 template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14
template <class T1, class T2> template <class T1, class T2>
void void
swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();

View File

@ -56,7 +56,7 @@ __cpp_lib_constexpr_functional 201907L <functional>
__cpp_lib_constexpr_iterator 201811L <iterator> __cpp_lib_constexpr_iterator 201811L <iterator>
__cpp_lib_constexpr_memory 201811L <memory> __cpp_lib_constexpr_memory 201811L <memory>
__cpp_lib_constexpr_numeric 201911L <numeric> __cpp_lib_constexpr_numeric 201911L <numeric>
__cpp_lib_constexpr_string 201907L <string> __cpp_lib_constexpr_string 201811L <string>
__cpp_lib_constexpr_string_view 201811L <string_view> __cpp_lib_constexpr_string_view 201811L <string_view>
__cpp_lib_constexpr_tuple 201811L <tuple> __cpp_lib_constexpr_tuple 201811L <tuple>
__cpp_lib_constexpr_utility 201811L <utility> __cpp_lib_constexpr_utility 201811L <utility>
@ -303,12 +303,12 @@ __cpp_lib_void_t 201411L <type_traits>
// # define __cpp_lib_constexpr_complex 201711L // # define __cpp_lib_constexpr_complex 201711L
# define __cpp_lib_constexpr_dynamic_alloc 201907L # define __cpp_lib_constexpr_dynamic_alloc 201907L
# define __cpp_lib_constexpr_functional 201907L # define __cpp_lib_constexpr_functional 201907L
// # define __cpp_lib_constexpr_iterator 201811L # define __cpp_lib_constexpr_iterator 201811L
# define __cpp_lib_constexpr_memory 201811L # define __cpp_lib_constexpr_memory 201811L
# define __cpp_lib_constexpr_numeric 201911L # define __cpp_lib_constexpr_numeric 201911L
// # define __cpp_lib_constexpr_string 201907L # define __cpp_lib_constexpr_string 201811L
// # define __cpp_lib_constexpr_string_view 201811L # define __cpp_lib_constexpr_string_view 201811L
// # define __cpp_lib_constexpr_tuple 201811L # define __cpp_lib_constexpr_tuple 201811L
# define __cpp_lib_constexpr_utility 201811L # define __cpp_lib_constexpr_utility 201811L
// # define __cpp_lib_constexpr_vector 201907L // # define __cpp_lib_constexpr_vector 201907L
// # define __cpp_lib_coroutine 201902L // # define __cpp_lib_coroutine 201902L

View File

@ -19,7 +19,8 @@
int main(int, char**) int main(int, char**)
{ {
std::back_insert_iterator<std::vector<int> > i = std::vector<int>(); std::vector<int> v;
std::back_insert_iterator<std::vector<int> > i = v;
return 0; return 0;
} }

View File

@ -15,12 +15,13 @@
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert> #include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::back_insert_iterator<C> i(c); std::back_insert_iterator<C> i(c);
@ -28,12 +29,16 @@ test(C c)
r = 0; r = 0;
assert(c.size() == 1); assert(c.size() == 1);
assert(c.back() == 0); assert(c.back() == 0);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,26 +12,31 @@
// back_insert_iterator<Cont>& operator++(); // back_insert_iterator<Cont>& operator++();
#include <cassert>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::back_insert_iterator<C> i(c); std::back_insert_iterator<C> i(c);
std::back_insert_iterator<C>& r = ++i; std::back_insert_iterator<C>& r = ++i;
assert(&r == &i); assert(&r == &i);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -19,15 +19,17 @@
#include <cassert> #include <cassert>
#include "test_macros.h" #include "test_macros.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX14 bool
test(C c) test(C c)
{ {
const typename C::value_type v = typename C::value_type(); const typename C::value_type v = typename C::value_type();
std::back_insert_iterator<C> i(c); std::back_insert_iterator<C> i(c);
i = v; i = v;
assert(c.back() == v); assert(c.back() == v);
return true;
} }
class Copyable class Copyable
@ -44,6 +46,9 @@ public:
int main(int, char**) int main(int, char**)
{ {
test(std::vector<Copyable>()); test(std::vector<Copyable>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -23,19 +23,24 @@
#include <cassert> #include <cassert>
#include "test_macros.h" #include "test_macros.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX14 bool
test(C c) test(C c)
{ {
std::back_insert_iterator<C> i(c); std::back_insert_iterator<C> i(c);
i = typename C::value_type(); i = typename C::value_type();
assert(c.back() == typename C::value_type()); assert(c.back() == typename C::value_type());
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<std::unique_ptr<int> >()); test(std::vector<std::unique_ptr<int> >());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,26 +12,31 @@
// back_insert_iterator<Cont>& operator*(); // back_insert_iterator<Cont>& operator*();
#include <cassert>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::back_insert_iterator<C> i(c); std::back_insert_iterator<C> i(c);
std::back_insert_iterator<C>& r = *i; std::back_insert_iterator<C>& r = *i;
assert(&r == &i); assert(&r == &i);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -19,7 +19,8 @@
int main(int, char**) int main(int, char**)
{ {
std::front_insert_iterator<std::list<int> > i = std::list<int>(); std::list<int> l;
std::front_insert_iterator<std::list<int> > i = l;
return 0; return 0;
} }

View File

@ -14,21 +14,26 @@
#include <iterator> #include <iterator>
#include <list> #include <list>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::front_insert_iterator<C> i(c); std::front_insert_iterator<C> i(c);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::list<int>()); test(std::list<int>());
test(nasty_list<int>()); test(nasty_list<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,15 +12,16 @@
// front_insert_iterator<Cont> operator++(int); // front_insert_iterator<Cont> operator++(int);
#include <cassert>
#include <iterator> #include <iterator>
#include <list> #include <list>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::front_insert_iterator<C> i(c); std::front_insert_iterator<C> i(c);
@ -28,12 +29,16 @@ test(C c)
r = 0; r = 0;
assert(c.size() == 1); assert(c.size() == 1);
assert(c.back() == 0); assert(c.back() == 0);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::list<int>()); test(std::list<int>());
test(nasty_list<int>()); test(nasty_list<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,26 +12,31 @@
// front_insert_iterator<Cont>& operator++(); // front_insert_iterator<Cont>& operator++();
#include <cassert>
#include <iterator> #include <iterator>
#include <list> #include <list>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::front_insert_iterator<C> i(c); std::front_insert_iterator<C> i(c);
std::front_insert_iterator<C>& r = ++i; std::front_insert_iterator<C>& r = ++i;
assert(&r == &i); assert(&r == &i);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::list<int>()); test(std::list<int>());
test(nasty_list<int>()); test(nasty_list<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -13,21 +13,23 @@
// front_insert_iterator<Cont>& // front_insert_iterator<Cont>&
// operator=(const Cont::value_type& value); // operator=(const Cont::value_type& value);
#include <cassert>
#include <iterator> #include <iterator>
#include <list> #include <list>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
const typename C::value_type v = typename C::value_type(); const typename C::value_type v = typename C::value_type();
std::front_insert_iterator<C> i(c); std::front_insert_iterator<C> i(c);
i = v; i = v;
assert(c.front() == v); assert(c.front() == v);
return true;
} }
class Copyable class Copyable
@ -45,6 +47,9 @@ int main(int, char**)
{ {
test(std::list<Copyable>()); test(std::list<Copyable>());
test(nasty_list<Copyable>()); test(nasty_list<Copyable>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -15,25 +15,30 @@
// front_insert_iterator<Cont>& // front_insert_iterator<Cont>&
// operator=(Cont::value_type&& value); // operator=(Cont::value_type&& value);
#include <cassert>
#include <iterator> #include <iterator>
#include <list> #include <list>
#include <memory> #include <memory>
#include <cassert>
#include "test_macros.h" #include "test_macros.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::front_insert_iterator<C> i(c); std::front_insert_iterator<C> i(c);
i = typename C::value_type(); i = typename C::value_type();
assert(c.front() == typename C::value_type()); assert(c.front() == typename C::value_type());
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::list<std::unique_ptr<int> >()); test(std::list<std::unique_ptr<int> >());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,26 +12,31 @@
// front_insert_iterator<Cont>& operator*(); // front_insert_iterator<Cont>& operator*();
#include <cassert>
#include <iterator> #include <iterator>
#include <list> #include <list>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::front_insert_iterator<C> i(c); std::front_insert_iterator<C> i(c);
std::front_insert_iterator<C>& r = *i; std::front_insert_iterator<C>& r = *i;
assert(&r == &i); assert(&r == &i);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::list<int>()); test(std::list<int>());
test(nasty_list<int>()); test(nasty_list<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,27 +12,32 @@
// front_insert_iterator<Cont> // front_insert_iterator<Cont>
// front_inserter(Cont& x); // front_inserter(Cont& x);
#include <cassert>
#include <iterator> #include <iterator>
#include <list> #include <list>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::front_insert_iterator<C> i = std::front_inserter(c); std::front_insert_iterator<C> i = std::front_inserter(c);
i = 0; i = 0;
assert(c.size() == 1); assert(c.size() == 1);
assert(c.front() == 0); assert(c.front() == 0);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::list<int>()); test(std::list<int>());
test(nasty_list<int>()); test(nasty_list<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -14,21 +14,26 @@
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::insert_iterator<C> i(c, c.begin()); std::insert_iterator<C> i(c, c.begin());
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,15 +12,16 @@
// insert_iterator<Cont> operator++(int); // insert_iterator<Cont> operator++(int);
#include <cassert>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::insert_iterator<C> i(c, c.end()); std::insert_iterator<C> i(c, c.end());
@ -28,12 +29,16 @@ test(C c)
r = 0; r = 0;
assert(c.size() == 1); assert(c.size() == 1);
assert(c.back() == 0); assert(c.back() == 0);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,26 +12,31 @@
// insert_iterator<Cont>& operator++(); // insert_iterator<Cont>& operator++();
#include <cassert>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::insert_iterator<C> i(c, c.end()); std::insert_iterator<C> i(c, c.end());
std::insert_iterator<C>& r = ++i; std::insert_iterator<C>& r = ++i;
assert(&r == &i); assert(&r == &i);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,26 +12,31 @@
// insert_iterator<Cont>& operator*(); // insert_iterator<Cont>& operator*();
#include <cassert>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::insert_iterator<C> i(c, c.end()); std::insert_iterator<C> i(c, c.end());
std::insert_iterator<C>& r = *i; std::insert_iterator<C>& r = *i;
assert(&r == &i); assert(&r == &i);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -12,27 +12,32 @@
// insert_iterator<Cont> // insert_iterator<Cont>
// inserter(Cont& x, Cont::iterator i); // inserter(Cont& x, Cont::iterator i);
#include <cassert>
#include <iterator> #include <iterator>
#include <vector> #include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h" #include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C> template <class C>
void TEST_CONSTEXPR_CXX20 bool
test(C c) test(C c)
{ {
std::insert_iterator<C> i = std::inserter(c, c.end()); std::insert_iterator<C> i = std::inserter(c, c.end());
i = 0; i = 0;
assert(c.size() == 1); assert(c.size() == 1);
assert(c.back() == 0); assert(c.back() == 0);
return true;
} }
int main(int, char**) int main(int, char**)
{ {
test(std::vector<int>()); test(std::vector<int>());
test(nasty_vector<int>()); test(nasty_vector<int>());
#if TEST_STD_VER >= 20
return 0; test(ConstexprFixedCapacityDeque<int, 10>());
static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
#endif
return 0;
} }

View File

@ -146,17 +146,11 @@
# error "__cpp_lib_array_constexpr should have the value 201811L in c++20" # error "__cpp_lib_array_constexpr should have the value 201811L in c++20"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_iterator
# ifndef __cpp_lib_constexpr_iterator # error "__cpp_lib_constexpr_iterator should be defined in c++20"
# error "__cpp_lib_constexpr_iterator should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_iterator != 201811L
# if __cpp_lib_constexpr_iterator != 201811L # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_make_reverse_iterator # ifndef __cpp_lib_make_reverse_iterator
@ -209,17 +203,11 @@
# error "__cpp_lib_array_constexpr should have the value 201811L in c++2b" # error "__cpp_lib_array_constexpr should have the value 201811L in c++2b"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_iterator
# ifndef __cpp_lib_constexpr_iterator # error "__cpp_lib_constexpr_iterator should be defined in c++2b"
# error "__cpp_lib_constexpr_iterator should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_iterator != 201811L
# if __cpp_lib_constexpr_iterator != 201811L # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_make_reverse_iterator # ifndef __cpp_lib_make_reverse_iterator

View File

@ -18,7 +18,7 @@
/* Constant Value /* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L [C++17] __cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
__cpp_lib_char8_t 201811L [C++20] __cpp_lib_char8_t 201811L [C++20]
__cpp_lib_constexpr_string 201907L [C++20] __cpp_lib_constexpr_string 201811L [C++20]
__cpp_lib_erase_if 202002L [C++20] __cpp_lib_erase_if 202002L [C++20]
__cpp_lib_nonmember_container_access 201411L [C++17] __cpp_lib_nonmember_container_access 201411L [C++17]
__cpp_lib_starts_ends_with 201711L [C++20] __cpp_lib_starts_ends_with 201711L [C++20]
@ -182,17 +182,11 @@
# endif # endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string
# ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++20"
# error "__cpp_lib_constexpr_string should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_string != 201811L
# if __cpp_lib_constexpr_string != 201907L # error "__cpp_lib_constexpr_string should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_string should have the value 201907L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_erase_if # ifndef __cpp_lib_erase_if
@ -256,17 +250,11 @@
# endif # endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string
# ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++2b"
# error "__cpp_lib_constexpr_string should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_string != 201811L
# if __cpp_lib_constexpr_string != 201907L # error "__cpp_lib_constexpr_string should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_string should have the value 201907L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_erase_if # ifndef __cpp_lib_erase_if

View File

@ -111,17 +111,11 @@
# endif # endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string_view
# ifndef __cpp_lib_constexpr_string_view # error "__cpp_lib_constexpr_string_view should be defined in c++20"
# error "__cpp_lib_constexpr_string_view should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_string_view != 201811L
# if __cpp_lib_constexpr_string_view != 201811L # error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_starts_ends_with # ifndef __cpp_lib_starts_ends_with
@ -157,17 +151,11 @@
# endif # endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string_view
# ifndef __cpp_lib_constexpr_string_view # error "__cpp_lib_constexpr_string_view should be defined in c++2b"
# error "__cpp_lib_constexpr_string_view should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_string_view != 201811L
# if __cpp_lib_constexpr_string_view != 201811L # error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_starts_ends_with # ifndef __cpp_lib_starts_ends_with

View File

@ -119,17 +119,11 @@
# error "__cpp_lib_apply should have the value 201603L in c++20" # error "__cpp_lib_apply should have the value 201603L in c++20"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_tuple
# ifndef __cpp_lib_constexpr_tuple # error "__cpp_lib_constexpr_tuple should be defined in c++20"
# error "__cpp_lib_constexpr_tuple should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_tuple != 201811L
# if __cpp_lib_constexpr_tuple != 201811L # error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_make_from_tuple # ifndef __cpp_lib_make_from_tuple
@ -162,17 +156,11 @@
# error "__cpp_lib_apply should have the value 201603L in c++2b" # error "__cpp_lib_apply should have the value 201603L in c++2b"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_tuple
# ifndef __cpp_lib_constexpr_tuple # error "__cpp_lib_constexpr_tuple should be defined in c++2b"
# error "__cpp_lib_constexpr_tuple should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_tuple != 201811L
# if __cpp_lib_constexpr_tuple != 201811L # error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_make_from_tuple # ifndef __cpp_lib_make_from_tuple

View File

@ -53,7 +53,7 @@
__cpp_lib_constexpr_iterator 201811L [C++20] __cpp_lib_constexpr_iterator 201811L [C++20]
__cpp_lib_constexpr_memory 201811L [C++20] __cpp_lib_constexpr_memory 201811L [C++20]
__cpp_lib_constexpr_numeric 201911L [C++20] __cpp_lib_constexpr_numeric 201911L [C++20]
__cpp_lib_constexpr_string 201907L [C++20] __cpp_lib_constexpr_string 201811L [C++20]
__cpp_lib_constexpr_string_view 201811L [C++20] __cpp_lib_constexpr_string_view 201811L [C++20]
__cpp_lib_constexpr_tuple 201811L [C++20] __cpp_lib_constexpr_tuple 201811L [C++20]
__cpp_lib_constexpr_utility 201811L [C++20] __cpp_lib_constexpr_utility 201811L [C++20]
@ -2436,17 +2436,11 @@
# error "__cpp_lib_constexpr_functional should have the value 201907L in c++20" # error "__cpp_lib_constexpr_functional should have the value 201907L in c++20"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_iterator
# ifndef __cpp_lib_constexpr_iterator # error "__cpp_lib_constexpr_iterator should be defined in c++20"
# error "__cpp_lib_constexpr_iterator should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_iterator != 201811L
# if __cpp_lib_constexpr_iterator != 201811L # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_constexpr_memory # ifndef __cpp_lib_constexpr_memory
@ -2463,43 +2457,25 @@
# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20" # error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string
# ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++20"
# error "__cpp_lib_constexpr_string should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_string != 201811L
# if __cpp_lib_constexpr_string != 201907L # error "__cpp_lib_constexpr_string should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_string should have the value 201907L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string_view
# ifndef __cpp_lib_constexpr_string_view # error "__cpp_lib_constexpr_string_view should be defined in c++20"
# error "__cpp_lib_constexpr_string_view should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_string_view != 201811L
# if __cpp_lib_constexpr_string_view != 201811L # error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_tuple
# ifndef __cpp_lib_constexpr_tuple # error "__cpp_lib_constexpr_tuple should be defined in c++20"
# error "__cpp_lib_constexpr_tuple should be defined in c++20" # endif
# endif # if __cpp_lib_constexpr_tuple != 201811L
# if __cpp_lib_constexpr_tuple != 201811L # error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_constexpr_utility # ifndef __cpp_lib_constexpr_utility
@ -3647,17 +3623,11 @@
# error "__cpp_lib_constexpr_functional should have the value 201907L in c++2b" # error "__cpp_lib_constexpr_functional should have the value 201907L in c++2b"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_iterator
# ifndef __cpp_lib_constexpr_iterator # error "__cpp_lib_constexpr_iterator should be defined in c++2b"
# error "__cpp_lib_constexpr_iterator should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_iterator != 201811L
# if __cpp_lib_constexpr_iterator != 201811L # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_constexpr_memory # ifndef __cpp_lib_constexpr_memory
@ -3674,43 +3644,25 @@
# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++2b" # error "__cpp_lib_constexpr_numeric should have the value 201911L in c++2b"
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string
# ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++2b"
# error "__cpp_lib_constexpr_string should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_string != 201811L
# if __cpp_lib_constexpr_string != 201907L # error "__cpp_lib_constexpr_string should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_string should have the value 201907L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_string_view
# ifndef __cpp_lib_constexpr_string_view # error "__cpp_lib_constexpr_string_view should be defined in c++2b"
# error "__cpp_lib_constexpr_string_view should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_string_view != 201811L
# if __cpp_lib_constexpr_string_view != 201811L # error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_constexpr_tuple
# ifndef __cpp_lib_constexpr_tuple # error "__cpp_lib_constexpr_tuple should be defined in c++2b"
# error "__cpp_lib_constexpr_tuple should be defined in c++2b" # endif
# endif # if __cpp_lib_constexpr_tuple != 201811L
# if __cpp_lib_constexpr_tuple != 201811L # error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
# endif
# endif # endif
# ifndef __cpp_lib_constexpr_utility # ifndef __cpp_lib_constexpr_utility

View File

@ -6,6 +6,9 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// XFAIL: gcc-10
// GCC's __builtin_strlen isn't constexpr yet
// <string_view> // <string_view>
// size_type copy(charT* s, size_type n, size_type pos = 0) const; // size_type copy(charT* s, size_type n, size_type pos = 0) const;
@ -74,7 +77,16 @@ void test ( const CharT *s ) {
test1(sv1, sv1.size() + 1, 0); test1(sv1, sv1.size() + 1, 0);
test1(sv1, sv1.size() + 1, 1); test1(sv1, sv1.size() + 1, 1);
test1(sv1, sv1.size() + 1, string_view_t::npos); test1(sv1, sv1.size() + 1, string_view_t::npos);
}
template<typename CharT>
TEST_CONSTEXPR_CXX20 bool test_constexpr_copy(const CharT *abcde, const CharT *ghijk, const CharT *bcdjk)
{
CharT buf[6] = {};
std::basic_string_view<CharT> lval(ghijk); lval.copy(buf, 6);
std::basic_string_view<CharT>(abcde).copy(buf, 3, 1);
assert(std::basic_string_view<CharT>(buf) == bcdjk);
return true;
} }
int main(int, char**) { int main(int, char**) {
@ -100,5 +112,22 @@ int main(int, char**) {
test ( U"" ); test ( U"" );
#endif #endif
test_constexpr_copy("ABCDE", "GHIJK", "BCDJK");
test_constexpr_copy(L"ABCDE", L"GHIJK", L"BCDJK");
#if TEST_STD_VER >= 11
test_constexpr_copy(u"ABCDE", u"GHIJK", u"BCDJK");
test_constexpr_copy(U"ABCDE", U"GHIJK", U"BCDJK");
#endif
#if TEST_STD_VER >= 17
test_constexpr_copy(u8"ABCDE", u8"GHIJK", u8"BCDJK");
#endif
#if TEST_STD_VER >= 20
static_assert(test_constexpr_copy("ABCDE", "GHIJK", "BCDJK"));
static_assert(test_constexpr_copy(L"ABCDE", L"GHIJK", L"BCDJK"));
static_assert(test_constexpr_copy(u"ABCDE", u"GHIJK", u"BCDJK"));
static_assert(test_constexpr_copy(U"ABCDE", U"GHIJK", U"BCDJK"));
static_assert(test_constexpr_copy(u8"ABCDE", u8"GHIJK", u8"BCDJK"));
#endif
return 0; return 0;
} }

View File

@ -30,7 +30,8 @@ struct PotentiallyThrowingCopyAssignable {
#include "test_macros.h" #include "test_macros.h"
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
{ {
typedef std::pair<long, char> T0; typedef std::pair<long, char> T0;
@ -41,6 +42,16 @@ int main(int, char**)
assert(std::get<0>(t1) == 2); assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == short('a')); assert(std::get<1>(t1) == short('a'));
} }
return true;
}
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
{ {
// test that the implicitly generated copy assignment operator // test that the implicitly generated copy assignment operator
// is properly deleted // is properly deleted

View File

@ -21,35 +21,31 @@
#include "test_macros.h" #include "test_macros.h"
struct B struct B {
{
int id_; int id_;
explicit B(int i = 0) : id_(i) {} constexpr explicit B(int i = 0) : id_(i) {}
}; };
struct D struct D : B {
: B constexpr explicit D(int i = 0) : B(i) {}
{
explicit D(int i = 0) : B(i) {}
}; };
struct NonAssignable { struct NonAssignable {
NonAssignable& operator=(NonAssignable const&) = delete; NonAssignable& operator=(NonAssignable const&) = delete;
NonAssignable& operator=(NonAssignable&&) = delete; NonAssignable& operator=(NonAssignable&&) = delete;
}; };
struct NothrowCopyAssignable struct NothrowCopyAssignable {
{
NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; } NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
}; };
struct PotentiallyThrowingCopyAssignable struct PotentiallyThrowingCopyAssignable {
{
PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; } PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
}; };
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
{ {
typedef std::tuple<long> T0; typedef std::tuple<long> T0;
@ -102,6 +98,16 @@ int main(int, char**)
assert(std::get<0>(t) == 43); assert(std::get<0>(t) == 43);
assert(&std::get<0>(t) == &x); assert(&std::get<0>(t) == &x);
} }
return true;
}
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
{ {
using T = std::tuple<int, NonAssignable>; using T = std::tuple<int, NonAssignable>;
using U = std::tuple<NonAssignable, int>; using U = std::tuple<NonAssignable, int>;
@ -116,6 +122,7 @@ int main(int, char**)
{ {
typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0; typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0;
typedef std::tuple<PotentiallyThrowingCopyAssignable, int> T1; typedef std::tuple<PotentiallyThrowingCopyAssignable, int> T1;
static_assert(std::is_assignable<T0&, T1 const&>::value, "");
static_assert(!std::is_nothrow_assignable<T0&, T1 const&>::value, ""); static_assert(!std::is_nothrow_assignable<T0&, T1 const&>::value, "");
} }

View File

@ -23,24 +23,19 @@
#include "test_macros.h" #include "test_macros.h"
struct B struct B {
{
int id_; int id_;
explicit B(int i = 0) : id_(i) {}
explicit B(int i= 0) : id_(i) {}
virtual ~B() {} virtual ~B() {}
}; };
struct D struct D : B {
: B
{
explicit D(int i) : B(i) {} explicit D(int i) : B(i) {}
}; };
struct E { struct E {
E() = default; constexpr E() = default;
E& operator=(int) { TEST_CONSTEXPR_CXX14 E& operator=(int) {
return *this; return *this;
} }
}; };
@ -92,7 +87,8 @@ struct TrackMove
bool moved_from; bool moved_from;
}; };
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
{ {
typedef std::tuple<long> T0; typedef std::tuple<long> T0;
@ -111,6 +107,29 @@ int main(int, char**)
assert(std::get<0>(t1) == 2); assert(std::get<0>(t1) == 2);
assert(std::get<1>(t1) == int('a')); assert(std::get<1>(t1) == int('a'));
} }
{
// Test that tuple evaluates correctly applies an lvalue reference
// before evaluating is_assignable (i.e. 'is_assignable<int&, int&&>')
// instead of evaluating 'is_assignable<int&&, int&&>' which is false.
int x = 42;
int y = 43;
std::tuple<int&&, E> t(std::move(x), E{});
std::tuple<int&&, int> t2(std::move(y), 44);
t = std::move(t2);
assert(std::get<0>(t) == 43);
assert(&std::get<0>(t) == &x);
}
return true;
}
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
{ {
typedef std::tuple<long, char, D> T0; typedef std::tuple<long, char, D> T0;
typedef std::tuple<long long, int, B> T1; typedef std::tuple<long long, int, B> T1;
@ -143,18 +162,7 @@ int main(int, char**)
assert(std::get<1>(t1) == int('a')); assert(std::get<1>(t1) == int('a'));
assert(std::get<2>(t1)->id_ == 3); assert(std::get<2>(t1)->id_ == 3);
} }
{
// Test that tuple evaluates correctly applies an lvalue reference
// before evaluating is_assignable (i.e. 'is_assignable<int&, int&&>')
// instead of evaluating 'is_assignable<int&&, int&&>' which is false.
int x = 42;
int y = 43;
std::tuple<int&&, E> t(std::move(x), E{});
std::tuple<int&&, int> t2(std::move(y), 44);
t = std::move(t2);
assert(std::get<0>(t) == 43);
assert(&std::get<0>(t) == &x);
}
{ {
using T = std::tuple<int, NonAssignable>; using T = std::tuple<int, NonAssignable>;
using U = std::tuple<NonAssignable, int>; using U = std::tuple<NonAssignable, int>;
@ -169,6 +177,7 @@ int main(int, char**)
{ {
typedef std::tuple<PotentiallyThrowingMoveAssignable, long> T0; typedef std::tuple<PotentiallyThrowingMoveAssignable, long> T0;
typedef std::tuple<PotentiallyThrowingMoveAssignable, int> T1; typedef std::tuple<PotentiallyThrowingMoveAssignable, int> T1;
static_assert(std::is_assignable<T0&, T1&&>::value, "");
static_assert(!std::is_nothrow_assignable<T0&, T1&&>::value, ""); static_assert(!std::is_nothrow_assignable<T0&, T1&&>::value, "");
} }
{ {

View File

@ -45,7 +45,8 @@ struct CopyAssignableInt {
CopyAssignableInt& operator=(int&) { return *this; } CopyAssignableInt& operator=(int&) { return *this; }
}; };
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
{ {
typedef std::tuple<> T; typedef std::tuple<> T;
@ -68,15 +69,6 @@ int main(int, char**)
assert(std::get<0>(t) == 2); assert(std::get<0>(t) == 2);
assert(std::get<1>(t) == 'a'); assert(std::get<1>(t) == 'a');
} }
{
typedef std::tuple<int, char, std::string> T;
const T t0(2, 'a', "some text");
T t;
t = t0;
assert(std::get<0>(t) == 2);
assert(std::get<1>(t) == 'a');
assert(std::get<2>(t) == "some text");
}
{ {
// test reference assignment. // test reference assignment.
using T = std::tuple<int&, int&&>; using T = std::tuple<int&, int&&>;
@ -92,6 +84,27 @@ int main(int, char**)
assert(std::get<1>(t) == y2); assert(std::get<1>(t) == y2);
assert(&std::get<1>(t) == &y); assert(&std::get<1>(t) == &y);
} }
return true;
}
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
{
// cannot be constexpr because of std::string
typedef std::tuple<int, char, std::string> T;
const T t0(2, 'a', "some text");
T t;
t = t0;
assert(std::get<0>(t) == 2);
assert(std::get<1>(t) == 'a');
assert(std::get<2>(t) == "some text");
}
{ {
// test that the implicitly generated copy assignment operator // test that the implicitly generated copy assignment operator
// is properly deleted // is properly deleted
@ -99,8 +112,8 @@ int main(int, char**)
static_assert(!std::is_copy_assignable<T>::value, ""); static_assert(!std::is_copy_assignable<T>::value, "");
} }
{ {
using T = std::tuple<int, NonAssignable>; using T = std::tuple<int, NonAssignable>;
static_assert(!std::is_copy_assignable<T>::value, ""); static_assert(!std::is_copy_assignable<T>::value, "");
} }
{ {
using T = std::tuple<int, CopyAssignable>; using T = std::tuple<int, CopyAssignable>;
@ -132,6 +145,7 @@ int main(int, char**)
} }
{ {
using T = std::tuple<PotentiallyThrowingCopyAssignable, int>; using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;
static_assert(std::is_copy_assignable<T>::value, "");
static_assert(!std::is_nothrow_copy_assignable<T>::value, ""); static_assert(!std::is_nothrow_copy_assignable<T>::value, "");
} }

View File

@ -53,7 +53,8 @@ struct CountAssign {
int CountAssign::copied = 0; int CountAssign::copied = 0;
int CountAssign::moved = 0; int CountAssign::moved = 0;
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
{ {
typedef std::tuple<> T; typedef std::tuple<> T;
@ -100,6 +101,16 @@ int main(int, char**)
assert(std::get<1>(t) == y2); assert(std::get<1>(t) == y2);
assert(&std::get<1>(t) == &y); assert(&std::get<1>(t) == &y);
} }
return true;
}
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
{ {
// test that the implicitly generated move assignment operator // test that the implicitly generated move assignment operator
// is properly deleted // is properly deleted
@ -108,8 +119,8 @@ int main(int, char**)
static_assert(!std::is_copy_assignable<T>::value, ""); static_assert(!std::is_copy_assignable<T>::value, "");
} }
{ {
using T = std::tuple<int, NonAssignable>; using T = std::tuple<int, NonAssignable>;
static_assert(!std::is_move_assignable<T>::value, ""); static_assert(!std::is_move_assignable<T>::value, "");
} }
{ {
using T = std::tuple<int, MoveAssignable>; using T = std::tuple<int, MoveAssignable>;

View File

@ -21,26 +21,36 @@
#include "test_macros.h" #include "test_macros.h"
TEST_CONSTEXPR_CXX20
bool test()
{
int i = 0;
float j = 0;
std::tuple<int, int&, float&> t =
std::make_tuple(1, std::ref(i), std::ref(j));
assert(std::get<0>(t) == 1);
assert(std::get<1>(t) == 0);
assert(std::get<2>(t) == 0);
i = 2;
j = 3.5;
assert(std::get<0>(t) == 1);
assert(std::get<1>(t) == 2);
assert(std::get<2>(t) == 3.5);
std::get<1>(t) = 0;
std::get<2>(t) = 0;
assert(i == 0);
assert(j == 0);
return true;
}
int main(int, char**) int main(int, char**)
{ {
{ test();
int i = 0; #if TEST_STD_VER >= 20
float j = 0; static_assert(test());
std::tuple<int, int&, float&> t = std::make_tuple(1, std::ref(i), #endif
std::ref(j));
assert(std::get<0>(t) == 1);
assert(std::get<1>(t) == 0);
assert(std::get<2>(t) == 0);
i = 2;
j = 3.5;
assert(std::get<0>(t) == 1);
assert(std::get<1>(t) == 2);
assert(std::get<2>(t) == 3.5);
std::get<1>(t) = 0;
std::get<2>(t) = 0;
assert(i == 0);
assert(j == 0);
}
#if TEST_STD_VER > 11 #if TEST_STD_VER > 11
{ {
constexpr auto t1 = std::make_tuple(0, 1, 3.14); constexpr auto t1 = std::make_tuple(0, 1, 3.14);
@ -51,5 +61,5 @@ int main(int, char**)
} }
#endif #endif
return 0; return 0;
} }

View File

@ -21,8 +21,9 @@
#include "test_macros.h" #include "test_macros.h"
#if TEST_STD_VER > 11 TEST_CONSTEXPR_CXX14
constexpr bool test_tie_constexpr() { bool test_tie()
{
{ {
int i = 42; int i = 42;
double f = 1.1; double f = 1.1;
@ -32,15 +33,23 @@ constexpr bool test_tie_constexpr() {
assert(&std::get<0>(res) == &i); assert(&std::get<0>(res) == &i);
assert(&std::get<1>(res) == &std::ignore); assert(&std::get<1>(res) == &std::ignore);
assert(&std::get<2>(res) == &f); assert(&std::get<2>(res) == &f);
// FIXME: If/when tuple gets constexpr assignment
//res = std::make_tuple(101, nullptr, -1.0); #if TEST_STD_VER >= 20
res = std::make_tuple(101, nullptr, -1.0);
assert(i == 101);
assert(f == -1.0);
#endif
} }
return true; return true;
} }
#endif
int main(int, char**) int main(int, char**)
{ {
test_tie();
#if TEST_STD_VER >= 14
static_assert(test_tie(), "");
#endif
{ {
int i = 0; int i = 0;
std::string s; std::string s;
@ -48,18 +57,6 @@ int main(int, char**)
assert(i == 42); assert(i == 42);
assert(s == "C++"); assert(s == "C++");
} }
#if TEST_STD_VER > 11
{
static constexpr int i = 42;
static constexpr double f = 1.1;
constexpr std::tuple<const int &, const double &> t = std::tie(i, f);
static_assert ( std::get<0>(t) == 42, "" );
static_assert ( std::get<1>(t) == 1.1, "" );
}
{
static_assert(test_tie_constexpr(), "");
}
#endif
return 0; return 0;
} }

View File

@ -20,7 +20,8 @@
#include "test_macros.h" #include "test_macros.h"
#include "MoveOnly.h" #include "MoveOnly.h"
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
{ {
typedef std::tuple<> T; typedef std::tuple<> T;
@ -58,6 +59,15 @@ int main(int, char**)
assert(std::get<1>(t1) == 1); assert(std::get<1>(t1) == 1);
assert(std::get<2>(t1) == 2); assert(std::get<2>(t1) == 2);
} }
return true;
return 0; }
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
return 0;
} }

View File

@ -26,9 +26,9 @@ class A
int i_; int i_;
char c_; char c_;
public: public:
A(int i, char c) : i_(i), c_(c) {} constexpr A(int i, char c) : i_(i), c_(c) {}
int get_i() const {return i_;} constexpr int get_i() const {return i_;}
char get_c() const {return c_;} constexpr char get_c() const {return c_;}
}; };
class B class B
@ -37,13 +37,14 @@ class B
unsigned u1_; unsigned u1_;
unsigned u2_; unsigned u2_;
public: public:
B(double d, unsigned u1, unsigned u2) : d_(d), u1_(u1), u2_(u2) {} constexpr explicit B(double d, unsigned u1, unsigned u2) : d_(d), u1_(u1), u2_(u2) {}
double get_d() const {return d_;} constexpr double get_d() const {return d_;}
unsigned get_u1() const {return u1_;} constexpr unsigned get_u1() const {return u1_;}
unsigned get_u2() const {return u2_;} constexpr unsigned get_u2() const {return u2_;}
}; };
int main(int, char**) TEST_CONSTEXPR_CXX20
bool test()
{ {
std::pair<A, B> p(std::piecewise_construct, std::pair<A, B> p(std::piecewise_construct,
std::make_tuple(4, 'a'), std::make_tuple(4, 'a'),
@ -54,5 +55,15 @@ int main(int, char**)
assert(p.second.get_u1() == 6u); assert(p.second.get_u1() == 6u);
assert(p.second.get_u2() == 2u); assert(p.second.get_u2() == 2u);
return 0; return true;
}
int main(int, char**)
{
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
return 0;
} }

View File

@ -0,0 +1,56 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef SUPPORT_TEST_CONSTEXPR_CONTAINER_H
#define SUPPORT_TEST_CONSTEXPR_CONTAINER_H
// A dummy container with enough constexpr support to test the standard
// insert iterators, such as `back_insert_iterator`.
#include <algorithm>
#include <cassert>
#include <utility>
#include "test_macros.h"
#if TEST_STD_VER >= 14
template<class T, int N>
class ConstexprFixedCapacityDeque {
T data_[N];
int size_ = 0;
public:
using value_type = T;
using iterator = T *;
using const_iterator = T const *;
constexpr ConstexprFixedCapacityDeque() = default;
constexpr iterator begin() { return data_; }
constexpr iterator end() { return data_ + size_; }
constexpr const_iterator begin() const { return data_; }
constexpr const_iterator end() const { return data_ + size_; }
constexpr size_t size() const { return size_; }
constexpr const T& front() const { assert(size_ >= 1); return data_[0]; }
constexpr const T& back() const { assert(size_ >= 1); return data_[size_-1]; }
constexpr iterator insert(const_iterator pos, T t) {
int i = (pos - data_);
if (i != size_) {
std::move_backward(data_ + i, data_ + size_, data_ + size_ + 1);
}
data_[i] = std::move(t);
size_ += 1;
return data_ + i;
}
constexpr void push_back(T t) { insert(end(), std::move(t)); }
constexpr void push_front(T t) { insert(begin(), std::move(t)); }
};
#endif // TEST_STD_VER >= 14
#endif // SUPPORT_TEST_CONSTEXPR_CONTAINER_H

View File

@ -198,7 +198,6 @@ feature_test_macros = [ add_version_header(x) for x in [
"name": "__cpp_lib_constexpr_iterator", "name": "__cpp_lib_constexpr_iterator",
"values": { "c++20": 201811 }, "values": { "c++20": 201811 },
"headers": ["iterator"], "headers": ["iterator"],
"unimplemented": True,
}, { }, {
"name": "__cpp_lib_constexpr_memory", "name": "__cpp_lib_constexpr_memory",
"values": { "c++20": 201811 }, "values": { "c++20": 201811 },
@ -209,19 +208,16 @@ feature_test_macros = [ add_version_header(x) for x in [
"headers": ["numeric"], "headers": ["numeric"],
}, { }, {
"name": "__cpp_lib_constexpr_string", "name": "__cpp_lib_constexpr_string",
"values": { "c++20": 201907 }, "values": { "c++20": 201811 }, # because P1032R1 is implemented; but should become 201907 after P0980R1
"headers": ["string"], "headers": ["string"],
"unimplemented": True,
}, { }, {
"name": "__cpp_lib_constexpr_string_view", "name": "__cpp_lib_constexpr_string_view",
"values": { "c++20": 201811 }, "values": { "c++20": 201811 },
"headers": ["string_view"], "headers": ["string_view"],
"unimplemented": True,
}, { }, {
"name": "__cpp_lib_constexpr_tuple", "name": "__cpp_lib_constexpr_tuple",
"values": { "c++20": 201811 }, "values": { "c++20": 201811 },
"headers": ["tuple"], "headers": ["tuple"],
"unimplemented": True,
}, { }, {
"name": "__cpp_lib_constexpr_utility", "name": "__cpp_lib_constexpr_utility",
"values": { "c++20": 201811 }, "values": { "c++20": 201811 },