#include <compare>
namespace std {
template<class... Types>
class tuple;
inline constexpr unspecified ignore;
template<class... TTypes>
constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&...);
template<class... TTypes>
constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;
template<class... TTypes>
constexpr tuple<TTypes&...> tie(TTypes&...) noexcept;
template<class... Tuples>
constexpr tuple<CTypes...> tuple_cat(Tuples&&...);
template<class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t);
template<class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t);
template<class T> struct tuple_size;
template<class T> struct tuple_size<const T>;
template<class... Types> struct tuple_size<tuple<Types...>>;
template<size_t I, class T> struct tuple_element;
template<size_t I, class T> struct tuple_element<I, const T>;
template<size_t I, class... Types>
struct tuple_element<I, tuple<Types...>>;
template<size_t I, class T>
using tuple_element_t = typename tuple_element<I, T>::type;
template<size_t I, class... Types>
constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept;
template<size_t I, class... Types>
constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept;
template<size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&) noexcept;
template<size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept;
template<class T, class... Types>
constexpr T& get(tuple<Types...>& t) noexcept;
template<class T, class... Types>
constexpr T&& get(tuple<Types...>&& t) noexcept;
template<class T, class... Types>
constexpr const T& get(const tuple<Types...>& t) noexcept;
template<class T, class... Types>
constexpr const T&& get(const tuple<Types...>&& t) noexcept;
template<class... TTypes, class... UTypes>
constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... TTypes, class... UTypes>
constexpr common_comparison_category_t<synth-three-way-result<TTypes, UTypes>...>
operator<=>(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc>;
template<class... Types>
constexpr void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below);
template<class T>
inline constexpr size_t tuple_size_v = tuple_size<T>::value;
}
namespace std {
template<class... Types>
class tuple {
public:
constexpr explicit(see below) tuple();
constexpr explicit(see below) tuple(const Types&...);
template<class... UTypes>
constexpr explicit(see below) tuple(UTypes&&...);
tuple(const tuple&) = default;
tuple(tuple&&) = default;
template<class... UTypes>
constexpr explicit(see below) tuple(const tuple<UTypes...>&);
template<class... UTypes>
constexpr explicit(see below) tuple(tuple<UTypes...>&&);
template<class U1, class U2>
constexpr explicit(see below) tuple(const pair<U1, U2>&);
template<class U1, class U2>
constexpr explicit(see below) tuple(pair<U1, U2>&&);
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a);
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const Types&...);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
constexpr tuple& operator=(const tuple&);
constexpr tuple& operator=(tuple&&) noexcept(see below);
template<class... UTypes>
constexpr tuple& operator=(const tuple<UTypes...>&);
template<class... UTypes>
constexpr tuple& operator=(tuple<UTypes...>&&);
template<class U1, class U2>
constexpr tuple& operator=(const pair<U1, U2>&);
template<class U1, class U2>
constexpr tuple& operator=(pair<U1, U2>&&);
constexpr void swap(tuple&) noexcept(see below);
};
template<class... UTypes>
tuple(UTypes...) -> tuple<UTypes...>;
template<class T1, class T2>
tuple(pair<T1, T2>) -> tuple<T1, T2>;
template<class Alloc, class... UTypes>
tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>;
template<class Alloc, class T1, class T2>
tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;
template<class Alloc, class... UTypes>
tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
}
In the descriptions that follow, let
i be in the range
[0, sizeof...(Types)) in order,
Ti
be the
ith type in
Types, and
Ui be the
ith type in a template parameter pack named
UTypes, where indexing
is zero-based
.For each
tuple constructor, an exception is thrown only if the construction of
one of the types in
Types throws an exception
.The defaulted move and copy constructor, respectively, of
tuple is a constexpr function if and only if all
required element-wise initializations for move and copy, respectively,
would satisfy the requirements for a constexpr function
. The
defaulted move and copy constructor of
tuple<> are
constexpr functions
.If
is_ยญtrivially_ยญdestructible_ยญv<Ti> is
true for all
Ti,
then the destructor of
tuple is trivial
. constexpr explicit(see below) tuple();
Constraints:
is_ยญdefault_ยญconstructible_ยญv<Ti> is
true for all
i. Effects:
Value-initializes each element
. Remarks:
The expression inside
explicit evaluates to
true
if and only if
Ti is not
copy-list-initializable from an empty list
for at least one
i. [
Note: This behavior can be implemented with a trait that checks whether
a
const Ti& can be initialized with
{}. โ
end note ]
constexpr explicit(see below) tuple(const Types&...);
Constraints:
sizeof...(Types)โฅ1 and
is_ยญcopy_ยญconstructible_ยญv<Ti> is
true for all
i. Effects:
Initializes each element with the value of the
corresponding parameter
. Remarks:
The expression inside
explicit is equivalent to:
!conjunction_v<is_convertible<const Types&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(UTypes&&... u);
Constraints:
sizeof...(Types) equals
sizeof...(UTypes) and
sizeof...(Types)โฅ1 and
is_ยญconstructible_ยญv<Ti, Ui> is
true for all
i. Effects:
Initializes the elements in the tuple with the
corresponding value in
stdโ::โforward<UTypes>(u). Remarks:
The expression inside
explicit is equivalent to:
!conjunction_v<is_convertible<UTypes, Types>...>
tuple(const tuple& u) = default;
Mandates:
is_ยญcopy_ยญconstructible_ยญv<Ti> is
true for all
i. Effects:
Initializes each element of
*this with the
corresponding element of
u. tuple(tuple&& u) = default;
Constraints:
is_ยญmove_ยญconstructible_ยญv<Ti> is
true for all
i. Effects:
For all
i, initializes the
ith element of
*this with
stdโ::โforward<Ti>(get<i>(u)). template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u);
Constraints:
- sizeof...(Types) equals sizeof...(UTypes) and
- is_ยญconstructible_ยญv<Ti, const Ui&> is true for all i, and
- either
sizeof...(Types) is not 1, or
(when Types... expands to T and UTypes... expands to U)
is_ยญconvertible_ยญv<const tuple<U>&, T>, is_ยญconstructible_ยญv<T, const tuple<U>&>, and is_ยญsame_ยญv<T, U> are all false.
Effects:
Initializes each element of
*this
with the corresponding element of
u. Remarks:
The expression inside
explicit is equivalent to:
!conjunction_v<is_convertible<const UTypes&, Types>...>
template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u);
Constraints:
- sizeof...(Types) equals sizeof...(UTypes), and
- is_ยญconstructible_ยญv<Ti, Ui> is true for all i, and
- either
sizeof...(Types) is not 1, or
(when Types... expands to T and UTypes... expands to U)
is_ยญconvertible_ยญv<tuple<U>, T>, is_ยญconstructible_ยญv<T, tuple<U>>,
and is_ยญsame_ยญv<T, U> are all false.
Effects:
For all
i,
initializes the
ith element of
*this with
stdโ::โforward<Ui>(get<i>(u)). Remarks:
The expression inside
explicit is equivalent to:
!conjunction_v<is_convertible<UTypes, Types>...>
template<class U1, class U2> constexpr explicit(see below) tuple(const pair<U1, U2>& u);
Constraints:
- sizeof...(Types) is 2,
- is_ยญconstructible_ยญv<T0, const U1&> is true, and
- is_ยญconstructible_ยญv<T1, const U2&> is true.
Effects:
Initializes the first element with
u.first and the
second element with
u.second. The expression inside
explicit is equivalent to:
!is_convertible_v<const U1&, T0> || !is_convertible_v<const U2&, T1>
template<class U1, class U2> constexpr explicit(see below) tuple(pair<U1, U2>&& u);
Constraints:
- sizeof...(Types) is 2,
- is_ยญconstructible_ยญv<T0, U1> is true, and
- is_ยญconstructible_ยญv<T1, U2> is true.
Effects:
Initializes the first element with
stdโ::โforward<U1>(u.first) and the
second element with
stdโ::โforward<U2>(u.second). The expression inside
explicit is equivalent to:
!is_convertible_v<U1, T0> || !is_convertible_v<U2, T1>
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a);
template<class Alloc>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const Types&...);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, const tuple&);
template<class Alloc>
constexpr tuple(allocator_arg_t, const Alloc& a, tuple&&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template<class Alloc, class... UTypes>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template<class Alloc, class U1, class U2>
constexpr explicit(see below)
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
Preconditions:
Alloc meets the
Cpp17Allocator requirements (Table
36)
. For each
tuple assignment operator, an exception is thrown only if the
assignment of one of the types in
Types throws an exception
. In the function descriptions that follow, let
i be in the range
[0, sizeof...โ(Types))
in order,
Ti be the
ith type in
Types,
and
Ui be the
ith type in a
template parameter pack named
UTypes, where indexing is zero-based
. constexpr tuple& operator=(const tuple& u);
Effects:
Assigns each element of
u to the corresponding
element of
*this. Remarks:
This operator is defined as deleted unless
is_ยญcopy_ยญassignable_ยญv<Ti> is
true for all
i. constexpr tuple& operator=(tuple&& u) noexcept(see below);
Constraints:
is_ยญmove_ยญassignable_ยญv<Ti> is
true for all
i. Effects:
For all
i, assigns
stdโ::โforward<Ti>(get<i>(u)) to
get<i>(*this). Remarks:
The expression inside noexcept is equivalent to the logical and of the
following expressions:
is_nothrow_move_assignable_v<Ti>
where
Ti is the
ith type in
Types.template<class... UTypes> constexpr tuple& operator=(const tuple<UTypes...>& u);
Constraints:
- sizeof...(Types) equals sizeof...(UTypes) and
- is_ยญassignable_ยญv<Ti&, const Ui&> is true for all i.
Effects:
Assigns each element of
u to the corresponding element
of
*this. template<class... UTypes> constexpr tuple& operator=(tuple<UTypes...>&& u);
Constraints:
- sizeof...(Types) equals sizeof...(UTypes) and
- is_ยญassignable_ยญv<Ti&, Ui> is true for all i.
Effects:
For all
i, assigns
stdโ::โforward<Ui>(get<i>(u)) to
get<i>(*this). template<class U1, class U2> constexpr tuple& operator=(const pair<U1, U2>& u);
Constraints:
- sizeof...(Types) is 2 and
- is_ยญassignable_ยญv<T0&, const U1&> is true, and
- is_ยญassignable_ยญv<T1&, const U2&> is true.
Effects:
Assigns
u.first to the first element of
*this
and
u.second to the second element of
*this. template<class U1, class U2> constexpr tuple& operator=(pair<U1, U2>&& u);
Constraints:
- sizeof...(Types) is 2 and
- is_ยญassignable_ยญv<T0&, U1> is true, and
- is_ยญassignable_ยญv<T1&, U2> is true.
Effects:
Assigns stdโ::โforward<U1>(u.first) to the first
element of *this and
stdโ::โforward<U2>(u.second) to the
second element of
*this. constexpr void swap(tuple& rhs) noexcept(see below);
Effects:
Calls
swap for each element in
*this and its
corresponding element in
rhs. Remarks:
The expression inside noexcept is equivalent to the logical
and of the following expressions:
is_nothrow_swappable_v<Ti>
where
Ti is the
ith type in
Types.Throws:
Nothing unless one of the element-wise
swap calls throws an exception
.