[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"
"`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","* *",""
"`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"
"`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","* *",""

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_iterator`` *unimplemented*
``__cpp_lib_constexpr_iterator`` ``201811L``
------------------------------------------------- -----------------
``__cpp_lib_constexpr_memory`` ``201811L``
------------------------------------------------- -----------------
``__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``
------------------------------------------------- -----------------

View File

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

View File

@ -107,7 +107,7 @@ namespace std {
constexpr void remove_suffix(size_type n);
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 int compare(basic_string_view s) const noexcept;
@ -359,7 +359,7 @@ public:
__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
{
if (__pos > size())

View File

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

View File

@ -19,7 +19,8 @@
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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,7 +19,8 @@
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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,27 +12,32 @@
// insert_iterator<Cont>
// inserter(Cont& x, Cont::iterator i);
#include <cassert>
#include <iterator>
#include <vector>
#include <cassert>
#include "nasty_containers.h"
#include "test_macros.h"
#include "nasty_containers.h"
#include "test_constexpr_container.h"
template <class C>
void
TEST_CONSTEXPR_CXX20 bool
test(C c)
{
std::insert_iterator<C> i = std::inserter(c, c.end());
i = 0;
assert(c.size() == 1);
assert(c.back() == 0);
return true;
}
int main(int, char**)
{
test(std::vector<int>());
test(nasty_vector<int>());
return 0;
#if TEST_STD_VER >= 20
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"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++20"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# 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
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++20"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
# endif
# ifndef __cpp_lib_make_reverse_iterator
@ -209,17 +203,11 @@
# error "__cpp_lib_array_constexpr should have the value 201811L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# 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
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
# endif
# ifndef __cpp_lib_make_reverse_iterator

View File

@ -18,7 +18,7 @@
/* Constant Value
__cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
__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_nonmember_container_access 201411L [C++17]
__cpp_lib_starts_ends_with 201711L [C++20]
@ -182,17 +182,11 @@
# endif
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string != 201907L
# 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
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string != 201811L
# error "__cpp_lib_constexpr_string should have the value 201811L in c++20"
# endif
# ifndef __cpp_lib_erase_if
@ -256,17 +250,11 @@
# endif
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string != 201907L
# 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
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string != 201811L
# error "__cpp_lib_constexpr_string should have the value 201811L in c++2b"
# endif
# ifndef __cpp_lib_erase_if

View File

@ -111,17 +111,11 @@
# endif
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# 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
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
# endif
# ifndef __cpp_lib_starts_ends_with
@ -157,17 +151,11 @@
# endif
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# 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
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
# endif
# ifndef __cpp_lib_starts_ends_with

View File

@ -119,17 +119,11 @@
# error "__cpp_lib_apply should have the value 201603L in c++20"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++20"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# 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
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++20"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
# endif
# ifndef __cpp_lib_make_from_tuple
@ -162,17 +156,11 @@
# error "__cpp_lib_apply should have the value 201603L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# 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
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# endif
# ifndef __cpp_lib_make_from_tuple

View File

@ -53,7 +53,7 @@
__cpp_lib_constexpr_iterator 201811L [C++20]
__cpp_lib_constexpr_memory 201811L [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_tuple 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"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++20"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# 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
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++20"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
# endif
# ifndef __cpp_lib_constexpr_memory
@ -2463,43 +2457,25 @@
# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string != 201907L
# 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
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string != 201811L
# error "__cpp_lib_constexpr_string should have the value 201811L in c++20"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# 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
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++20"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++20"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# 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
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++20"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
# endif
# ifndef __cpp_lib_constexpr_utility
@ -3647,17 +3623,11 @@
# error "__cpp_lib_constexpr_functional should have the value 201907L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# 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
# ifndef __cpp_lib_constexpr_iterator
# error "__cpp_lib_constexpr_iterator should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_iterator != 201811L
# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
# endif
# ifndef __cpp_lib_constexpr_memory
@ -3674,43 +3644,25 @@
# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string != 201907L
# 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
# ifndef __cpp_lib_constexpr_string
# error "__cpp_lib_constexpr_string should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string != 201811L
# error "__cpp_lib_constexpr_string should have the value 201811L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# 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
# ifndef __cpp_lib_constexpr_string_view
# error "__cpp_lib_constexpr_string_view should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_string_view != 201811L
# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
# endif
# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# 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
# ifndef __cpp_lib_constexpr_tuple
# error "__cpp_lib_constexpr_tuple should be defined in c++2b"
# endif
# if __cpp_lib_constexpr_tuple != 201811L
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# endif
# ifndef __cpp_lib_constexpr_utility

View File

@ -6,6 +6,9 @@
//
//===----------------------------------------------------------------------===//
// XFAIL: gcc-10
// GCC's __builtin_strlen isn't constexpr yet
// <string_view>
// 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, 1);
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**) {
@ -100,5 +112,22 @@ int main(int, char**) {
test ( U"" );
#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;
}

View File

@ -30,7 +30,8 @@ struct PotentiallyThrowingCopyAssignable {
#include "test_macros.h"
int main(int, char**)
TEST_CONSTEXPR_CXX20
bool test()
{
{
typedef std::pair<long, char> T0;
@ -41,6 +42,16 @@ int main(int, char**)
assert(std::get<0>(t1) == 2);
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
// is properly deleted

View File

@ -21,35 +21,31 @@
#include "test_macros.h"
struct B
{
struct B {
int id_;
explicit B(int i = 0) : id_(i) {}
constexpr explicit B(int i = 0) : id_(i) {}
};
struct D
: B
{
explicit D(int i = 0) : B(i) {}
struct D : B {
constexpr explicit D(int i = 0) : B(i) {}
};
struct NonAssignable {
NonAssignable& operator=(NonAssignable const&) = delete;
NonAssignable& operator=(NonAssignable&&) = delete;
NonAssignable& operator=(NonAssignable const&) = delete;
NonAssignable& operator=(NonAssignable&&) = delete;
};
struct NothrowCopyAssignable
{
struct NothrowCopyAssignable {
NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
};
struct PotentiallyThrowingCopyAssignable
{
struct PotentiallyThrowingCopyAssignable {
PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
};
int main(int, char**)
TEST_CONSTEXPR_CXX20
bool test()
{
{
typedef std::tuple<long> T0;
@ -102,6 +98,16 @@ int main(int, char**)
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
{
using T = std::tuple<int, NonAssignable>;
using U = std::tuple<NonAssignable, int>;
@ -116,6 +122,7 @@ int main(int, char**)
{
typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0;
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, "");
}

View File

@ -23,24 +23,19 @@
#include "test_macros.h"
struct B
{
struct B {
int id_;
explicit B(int i= 0) : id_(i) {}
explicit B(int i = 0) : id_(i) {}
virtual ~B() {}
};
struct D
: B
{
struct D : B {
explicit D(int i) : B(i) {}
};
struct E {
E() = default;
E& operator=(int) {
constexpr E() = default;
TEST_CONSTEXPR_CXX14 E& operator=(int) {
return *this;
}
};
@ -92,7 +87,8 @@ struct TrackMove
bool moved_from;
};
int main(int, char**)
TEST_CONSTEXPR_CXX20
bool test()
{
{
typedef std::tuple<long> T0;
@ -111,6 +107,29 @@ int main(int, char**)
assert(std::get<0>(t1) == 2);
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 long, int, B> T1;
@ -143,18 +162,7 @@ int main(int, char**)
assert(std::get<1>(t1) == int('a'));
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 U = std::tuple<NonAssignable, int>;
@ -169,6 +177,7 @@ int main(int, char**)
{
typedef std::tuple<PotentiallyThrowingMoveAssignable, long> T0;
typedef std::tuple<PotentiallyThrowingMoveAssignable, int> T1;
static_assert(std::is_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; }
};
int main(int, char**)
TEST_CONSTEXPR_CXX20
bool test()
{
{
typedef std::tuple<> T;
@ -68,15 +69,6 @@ int main(int, char**)
assert(std::get<0>(t) == 2);
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.
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) == &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
// is properly deleted
@ -99,8 +112,8 @@ int main(int, char**)
static_assert(!std::is_copy_assignable<T>::value, "");
}
{
using T = std::tuple<int, NonAssignable>;
static_assert(!std::is_copy_assignable<T>::value, "");
using T = std::tuple<int, NonAssignable>;
static_assert(!std::is_copy_assignable<T>::value, "");
}
{
using T = std::tuple<int, CopyAssignable>;
@ -132,6 +145,7 @@ int main(int, char**)
}
{
using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;
static_assert(std::is_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::moved = 0;
int main(int, char**)
TEST_CONSTEXPR_CXX20
bool test()
{
{
typedef std::tuple<> T;
@ -100,6 +101,16 @@ int main(int, char**)
assert(std::get<1>(t) == y2);
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
// is properly deleted
@ -108,8 +119,8 @@ int main(int, char**)
static_assert(!std::is_copy_assignable<T>::value, "");
}
{
using T = std::tuple<int, NonAssignable>;
static_assert(!std::is_move_assignable<T>::value, "");
using T = std::tuple<int, NonAssignable>;
static_assert(!std::is_move_assignable<T>::value, "");
}
{
using T = std::tuple<int, MoveAssignable>;

View File

@ -21,26 +21,36 @@
#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 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);
}
test();
#if TEST_STD_VER >= 20
static_assert(test());
#endif
#if TEST_STD_VER > 11
{
constexpr auto t1 = std::make_tuple(0, 1, 3.14);
@ -51,5 +61,5 @@ int main(int, char**)
}
#endif
return 0;
return 0;
}

View File

@ -21,8 +21,9 @@
#include "test_macros.h"
#if TEST_STD_VER > 11
constexpr bool test_tie_constexpr() {
TEST_CONSTEXPR_CXX14
bool test_tie()
{
{
int i = 42;
double f = 1.1;
@ -32,15 +33,23 @@ constexpr bool test_tie_constexpr() {
assert(&std::get<0>(res) == &i);
assert(&std::get<1>(res) == &std::ignore);
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;
}
#endif
int main(int, char**)
{
test_tie();
#if TEST_STD_VER >= 14
static_assert(test_tie(), "");
#endif
{
int i = 0;
std::string s;
@ -48,18 +57,6 @@ int main(int, char**)
assert(i == 42);
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 "MoveOnly.h"
int main(int, char**)
TEST_CONSTEXPR_CXX20
bool test()
{
{
typedef std::tuple<> T;
@ -58,6 +59,15 @@ int main(int, char**)
assert(std::get<1>(t1) == 1);
assert(std::get<2>(t1) == 2);
}
return 0;
return true;
}
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_;
char c_;
public:
A(int i, char c) : i_(i), c_(c) {}
int get_i() const {return i_;}
char get_c() const {return c_;}
constexpr A(int i, char c) : i_(i), c_(c) {}
constexpr int get_i() const {return i_;}
constexpr char get_c() const {return c_;}
};
class B
@ -37,13 +37,14 @@ class B
unsigned u1_;
unsigned u2_;
public:
B(double d, unsigned u1, unsigned u2) : d_(d), u1_(u1), u2_(u2) {}
double get_d() const {return d_;}
unsigned get_u1() const {return u1_;}
unsigned get_u2() const {return u2_;}
constexpr explicit B(double d, unsigned u1, unsigned u2) : d_(d), u1_(u1), u2_(u2) {}
constexpr double get_d() const {return d_;}
constexpr unsigned get_u1() const {return u1_;}
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::make_tuple(4, 'a'),
@ -54,5 +55,15 @@ int main(int, char**)
assert(p.second.get_u1() == 6u);
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",
"values": { "c++20": 201811 },
"headers": ["iterator"],
"unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_memory",
"values": { "c++20": 201811 },
@ -209,19 +208,16 @@ feature_test_macros = [ add_version_header(x) for x in [
"headers": ["numeric"],
}, {
"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"],
"unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_string_view",
"values": { "c++20": 201811 },
"headers": ["string_view"],
"unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_tuple",
"values": { "c++20": 201811 },
"headers": ["tuple"],
"unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_utility",
"values": { "c++20": 201811 },