840 lines
28 KiB
Markdown
840 lines
28 KiB
Markdown
[pairs]
|
||
|
||
# 22 General utilities library [[utilities]](./#utilities)
|
||
|
||
## 22.3 Pairs [pairs]
|
||
|
||
### [22.3.1](#general) General [[pairs.general]](pairs.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L737)
|
||
|
||
The library provides a template for heterogeneous pairs of values[.](#general-1.sentence-1)
|
||
|
||
The library also provides a matching function template to simplify
|
||
their construction and several templates that provide access to pair objects as if they were tuple objects (see [[tuple.helper]](tuple.helper "22.4.7 Tuple helper classes") and [[tuple.elem]](tuple.elem "22.4.8 Element access"))[.](#general-1.sentence-2)
|
||
|
||
### [22.3.2](#pair) Class template pair [[pairs.pair]](pairs.pair)
|
||
|
||
[ð](#lib:pair_)
|
||
|
||
namespace std {template<class T1, class T2>struct pair {using first_type = T1; using second_type = T2;
|
||
|
||
T1 first;
|
||
T2 second;
|
||
|
||
pair(const pair&) = default;
|
||
pair(pair&&) = default; constexpr explicit(*see below*) pair(); constexpr explicit(*see below*) pair(const T1& x, const T2& y); template<class U1 = T1, class U2 = T2>constexpr explicit(*see below*) pair(U1&& x, U2&& y); template<class U1, class U2>constexpr explicit(*see below*) pair(pair<U1, U2>& p); template<class U1, class U2>constexpr explicit(*see below*) pair(const pair<U1, U2>& p); template<class U1, class U2>constexpr explicit(*see below*) pair(pair<U1, U2>&& p); template<class U1, class U2>constexpr explicit(*see below*) pair(const pair<U1, U2>&& p); template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P>constexpr explicit(*see below*) pair(P&& p); template<class... Args1, class... Args2>constexpr pair(piecewise_construct_t,
|
||
tuple<Args1...> first_args, tuple<Args2...> second_args); constexpr pair& operator=(const pair& p); constexpr const pair& operator=(const pair& p) const; template<class U1, class U2>constexpr pair& operator=(const pair<U1, U2>& p); template<class U1, class U2>constexpr const pair& operator=(const pair<U1, U2>& p) const; constexpr pair& operator=(pair&& p) noexcept(*see below*); constexpr const pair& operator=(pair&& p) const; template<class U1, class U2>constexpr pair& operator=(pair<U1, U2>&& p); template<class U1, class U2>constexpr const pair& operator=(pair<U1, U2>&& p) const; template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P>constexpr pair& operator=(P&& p); template<[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P>constexpr const pair& operator=(P&& p) const; constexpr void swap(pair& p) noexcept(*see below*); constexpr void swap(const pair& p) const noexcept(*see below*); }; template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>;}
|
||
|
||
[1](#pair-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L806)
|
||
|
||
Constructors and member functions of pair do not throw exceptions unless one of
|
||
the element-wise operations specified to be called for that operation
|
||
throws an exception[.](#pair-1.sentence-1)
|
||
|
||
[2](#pair-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L811)
|
||
|
||
The defaulted move and copy constructor, respectively, of pair is a constexpr function if and only if all required element-wise
|
||
initializations for move and copy, respectively,
|
||
would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"))[.](#pair-2.sentence-1)
|
||
|
||
[3](#pair-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L817)
|
||
|
||
If (is_trivially_destructible_v<T1> && is_trivially_destructible_v<T2>) is true, then the destructor of pair is trivial[.](#pair-3.sentence-1)
|
||
|
||
[4](#pair-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L821)
|
||
|
||
pair<T, U> is a structural type ([[temp.param]](temp.param#term.structural.type "13.2 Template parameters"))
|
||
if T and U are both structural types[.](#pair-4.sentence-1)
|
||
|
||
Two values p1 and p2 of type pair<T, U> are template-argument-equivalent ([[temp.type]](temp.type "13.6 Type equivalence")) if and only ifp1.first and p2.first are template-argument-equivalent andp1.second and p2.second are template-argument-equivalent[.](#pair-4.sentence-2)
|
||
|
||
[ð](#lib:pair,constructor)
|
||
|
||
`constexpr explicit(see below) pair();
|
||
`
|
||
|
||
[5](#pair-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L835)
|
||
|
||
*Constraints*:
|
||
|
||
- [(5.1)](#pair-5.1)
|
||
|
||
is_default_constructible_v<T1> is true and
|
||
|
||
- [(5.2)](#pair-5.2)
|
||
|
||
is_default_constructible_v<T2> is true[.](#pair-5.sentence-1)
|
||
|
||
[6](#pair-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L842)
|
||
|
||
*Effects*: Value-initializes first and second[.](#pair-6.sentence-1)
|
||
|
||
[7](#pair-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L846)
|
||
|
||
*Remarks*: The expression inside explicit evaluates to true if and only if either T1 orT2 is not implicitly default-constructible[.](#pair-7.sentence-1)
|
||
|
||
[*Note [1](#pair-note-1)*:
|
||
|
||
This behavior can be implemented with a trait that checks
|
||
whether a const T1& or a const T2& can be initialized with {}[.](#pair-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:pair,constructor_)
|
||
|
||
`constexpr explicit(see below) pair(const T1& x, const T2& y);
|
||
`
|
||
|
||
[8](#pair-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L864)
|
||
|
||
*Constraints*:
|
||
|
||
- [(8.1)](#pair-8.1)
|
||
|
||
is_copy_constructible_v<T1> is true and
|
||
|
||
- [(8.2)](#pair-8.2)
|
||
|
||
is_copy_constructible_v<T2> is true[.](#pair-8.sentence-1)
|
||
|
||
[9](#pair-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L871)
|
||
|
||
*Effects*: Initializes first with x and second with y[.](#pair-9.sentence-1)
|
||
|
||
[10](#pair-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L875)
|
||
|
||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<const T1&, T1> || !is_convertible_v<const T2&, T2>
|
||
|
||
[ð](#lib:pair,constructor__)
|
||
|
||
`template<class U1 = T1, class U2 = T2> constexpr explicit(see below) pair(U1&& x, U2&& y);
|
||
`
|
||
|
||
[11](#pair-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L889)
|
||
|
||
*Constraints*:
|
||
|
||
- [(11.1)](#pair-11.1)
|
||
|
||
is_constructible_v<T1, U1> is true and
|
||
|
||
- [(11.2)](#pair-11.2)
|
||
|
||
is_constructible_v<T2, U2> is true[.](#pair-11.sentence-1)
|
||
|
||
[12](#pair-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L896)
|
||
|
||
*Effects*: Initializes first withstd::forward<U1>(x) and second with std::forward<U2>(y)[.](#pair-12.sentence-1)
|
||
|
||
[13](#pair-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L902)
|
||
|
||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<U1, T1> || !is_convertible_v<U2, T2>
|
||
|
||
This constructor is defined as deleted ifreference_constructs_from_temporary_v<first_type, U1&&> is true orreference_constructs_from_temporary_v<second_type, U2&&> is true[.](#pair-13.sentence-2)
|
||
|
||
[ð](#lib:pair,constructor___)
|
||
|
||
`template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>& p);
|
||
template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>& p);
|
||
template<class U1, class U2> constexpr explicit(see below) pair(pair<U1, U2>&& p);
|
||
template<class U1, class U2> constexpr explicit(see below) pair(const pair<U1, U2>&& p);
|
||
template<[pair-like](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P> constexpr explicit(see below) pair(P&& p);
|
||
`
|
||
|
||
[14](#pair-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L925)
|
||
|
||
Let *FWD*(u) be static_cast<decltype(u)>(u)[.](#pair-14.sentence-1)
|
||
|
||
[15](#pair-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L928)
|
||
|
||
*Constraints*:
|
||
|
||
- [(15.1)](#pair-15.1)
|
||
|
||
For the last overload,remove_cvref_t<P> is not a specialization of ranges::subrange,
|
||
|
||
- [(15.2)](#pair-15.2)
|
||
|
||
is_constructible_v<T1, decltype(get<0>(*FWD*(p)))> is true, and
|
||
|
||
- [(15.3)](#pair-15.3)
|
||
|
||
is_constructible_v<T2, decltype(get<1>(*FWD*(p)))> is true[.](#pair-15.sentence-1)
|
||
|
||
[16](#pair-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L942)
|
||
|
||
*Effects*: Initializes first with get<0>(*FWD*(p)) andsecond with get<1>(*FWD*(p))[.](#pair-16.sentence-1)
|
||
|
||
[17](#pair-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L947)
|
||
|
||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<decltype(get<0>(*FWD*(p))), T1> ||!is_convertible_v<decltype(get<1>(*FWD*(p))), T2>
|
||
|
||
The constructor is defined as deleted ifreference_constructs_from_temporary_v<first_type, decltype(get<0>(*FWD*(p)))> || reference_constructs_from_temporary_v<second_type, decltype(get<1>(*FWD*(p)))> is true[.](#pair-17.sentence-2)
|
||
|
||
[ð](#lib:pair,constructor____)
|
||
|
||
`template<class... Args1, class... Args2>
|
||
constexpr pair(piecewise_construct_t,
|
||
tuple<Args1...> first_args, tuple<Args2...> second_args);
|
||
`
|
||
|
||
[18](#pair-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L970)
|
||
|
||
*Mandates*:
|
||
|
||
- [(18.1)](#pair-18.1)
|
||
|
||
is_constructible_v<T1, Args1...> is true and
|
||
|
||
- [(18.2)](#pair-18.2)
|
||
|
||
is_constructible_v<T2, Args2...> is true[.](#pair-18.sentence-1)
|
||
|
||
[19](#pair-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L977)
|
||
|
||
*Effects*: Initializes first with arguments of typesArgs1... obtained by forwarding the elements of first_args and initializes second with arguments of types Args2... obtained by forwarding the elements of second_args[.](#pair-19.sentence-1)
|
||
|
||
(Here, forwarding
|
||
an element x of type U within a tuple object means callingstd::forward<U>(x)[.](#pair-19.sentence-2))
|
||
|
||
This form of construction, whereby constructor
|
||
arguments for first and second are each provided in a separatetuple object, is called [*piecewise construction*](#def:piecewise_construction "22.3.2 Class template pair [pairs.pair]")[.](#pair-19.sentence-3)
|
||
|
||
[*Note [2](#pair-note-2)*:
|
||
|
||
If a data member of pair is of reference type and
|
||
its initialization binds it to a temporary object,
|
||
the program is ill-formed ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members"))[.](#pair-19.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:operator=,pair)
|
||
|
||
`constexpr pair& operator=(const pair& p);
|
||
`
|
||
|
||
[20](#pair-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1000)
|
||
|
||
*Effects*: Assigns p.first to first and p.second to second[.](#pair-20.sentence-1)
|
||
|
||
[21](#pair-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1004)
|
||
|
||
*Returns*: *this[.](#pair-21.sentence-1)
|
||
|
||
[22](#pair-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1008)
|
||
|
||
*Remarks*: This operator is defined as deleted unlessis_copy_assignable_v<T1> is true andis_copy_assignable_v<T2> is true[.](#pair-22.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair_)
|
||
|
||
`constexpr const pair& operator=(const pair& p) const;
|
||
`
|
||
|
||
[23](#pair-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1021)
|
||
|
||
*Constraints*:
|
||
|
||
- [(23.1)](#pair-23.1)
|
||
|
||
is_copy_assignable_v<const T1> is true and
|
||
|
||
- [(23.2)](#pair-23.2)
|
||
|
||
is_copy_assignable_v<const T2> is true[.](#pair-23.sentence-1)
|
||
|
||
[24](#pair-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1030)
|
||
|
||
*Effects*: Assigns p.first to first and p.second to second[.](#pair-24.sentence-1)
|
||
|
||
[25](#pair-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1034)
|
||
|
||
*Returns*: *this[.](#pair-25.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair__)
|
||
|
||
`template<class U1, class U2> constexpr pair& operator=(const pair<U1, U2>& p);
|
||
`
|
||
|
||
[26](#pair-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1045)
|
||
|
||
*Constraints*:
|
||
|
||
- [(26.1)](#pair-26.1)
|
||
|
||
is_assignable_v<T1&, const U1&> is true and
|
||
|
||
- [(26.2)](#pair-26.2)
|
||
|
||
is_assignable_v<T2&, const U2&> is true[.](#pair-26.sentence-1)
|
||
|
||
[27](#pair-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1052)
|
||
|
||
*Effects*: Assigns p.first to first and p.second to second[.](#pair-27.sentence-1)
|
||
|
||
[28](#pair-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1056)
|
||
|
||
*Returns*: *this[.](#pair-28.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair___)
|
||
|
||
`template<class U1, class U2> constexpr const pair& operator=(const pair<U1, U2>& p) const;
|
||
`
|
||
|
||
[29](#pair-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1067)
|
||
|
||
*Constraints*:
|
||
|
||
- [(29.1)](#pair-29.1)
|
||
|
||
is_assignable_v<const T1&, const U1&> is true, and
|
||
|
||
- [(29.2)](#pair-29.2)
|
||
|
||
is_assignable_v<const T2&, const U2&> is true[.](#pair-29.sentence-1)
|
||
|
||
[30](#pair-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1076)
|
||
|
||
*Effects*: Assigns p.first to first and p.second to second[.](#pair-30.sentence-1)
|
||
|
||
[31](#pair-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1080)
|
||
|
||
*Returns*: *this[.](#pair-31.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair____)
|
||
|
||
`constexpr pair& operator=(pair&& p) noexcept(see below);
|
||
`
|
||
|
||
[32](#pair-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1091)
|
||
|
||
*Constraints*:
|
||
|
||
- [(32.1)](#pair-32.1)
|
||
|
||
is_move_assignable_v<T1> is true and
|
||
|
||
- [(32.2)](#pair-32.2)
|
||
|
||
is_move_assignable_v<T2> is true[.](#pair-32.sentence-1)
|
||
|
||
[33](#pair-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1098)
|
||
|
||
*Effects*: Assigns std::forward<T1>(p.first) to first andstd::forward<T2>(p.second) to second[.](#pair-33.sentence-1)
|
||
|
||
[34](#pair-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1103)
|
||
|
||
*Returns*: *this[.](#pair-34.sentence-1)
|
||
|
||
[35](#pair-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1107)
|
||
|
||
*Remarks*: The exception specification is equivalent to:is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
|
||
|
||
[ð](#lib:operator=,pair_____)
|
||
|
||
`constexpr const pair& operator=(pair&& p) const;
|
||
`
|
||
|
||
[36](#pair-36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1121)
|
||
|
||
*Constraints*:
|
||
|
||
- [(36.1)](#pair-36.1)
|
||
|
||
is_assignable_v<const T1&, T1> is true and
|
||
|
||
- [(36.2)](#pair-36.2)
|
||
|
||
is_assignable_v<const T2&, T2> is true[.](#pair-36.sentence-1)
|
||
|
||
[37](#pair-37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1130)
|
||
|
||
*Effects*: Assigns std::forward<T1>(p.first) to first andstd::forward<T2>(p.second) to second[.](#pair-37.sentence-1)
|
||
|
||
[38](#pair-38)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1135)
|
||
|
||
*Returns*: *this[.](#pair-38.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair______)
|
||
|
||
`template<class U1, class U2> constexpr pair& operator=(pair<U1, U2>&& p);
|
||
`
|
||
|
||
[39](#pair-39)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1146)
|
||
|
||
*Constraints*:
|
||
|
||
- [(39.1)](#pair-39.1)
|
||
|
||
is_assignable_v<T1&, U1> is true and
|
||
|
||
- [(39.2)](#pair-39.2)
|
||
|
||
is_assignable_v<T2&, U2> is true[.](#pair-39.sentence-1)
|
||
|
||
[40](#pair-40)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1153)
|
||
|
||
*Effects*: Assigns std::forward<U1>(p.first) first andstd::forward<U2>(p.second) to second[.](#pair-40.sentence-1)
|
||
|
||
[41](#pair-41)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1158)
|
||
|
||
*Returns*: *this[.](#pair-41.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair_______)
|
||
|
||
`template<[pair-like](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P> constexpr pair& operator=(P&& p);
|
||
`
|
||
|
||
[42](#pair-42)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1169)
|
||
|
||
*Constraints*:
|
||
|
||
- [(42.1)](#pair-42.1)
|
||
|
||
[*different-from*](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<P, pair> ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts"))
|
||
is true,
|
||
|
||
- [(42.2)](#pair-42.2)
|
||
|
||
remove_cvref_t<P> is not a specialization of ranges::subrange,
|
||
|
||
- [(42.3)](#pair-42.3)
|
||
|
||
is_assignable_v<T1&, decltype(get<0>(std::forward<P>(p)))> is true, and
|
||
|
||
- [(42.4)](#pair-42.4)
|
||
|
||
is_assignable_v<T2&, decltype(get<1>(std::forward<P>(p)))> is true[.](#pair-42.sentence-1)
|
||
|
||
[43](#pair-43)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1185)
|
||
|
||
*Effects*: Assigns get<0>(std::forward<P>(p)) to first andget<1>(std::forward<P>(p)) to second[.](#pair-43.sentence-1)
|
||
|
||
[44](#pair-44)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1190)
|
||
|
||
*Returns*: *this[.](#pair-44.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair________)
|
||
|
||
`template<[pair-like](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P> constexpr const pair& operator=(P&& p) const;
|
||
`
|
||
|
||
[45](#pair-45)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1201)
|
||
|
||
*Constraints*:
|
||
|
||
- [(45.1)](#pair-45.1)
|
||
|
||
[*different-from*](range.utility.helpers#concept:different-from "25.5.2 Helper concepts [range.utility.helpers]")<P, pair> ([[range.utility.helpers]](range.utility.helpers "25.5.2 Helper concepts"))
|
||
is true,
|
||
|
||
- [(45.2)](#pair-45.2)
|
||
|
||
remove_cvref_t<P> is not a specialization of ranges::subrange,
|
||
|
||
- [(45.3)](#pair-45.3)
|
||
|
||
is_assignable_v<const T1&, decltype(get<0>(std::forward<P>(p)))> is true, and
|
||
|
||
- [(45.4)](#pair-45.4)
|
||
|
||
is_assignable_v<const T2&, decltype(get<1>(std::forward<P>(p)))> is true[.](#pair-45.sentence-1)
|
||
|
||
[46](#pair-46)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1217)
|
||
|
||
*Effects*: Assigns get<0>(std::forward<P>(p)) to first andget<1>(std::forward<P>(p)) to second[.](#pair-46.sentence-1)
|
||
|
||
[47](#pair-47)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1222)
|
||
|
||
*Returns*: *this[.](#pair-47.sentence-1)
|
||
|
||
[ð](#lib:operator=,pair_________)
|
||
|
||
`template<class U1, class U2> constexpr const pair& operator=(pair<U1, U2>&& p) const;
|
||
`
|
||
|
||
[48](#pair-48)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1233)
|
||
|
||
*Constraints*:
|
||
|
||
- [(48.1)](#pair-48.1)
|
||
|
||
is_assignable_v<const T1&, U1> is true, and
|
||
|
||
- [(48.2)](#pair-48.2)
|
||
|
||
is_assignable_v<const T2&, U2> is true[.](#pair-48.sentence-1)
|
||
|
||
[49](#pair-49)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1242)
|
||
|
||
*Effects*: Assigns std::forward<U1>(p.first) to first andstd::forward<U2>(u.second) to second[.](#pair-49.sentence-1)
|
||
|
||
[50](#pair-50)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1247)
|
||
|
||
*Returns*: *this[.](#pair-50.sentence-1)
|
||
|
||
[ð](#lib:swap,pair)
|
||
|
||
`constexpr void swap(pair& p) noexcept(see below);
|
||
constexpr void swap(const pair& p) const noexcept(see below);
|
||
`
|
||
|
||
[51](#pair-51)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1259)
|
||
|
||
*Mandates*:
|
||
|
||
- [(51.1)](#pair-51.1)
|
||
|
||
For the first overload,is_swappable_v<T1> is true andis_swappable_v<T2> is true[.](#pair-51.1.sentence-1)
|
||
|
||
- [(51.2)](#pair-51.2)
|
||
|
||
For the second overload,is_swappable_v<const T1> is true andis_swappable_v<const T2> is true[.](#pair-51.2.sentence-1)
|
||
|
||
[52](#pair-52)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1272)
|
||
|
||
*Preconditions*: first is swappable with ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")) p.first andsecond is swappable with p.second[.](#pair-52.sentence-1)
|
||
|
||
[53](#pair-53)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1277)
|
||
|
||
*Effects*: Swapsfirst with p.first andsecond with p.second[.](#pair-53.sentence-1)
|
||
|
||
[54](#pair-54)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1283)
|
||
|
||
*Remarks*: The exception specification is equivalent to:
|
||
|
||
- [(54.1)](#pair-54.1)
|
||
|
||
is_nothrow_swappable_v<T1> && is_nothrow_swappable_v<T2> for the first overload, and
|
||
|
||
- [(54.2)](#pair-54.2)
|
||
|
||
is_nothrow_swappable_v<const T1> && is_nothrow_swappable_v<const T2> for the second overload[.](#pair-54.sentence-1)
|
||
|
||
### [22.3.3](#spec) Specialized algorithms [[pairs.spec]](pairs.spec)
|
||
|
||
[ð](#lib:operator==,pair)
|
||
|
||
`template<class T1, class T2, class U1, class U2>
|
||
constexpr bool operator==(const pair<T1, T2>& x, const pair<U1, U2>& y);
|
||
`
|
||
|
||
[1](#spec-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1305)
|
||
|
||
*Constraints*: x.first == y.first and x.second == y.second are
|
||
valid expressions and
|
||
each of decltype(x.first == y.first) anddecltype(x.second == y.second) models *boolean-
|
||
testable*[.](#spec-1.sentence-1)
|
||
|
||
[2](#spec-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1312)
|
||
|
||
*Returns*: x.first == y.first && x.second == y.second[.](#spec-2.sentence-1)
|
||
|
||
[ð](#lib:operator%3c=%3e,pair)
|
||
|
||
`template<class T1, class T2, class U1, class U2>
|
||
constexpr common_comparison_category_t<synth-three-way-result<T1, U1>,
|
||
synth-three-way-result<T2, U2>>
|
||
operator<=>(const pair<T1, T2>& x, const pair<U1, U2>& y);
|
||
`
|
||
|
||
[3](#spec-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1326)
|
||
|
||
*Effects*: Equivalent to:if (auto c = *synth-three-way*(x.first, y.first); c != 0) return c;return *synth-three-way*(x.second, y.second);
|
||
|
||
[ð](#lib:swap,pair_)
|
||
|
||
`template<class T1, class T2>
|
||
constexpr void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
|
||
template<class T1, class T2>
|
||
constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
|
||
`
|
||
|
||
[4](#spec-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1344)
|
||
|
||
*Constraints*:
|
||
|
||
- [(4.1)](#spec-4.1)
|
||
|
||
For the first overload,is_swappable_v<T1> is true andis_swappable_v<T2> is true[.](#spec-4.1.sentence-1)
|
||
|
||
- [(4.2)](#spec-4.2)
|
||
|
||
For the second overload,is_swappable_v<const T1> is true andis_swappable_v<const T2> is true[.](#spec-4.2.sentence-1)
|
||
|
||
[5](#spec-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1357)
|
||
|
||
*Effects*: Equivalent to x.swap(y)[.](#spec-5.sentence-1)
|
||
|
||
[ð](#lib:make_pair)
|
||
|
||
`template<class T1, class T2>
|
||
constexpr pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>> make_pair(T1&& x, T2&& y);
|
||
`
|
||
|
||
[6](#spec-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1369)
|
||
|
||
*Returns*: pair<unwrap_ref_decay_t<T1>,
|
||
unwrap_ref_decay_t<T2>>(std::forward<T1>(x), std::forward<T2>(y))
|
||
|
||
[7](#spec-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1377)
|
||
|
||
[*Example [1](#spec-example-1)*:
|
||
|
||
In place of:return pair<int, double>(5, 3.1415926); // explicit types a C++ program may contain:return make_pair(5, 3.1415926); // types are deduced
|
||
|
||
â *end example*]
|
||
|
||
### [22.3.4](#pair.astuple) Tuple-like access to pair [[pair.astuple]](pair.astuple)
|
||
|
||
[ð](#lib:tuple_size)
|
||
|
||
`template<class T1, class T2>
|
||
struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
|
||
`
|
||
|
||
[ð](#lib:tuple_element)
|
||
|
||
`template<size_t I, class T1, class T2>
|
||
struct tuple_element<I, pair<T1, T2>> {
|
||
using type = see below ;
|
||
};
|
||
`
|
||
|
||
[1](#pair.astuple-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1405)
|
||
|
||
*Mandates*: I<2[.](#pair.astuple-1.sentence-1)
|
||
|
||
[2](#pair.astuple-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1409)
|
||
|
||
*Type*: The type T1 if I is 0, otherwise the type T2[.](#pair.astuple-2.sentence-1)
|
||
|
||
[ð](#lib:get,pair)
|
||
|
||
`template<size_t I, class T1, class T2>
|
||
constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept;
|
||
template<size_t I, class T1, class T2>
|
||
constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept;
|
||
template<size_t I, class T1, class T2>
|
||
constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept;
|
||
template<size_t I, class T1, class T2>
|
||
constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
|
||
`
|
||
|
||
[3](#pair.astuple-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1427)
|
||
|
||
*Mandates*: I<2[.](#pair.astuple-3.sentence-1)
|
||
|
||
[4](#pair.astuple-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1431)
|
||
|
||
*Returns*:
|
||
|
||
- [(4.1)](#pair.astuple-4.1)
|
||
|
||
If I is 0, returns a reference to p.first[.](#pair.astuple-4.1.sentence-1)
|
||
|
||
- [(4.2)](#pair.astuple-4.2)
|
||
|
||
If I is 1, returns a reference to p.second[.](#pair.astuple-4.2.sentence-1)
|
||
|
||
[ð](#lib:get,pair_)
|
||
|
||
`template<class T1, class T2>
|
||
constexpr T1& get(pair<T1, T2>& p) noexcept;
|
||
template<class T1, class T2>
|
||
constexpr const T1& get(const pair<T1, T2>& p) noexcept;
|
||
template<class T1, class T2>
|
||
constexpr T1&& get(pair<T1, T2>&& p) noexcept;
|
||
template<class T1, class T2>
|
||
constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
|
||
`
|
||
|
||
[5](#pair.astuple-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1455)
|
||
|
||
*Mandates*: T1 and T2 are distinct types[.](#pair.astuple-5.sentence-1)
|
||
|
||
[6](#pair.astuple-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1459)
|
||
|
||
*Returns*: A reference to p.first[.](#pair.astuple-6.sentence-1)
|
||
|
||
[ð](#lib:get,pair__)
|
||
|
||
`template<class T2, class T1>
|
||
constexpr T2& get(pair<T1, T2>& p) noexcept;
|
||
template<class T2, class T1>
|
||
constexpr const T2& get(const pair<T1, T2>& p) noexcept;
|
||
template<class T2, class T1>
|
||
constexpr T2&& get(pair<T1, T2>&& p) noexcept;
|
||
template<class T2, class T1>
|
||
constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
|
||
`
|
||
|
||
[7](#pair.astuple-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1477)
|
||
|
||
*Mandates*: T1 and T2 are distinct types[.](#pair.astuple-7.sentence-1)
|
||
|
||
[8](#pair.astuple-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1481)
|
||
|
||
*Returns*: A reference to p.second[.](#pair.astuple-8.sentence-1)
|
||
|
||
### [22.3.5](#pair.piecewise) Piecewise construction [[pair.piecewise]](pair.piecewise)
|
||
|
||
[ð](#lib:piecewise_construct_t)
|
||
|
||
`struct piecewise_construct_t {
|
||
explicit piecewise_construct_t() = default;
|
||
};
|
||
inline constexpr piecewise_construct_t piecewise_construct{};
|
||
`
|
||
|
||
[1](#pair.piecewise-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L1497)
|
||
|
||
The struct piecewise_construct_t is an empty class type
|
||
used as a unique type to disambiguate constructor and function overloading[.](#pair.piecewise-1.sentence-1)
|
||
|
||
Specifically,pair has a constructor with piecewise_construct_t as the
|
||
first argument, immediately followed by two <tuple> arguments used
|
||
for piecewise construction of the elements of the pair object[.](#pair.piecewise-1.sentence-2)
|