tmp/tmpzrfgc1_7/{from.md → to.md}
RENAMED
|
@@ -6,26 +6,26 @@ namespace std {
|
|
| 6 |
class tuple {
|
| 7 |
public:
|
| 8 |
|
| 9 |
// [tuple.cnstr], tuple construction
|
| 10 |
constexpr tuple();
|
| 11 |
-
explicit tuple(const Types&...);
|
| 12 |
template <class... UTypes>
|
| 13 |
-
explicit tuple(UTypes&&...);
|
| 14 |
|
| 15 |
tuple(const tuple&) = default;
|
| 16 |
tuple(tuple&&) = default;
|
| 17 |
|
| 18 |
template <class... UTypes>
|
| 19 |
-
tuple(const tuple<UTypes...>&);
|
| 20 |
template <class... UTypes>
|
| 21 |
-
tuple(tuple<UTypes...>&&);
|
| 22 |
|
| 23 |
template <class U1, class U2>
|
| 24 |
-
tuple(const pair<U1, U2>&); //
|
| 25 |
template <class U1, class U2>
|
| 26 |
-
tuple(pair<U1, U2>&&); //
|
| 27 |
|
| 28 |
// allocator-extended constructors
|
| 29 |
template <class Alloc>
|
| 30 |
tuple(allocator_arg_t, const Alloc& a);
|
| 31 |
template <class Alloc>
|
|
@@ -53,13 +53,13 @@ namespace std {
|
|
| 53 |
tuple& operator=(const tuple<UTypes...>&);
|
| 54 |
template <class... UTypes>
|
| 55 |
tuple& operator=(tuple<UTypes...>&&);
|
| 56 |
|
| 57 |
template <class U1, class U2>
|
| 58 |
-
tuple& operator=(const pair<U1, U2>&); //
|
| 59 |
template <class U1, class U2>
|
| 60 |
-
tuple& operator=(pair<U1, U2>&&); //
|
| 61 |
|
| 62 |
// [tuple.swap], tuple swap
|
| 63 |
void swap(tuple&) noexcept(see below);
|
| 64 |
};
|
| 65 |
}
|
|
@@ -68,10 +68,16 @@ namespace std {
|
|
| 68 |
#### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
|
| 69 |
|
| 70 |
For each `tuple` constructor, an exception is thrown only if the
|
| 71 |
construction of one of the types in `Types` throws an exception.
|
| 72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
In the constructor descriptions that follow, let i be in the range
|
| 74 |
\[`0`, `sizeof...(Types)`) in order, Tᵢ be the iᵗʰ type in `Types`, and
|
| 75 |
Uᵢ be the iᵗʰ type in a template parameter pack named `UTypes`, where
|
| 76 |
indexing is zero-based.
|
| 77 |
|
|
@@ -82,21 +88,21 @@ constexpr tuple();
|
|
| 82 |
*Requires:* `is_default_constructible<`Tᵢ`>::value` is true for all i.
|
| 83 |
|
| 84 |
*Effects:* Value initializes each element.
|
| 85 |
|
| 86 |
``` cpp
|
| 87 |
-
explicit tuple(const Types&...);
|
| 88 |
```
|
| 89 |
|
| 90 |
*Requires:* `is_copy_constructible<`Tᵢ`>::value` is true for all i.
|
| 91 |
|
| 92 |
*Effects:* Initializes each element with the value of the corresponding
|
| 93 |
parameter.
|
| 94 |
|
| 95 |
``` cpp
|
| 96 |
template <class... UTypes>
|
| 97 |
-
explicit tuple(UTypes&&... u);
|
| 98 |
```
|
| 99 |
|
| 100 |
*Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
|
| 101 |
`is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
|
| 102 |
|
|
@@ -124,11 +130,11 @@ tuple(tuple&& u) = default;
|
|
| 124 |
|
| 125 |
*Effects:* For all i, initializes the iᵗʰ element of `*this` with
|
| 126 |
`std::forward<`Tᵢ`>(get<`i`>(u))`.
|
| 127 |
|
| 128 |
``` cpp
|
| 129 |
-
template <class... UTypes> tuple(const tuple<UTypes...>& u);
|
| 130 |
```
|
| 131 |
|
| 132 |
*Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
|
| 133 |
`is_constructible<`Tᵢ`, const `Uᵢ`&>::value` is `true` for all i.
|
| 134 |
|
|
@@ -137,11 +143,11 @@ element of `u`.
|
|
| 137 |
|
| 138 |
This constructor shall not participate in overload resolution unless
|
| 139 |
`const `Uᵢ`&` is implicitly convertible to Tᵢ for all i.
|
| 140 |
|
| 141 |
``` cpp
|
| 142 |
-
template <class... UTypes> tuple(tuple<UTypes...>&& u);
|
| 143 |
```
|
| 144 |
|
| 145 |
*Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
|
| 146 |
`is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
|
| 147 |
|
|
@@ -151,11 +157,11 @@ template <class... UTypes> tuple(tuple<UTypes...>&& u);
|
|
| 151 |
This constructor shall not participate in overload resolution unless
|
| 152 |
each type in `UTypes` is implicitly convertible to its corresponding
|
| 153 |
type in `Types`.
|
| 154 |
|
| 155 |
``` cpp
|
| 156 |
-
template <class U1, class U2> tuple(const pair<U1, U2>& u);
|
| 157 |
```
|
| 158 |
|
| 159 |
*Requires:* `sizeof...(Types) == 2`.
|
| 160 |
`is_constructible<`T₀`, const U1&>::value` is `true` for the first type
|
| 161 |
T₀ in `Types` and `is_constructible<`T₁`, const U2&>::value` is `true`
|
|
@@ -167,11 +173,11 @@ element with `u.second`.
|
|
| 167 |
This constructor shall not participate in overload resolution unless
|
| 168 |
`const U1&` is implicitly convertible to T₀ and `const U2&` is
|
| 169 |
implicitly convertible to T₁.
|
| 170 |
|
| 171 |
``` cpp
|
| 172 |
-
template <class U1, class U2> tuple(pair<U1, U2>&& u);
|
| 173 |
```
|
| 174 |
|
| 175 |
*Requires:* `sizeof...(Types) == 2`.
|
| 176 |
`is_constructible<`T₀`, U1&&>::value` is `true` for the first type T₀ in
|
| 177 |
`Types` and `is_constructible<`T₁`, U2&&>::value` is `true` for the
|
|
@@ -320,11 +326,11 @@ The expression inside `noexcept` is equivalent to the logical
|
|
| 320 |
|
| 321 |
``` cpp
|
| 322 |
noexcept(swap(declval<Tᵢ&>>(), declval<Tᵢ&>()))
|
| 323 |
```
|
| 324 |
|
| 325 |
-
where T
|
| 326 |
|
| 327 |
*Requires:* Each element in `*this` shall be swappable
|
| 328 |
with ([[swappable.requirements]]) the corresponding element in `rhs`.
|
| 329 |
|
| 330 |
*Effects:* Calls `swap` for each element in `*this` and its
|
|
@@ -341,14 +347,14 @@ parameter pack named `TTypes`; let j be in the range \[`0`,
|
|
| 341 |
`sizeof...(UTypes)`) in order and Uⱼ be the jᵗʰ type in a template
|
| 342 |
parameter pack named `UTypes`, where indexing is zero-based.
|
| 343 |
|
| 344 |
``` cpp
|
| 345 |
template<class... Types>
|
| 346 |
-
tuple<VTypes...> make_tuple(Types&&... t);
|
| 347 |
```
|
| 348 |
|
| 349 |
-
Let Uᵢ be `
|
| 350 |
`VTypes` is `X&` if Uᵢ equals `reference_wrapper<X>`, otherwise Vᵢ is
|
| 351 |
Uᵢ.
|
| 352 |
|
| 353 |
*Returns:* `tuple<VTypes...>(std::forward<Types>(t)...)`.
|
| 354 |
|
|
@@ -363,11 +369,11 @@ creates a tuple of type
|
|
| 363 |
tuple<int, int&, const float&>
|
| 364 |
```
|
| 365 |
|
| 366 |
``` cpp
|
| 367 |
template<class... Types>
|
| 368 |
-
tuple<Types&&...> forward_as_tuple(Types&&... t) noexcept;
|
| 369 |
```
|
| 370 |
|
| 371 |
*Effects:* Constructs a tuple of references to the arguments in `t`
|
| 372 |
suitable for forwarding as arguments to a function. Because the result
|
| 373 |
may contain references to temporary variables, a program shall ensure
|
|
@@ -377,15 +383,16 @@ named variable).
|
|
| 377 |
|
| 378 |
*Returns:* `tuple<Types&&...>(std::forward<Types>(t)...)`
|
| 379 |
|
| 380 |
``` cpp
|
| 381 |
template<class... Types>
|
| 382 |
-
tuple<Types&...> tie(Types&... t) noexcept;
|
| 383 |
```
|
| 384 |
|
| 385 |
-
*Returns:* `tuple<Types&>(t...)`. When an argument in `t` is
|
| 386 |
-
assigning any value to the corresponding tuple element has no
|
|
|
|
| 387 |
|
| 388 |
`tie` functions allow one to create tuples that unpack tuples into
|
| 389 |
variables. `ignore` can be used for elements that are not needed:
|
| 390 |
|
| 391 |
``` cpp
|
|
@@ -394,16 +401,16 @@ tie(i, ignore, s) = make_tuple(42, 3.14, "C++");
|
|
| 394 |
// i == 42, s == "C++"
|
| 395 |
```
|
| 396 |
|
| 397 |
``` cpp
|
| 398 |
template <class... Tuples>
|
| 399 |
-
tuple<CTypes...> tuple_cat(Tuples&&... tpls);
|
| 400 |
```
|
| 401 |
|
| 402 |
In the following paragraphs, let Tᵢ be the iᵗʰ type in `Tuples`, Uᵢ be
|
| 403 |
-
`
|
| 404 |
-
|
| 405 |
|
| 406 |
*Requires:* For all i, Uᵢ shall be the type cvᵢ `tuple<`Argsᵢ...`>`,
|
| 407 |
where cvᵢ is the (possibly empty) iᵗʰ cv-qualifier-seq and Argsᵢ is the
|
| 408 |
parameter pack representing the element types in Uᵢ. Let {Aᵢₖ} be the
|
| 409 |
kᵢᵗʰ type in Argsᵢ. For all Aᵢₖ the following requirements shall be
|
|
@@ -426,10 +433,18 @@ eᵢ in order.
|
|
| 426 |
pack `Tuples` that support the `tuple`-like protocol, such as `pair` and
|
| 427 |
`array`.
|
| 428 |
|
| 429 |
#### Tuple helper classes <a id="tuple.helper">[[tuple.helper]]</a>
|
| 430 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 431 |
``` cpp
|
| 432 |
template <class... Types>
|
| 433 |
class tuple_size<tuple<Types...> >
|
| 434 |
: public integral_constant<size_t, sizeof...(Types)> { };
|
| 435 |
```
|
|
@@ -457,11 +472,11 @@ template <class T> class tuple_size<const volatile T>;
|
|
| 457 |
Let *TS* denote `tuple_size<T>` of the cv-unqualified type `T`. Then
|
| 458 |
each of the three templates shall meet the `UnaryTypeTrait`
|
| 459 |
requirements ([[meta.rqmts]]) with a `BaseCharacteristic` of
|
| 460 |
|
| 461 |
``` cpp
|
| 462 |
-
integral_constant<
|
| 463 |
```
|
| 464 |
|
| 465 |
``` cpp
|
| 466 |
template <size_t I, class T> class tuple_element<I, const T>;
|
| 467 |
template <size_t I, class T> class tuple_element<I, volatile T>;
|
|
@@ -471,31 +486,30 @@ template <size_t I, class T> class tuple_element<I, const volatile T>;
|
|
| 471 |
Let *TE* denote `tuple_element<I, T>` of the cv-unqualified type `T`.
|
| 472 |
Then each of the three templates shall meet the `TransformationTrait`
|
| 473 |
requirements ([[meta.rqmts]]) with a member typedef `type` that names
|
| 474 |
the following type:
|
| 475 |
|
| 476 |
-
- for the first specialization, `
|
| 477 |
-
- for the second specialization, `
|
| 478 |
-
|
| 479 |
-
- for the third specialization, `add_cv<`*`TE`*`::type>::type`.
|
| 480 |
|
| 481 |
#### Element access <a id="tuple.elem">[[tuple.elem]]</a>
|
| 482 |
|
| 483 |
``` cpp
|
| 484 |
template <size_t I, class... Types>
|
| 485 |
-
|
| 486 |
```
|
| 487 |
|
| 488 |
*Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
|
| 489 |
out of bounds.
|
| 490 |
|
| 491 |
*Returns:* A reference to the `I`th element of `t`, where indexing is
|
| 492 |
zero-based.
|
| 493 |
|
| 494 |
``` cpp
|
| 495 |
-
template <size_t I, class...
|
| 496 |
-
|
| 497 |
```
|
| 498 |
|
| 499 |
*Effects:* Equivalent to
|
| 500 |
`return std::forward<typename tuple_element<I, tuple<Types...> >`
|
| 501 |
`::type&&>(get<I>(t));`
|
|
@@ -504,11 +518,11 @@ template <size_t I, class... types>
|
|
| 504 |
is `X&`, not `X&&`. However, if the element type is a non-reference type
|
| 505 |
`T`, the return type is `T&&`.
|
| 506 |
|
| 507 |
``` cpp
|
| 508 |
template <size_t I, class... Types>
|
| 509 |
-
|
| 510 |
```
|
| 511 |
|
| 512 |
*Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
|
| 513 |
out of bounds.
|
| 514 |
|
|
@@ -519,38 +533,61 @@ Constness is shallow. If a `T` in `Types` is some reference type `X&`,
|
|
| 519 |
the return type is `X&`, not `const X&`. However, if the element type is
|
| 520 |
non-reference type `T`, the return type is `const T&`. This is
|
| 521 |
consistent with how constness is defined to work for member variables of
|
| 522 |
reference type.
|
| 523 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 524 |
The reason `get` is a nonmember function is that if this functionality
|
| 525 |
had been provided as a member function, code where the type depended on
|
| 526 |
a template parameter would have required using the `template` keyword.
|
| 527 |
|
| 528 |
#### Relational operators <a id="tuple.rel">[[tuple.rel]]</a>
|
| 529 |
|
| 530 |
``` cpp
|
| 531 |
template<class... TTypes, class... UTypes>
|
| 532 |
-
bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 533 |
```
|
| 534 |
|
| 535 |
-
*Requires:* For all `i`, where `0 <= i` and `i < sizeof...(
|
| 536 |
`get<i>(t) == get<i>(u)` is a valid expression returning a type that is
|
| 537 |
convertible to `bool`. `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
|
| 538 |
|
| 539 |
-
*Returns:* `true`
|
| 540 |
-
zero-length tuples `e` and `f`, `e == f` returns
|
|
|
|
| 541 |
|
| 542 |
*Effects:* The elementary comparisons are performed in order from the
|
| 543 |
zeroth index upwards. No comparisons or element accesses are performed
|
| 544 |
after the first equality comparison that evaluates to `false`.
|
| 545 |
|
| 546 |
``` cpp
|
| 547 |
template<class... TTypes, class... UTypes>
|
| 548 |
-
bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 549 |
```
|
| 550 |
|
| 551 |
-
*Requires:* For all `i`, where `0 <= i` and `i < sizeof...(
|
| 552 |
`get<i>(t) < get<i>(u)` and `get<i>(u) < get<i>(t)` are valid
|
| 553 |
expressions returning types that are convertible to `bool`.
|
| 554 |
`sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
|
| 555 |
|
| 556 |
*Returns:* The result of a lexicographical comparison between `t` and
|
|
@@ -560,32 +597,32 @@ where `r`ₜₐᵢₗ for some tuple `r` is a tuple containing all but the first
|
|
| 560 |
element of `r`. For any two zero-length tuples `e` and `f`, `e < f`
|
| 561 |
returns `false`.
|
| 562 |
|
| 563 |
``` cpp
|
| 564 |
template<class... TTypes, class... UTypes>
|
| 565 |
-
bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 566 |
```
|
| 567 |
|
| 568 |
*Returns:* `!(t == u)`.
|
| 569 |
|
| 570 |
``` cpp
|
| 571 |
template<class... TTypes, class... UTypes>
|
| 572 |
-
bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 573 |
```
|
| 574 |
|
| 575 |
*Returns:* `u < t`.
|
| 576 |
|
| 577 |
``` cpp
|
| 578 |
template<class... TTypes, class... UTypes>
|
| 579 |
-
bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 580 |
```
|
| 581 |
|
| 582 |
*Returns:* `!(u < t)`
|
| 583 |
|
| 584 |
``` cpp
|
| 585 |
template<class... TTypes, class... UTypes>
|
| 586 |
-
bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 587 |
```
|
| 588 |
|
| 589 |
*Returns:* `!(t < u)`
|
| 590 |
|
| 591 |
The above definitions for comparison operators do not require `tₜₐᵢₗ`
|
|
|
|
| 6 |
class tuple {
|
| 7 |
public:
|
| 8 |
|
| 9 |
// [tuple.cnstr], tuple construction
|
| 10 |
constexpr tuple();
|
| 11 |
+
constexpr explicit tuple(const Types&...);
|
| 12 |
template <class... UTypes>
|
| 13 |
+
constexpr explicit tuple(UTypes&&...);
|
| 14 |
|
| 15 |
tuple(const tuple&) = default;
|
| 16 |
tuple(tuple&&) = default;
|
| 17 |
|
| 18 |
template <class... UTypes>
|
| 19 |
+
constexpr tuple(const tuple<UTypes...>&);
|
| 20 |
template <class... UTypes>
|
| 21 |
+
constexpr tuple(tuple<UTypes...>&&);
|
| 22 |
|
| 23 |
template <class U1, class U2>
|
| 24 |
+
constexpr tuple(const pair<U1, U2>&); // only if sizeof...(Types) == 2
|
| 25 |
template <class U1, class U2>
|
| 26 |
+
constexpr tuple(pair<U1, U2>&&); // only if sizeof...(Types) == 2
|
| 27 |
|
| 28 |
// allocator-extended constructors
|
| 29 |
template <class Alloc>
|
| 30 |
tuple(allocator_arg_t, const Alloc& a);
|
| 31 |
template <class Alloc>
|
|
|
|
| 53 |
tuple& operator=(const tuple<UTypes...>&);
|
| 54 |
template <class... UTypes>
|
| 55 |
tuple& operator=(tuple<UTypes...>&&);
|
| 56 |
|
| 57 |
template <class U1, class U2>
|
| 58 |
+
tuple& operator=(const pair<U1, U2>&); // only if sizeof...(Types) == 2
|
| 59 |
template <class U1, class U2>
|
| 60 |
+
tuple& operator=(pair<U1, U2>&&); // only if sizeof...(Types) == 2
|
| 61 |
|
| 62 |
// [tuple.swap], tuple swap
|
| 63 |
void swap(tuple&) noexcept(see below);
|
| 64 |
};
|
| 65 |
}
|
|
|
|
| 68 |
#### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
|
| 69 |
|
| 70 |
For each `tuple` constructor, an exception is thrown only if the
|
| 71 |
construction of one of the types in `Types` throws an exception.
|
| 72 |
|
| 73 |
+
The defaulted move and copy constructor, respectively, of `tuple` shall
|
| 74 |
+
be a `constexpr` function if and only if all required element-wise
|
| 75 |
+
initializations for copy and move, respectively, would satisfy the
|
| 76 |
+
requirements for a `constexpr` function. The defaulted move and copy
|
| 77 |
+
constructor of `tuple<>` shall be `constexpr` functions.
|
| 78 |
+
|
| 79 |
In the constructor descriptions that follow, let i be in the range
|
| 80 |
\[`0`, `sizeof...(Types)`) in order, Tᵢ be the iᵗʰ type in `Types`, and
|
| 81 |
Uᵢ be the iᵗʰ type in a template parameter pack named `UTypes`, where
|
| 82 |
indexing is zero-based.
|
| 83 |
|
|
|
|
| 88 |
*Requires:* `is_default_constructible<`Tᵢ`>::value` is true for all i.
|
| 89 |
|
| 90 |
*Effects:* Value initializes each element.
|
| 91 |
|
| 92 |
``` cpp
|
| 93 |
+
constexpr explicit tuple(const Types&...);
|
| 94 |
```
|
| 95 |
|
| 96 |
*Requires:* `is_copy_constructible<`Tᵢ`>::value` is true for all i.
|
| 97 |
|
| 98 |
*Effects:* Initializes each element with the value of the corresponding
|
| 99 |
parameter.
|
| 100 |
|
| 101 |
``` cpp
|
| 102 |
template <class... UTypes>
|
| 103 |
+
constexpr explicit tuple(UTypes&&... u);
|
| 104 |
```
|
| 105 |
|
| 106 |
*Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
|
| 107 |
`is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
|
| 108 |
|
|
|
|
| 130 |
|
| 131 |
*Effects:* For all i, initializes the iᵗʰ element of `*this` with
|
| 132 |
`std::forward<`Tᵢ`>(get<`i`>(u))`.
|
| 133 |
|
| 134 |
``` cpp
|
| 135 |
+
template <class... UTypes> constexpr tuple(const tuple<UTypes...>& u);
|
| 136 |
```
|
| 137 |
|
| 138 |
*Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
|
| 139 |
`is_constructible<`Tᵢ`, const `Uᵢ`&>::value` is `true` for all i.
|
| 140 |
|
|
|
|
| 143 |
|
| 144 |
This constructor shall not participate in overload resolution unless
|
| 145 |
`const `Uᵢ`&` is implicitly convertible to Tᵢ for all i.
|
| 146 |
|
| 147 |
``` cpp
|
| 148 |
+
template <class... UTypes> constexpr tuple(tuple<UTypes...>&& u);
|
| 149 |
```
|
| 150 |
|
| 151 |
*Requires:* `sizeof...(Types)` `==` `sizeof...(UTypes)`.
|
| 152 |
`is_constructible<`Tᵢ`, `Uᵢ`&&>::value` is `true` for all i.
|
| 153 |
|
|
|
|
| 157 |
This constructor shall not participate in overload resolution unless
|
| 158 |
each type in `UTypes` is implicitly convertible to its corresponding
|
| 159 |
type in `Types`.
|
| 160 |
|
| 161 |
``` cpp
|
| 162 |
+
template <class U1, class U2> constexpr tuple(const pair<U1, U2>& u);
|
| 163 |
```
|
| 164 |
|
| 165 |
*Requires:* `sizeof...(Types) == 2`.
|
| 166 |
`is_constructible<`T₀`, const U1&>::value` is `true` for the first type
|
| 167 |
T₀ in `Types` and `is_constructible<`T₁`, const U2&>::value` is `true`
|
|
|
|
| 173 |
This constructor shall not participate in overload resolution unless
|
| 174 |
`const U1&` is implicitly convertible to T₀ and `const U2&` is
|
| 175 |
implicitly convertible to T₁.
|
| 176 |
|
| 177 |
``` cpp
|
| 178 |
+
template <class U1, class U2> constexpr tuple(pair<U1, U2>&& u);
|
| 179 |
```
|
| 180 |
|
| 181 |
*Requires:* `sizeof...(Types) == 2`.
|
| 182 |
`is_constructible<`T₀`, U1&&>::value` is `true` for the first type T₀ in
|
| 183 |
`Types` and `is_constructible<`T₁`, U2&&>::value` is `true` for the
|
|
|
|
| 326 |
|
| 327 |
``` cpp
|
| 328 |
noexcept(swap(declval<Tᵢ&>>(), declval<Tᵢ&>()))
|
| 329 |
```
|
| 330 |
|
| 331 |
+
where Tᵢ is the iᵗʰ type in `Types`.
|
| 332 |
|
| 333 |
*Requires:* Each element in `*this` shall be swappable
|
| 334 |
with ([[swappable.requirements]]) the corresponding element in `rhs`.
|
| 335 |
|
| 336 |
*Effects:* Calls `swap` for each element in `*this` and its
|
|
|
|
| 347 |
`sizeof...(UTypes)`) in order and Uⱼ be the jᵗʰ type in a template
|
| 348 |
parameter pack named `UTypes`, where indexing is zero-based.
|
| 349 |
|
| 350 |
``` cpp
|
| 351 |
template<class... Types>
|
| 352 |
+
constexpr tuple<VTypes...> make_tuple(Types&&... t);
|
| 353 |
```
|
| 354 |
|
| 355 |
+
Let Uᵢ be `decay_t<`Tᵢ`>` for each Tᵢ in `Types`. Then each Vᵢ in
|
| 356 |
`VTypes` is `X&` if Uᵢ equals `reference_wrapper<X>`, otherwise Vᵢ is
|
| 357 |
Uᵢ.
|
| 358 |
|
| 359 |
*Returns:* `tuple<VTypes...>(std::forward<Types>(t)...)`.
|
| 360 |
|
|
|
|
| 369 |
tuple<int, int&, const float&>
|
| 370 |
```
|
| 371 |
|
| 372 |
``` cpp
|
| 373 |
template<class... Types>
|
| 374 |
+
constexpr tuple<Types&&...> forward_as_tuple(Types&&... t) noexcept;
|
| 375 |
```
|
| 376 |
|
| 377 |
*Effects:* Constructs a tuple of references to the arguments in `t`
|
| 378 |
suitable for forwarding as arguments to a function. Because the result
|
| 379 |
may contain references to temporary variables, a program shall ensure
|
|
|
|
| 383 |
|
| 384 |
*Returns:* `tuple<Types&&...>(std::forward<Types>(t)...)`
|
| 385 |
|
| 386 |
``` cpp
|
| 387 |
template<class... Types>
|
| 388 |
+
constexpr tuple<Types&...> tie(Types&... t) noexcept;
|
| 389 |
```
|
| 390 |
|
| 391 |
+
*Returns:* `tuple<Types&...>(t...)`. When an argument in `t` is
|
| 392 |
+
`ignore`, assigning any value to the corresponding tuple element has no
|
| 393 |
+
effect.
|
| 394 |
|
| 395 |
`tie` functions allow one to create tuples that unpack tuples into
|
| 396 |
variables. `ignore` can be used for elements that are not needed:
|
| 397 |
|
| 398 |
``` cpp
|
|
|
|
| 401 |
// i == 42, s == "C++"
|
| 402 |
```
|
| 403 |
|
| 404 |
``` cpp
|
| 405 |
template <class... Tuples>
|
| 406 |
+
constexpr tuple<CTypes...> tuple_cat(Tuples&&... tpls);
|
| 407 |
```
|
| 408 |
|
| 409 |
In the following paragraphs, let Tᵢ be the iᵗʰ type in `Tuples`, Uᵢ be
|
| 410 |
+
`remove_reference_t<Ti>`, and tpᵢ be the iᵗʰ parameter in the function
|
| 411 |
+
parameter pack `tpls`, where all indexing is zero-based.
|
| 412 |
|
| 413 |
*Requires:* For all i, Uᵢ shall be the type cvᵢ `tuple<`Argsᵢ...`>`,
|
| 414 |
where cvᵢ is the (possibly empty) iᵗʰ cv-qualifier-seq and Argsᵢ is the
|
| 415 |
parameter pack representing the element types in Uᵢ. Let {Aᵢₖ} be the
|
| 416 |
kᵢᵗʰ type in Argsᵢ. For all Aᵢₖ the following requirements shall be
|
|
|
|
| 433 |
pack `Tuples` that support the `tuple`-like protocol, such as `pair` and
|
| 434 |
`array`.
|
| 435 |
|
| 436 |
#### Tuple helper classes <a id="tuple.helper">[[tuple.helper]]</a>
|
| 437 |
|
| 438 |
+
``` cpp
|
| 439 |
+
template <class T> struct tuple_size;
|
| 440 |
+
```
|
| 441 |
+
|
| 442 |
+
*Remarks:* All specializations of `tuple_size<T>` shall meet the
|
| 443 |
+
`UnaryTypeTrait` requirements ([[meta.rqmts]]) with a
|
| 444 |
+
`BaseCharacteristic` of `integral_constant<size_t, N>` for some `N`.
|
| 445 |
+
|
| 446 |
``` cpp
|
| 447 |
template <class... Types>
|
| 448 |
class tuple_size<tuple<Types...> >
|
| 449 |
: public integral_constant<size_t, sizeof...(Types)> { };
|
| 450 |
```
|
|
|
|
| 472 |
Let *TS* denote `tuple_size<T>` of the cv-unqualified type `T`. Then
|
| 473 |
each of the three templates shall meet the `UnaryTypeTrait`
|
| 474 |
requirements ([[meta.rqmts]]) with a `BaseCharacteristic` of
|
| 475 |
|
| 476 |
``` cpp
|
| 477 |
+
integral_constant<size_t, TS::value>
|
| 478 |
```
|
| 479 |
|
| 480 |
``` cpp
|
| 481 |
template <size_t I, class T> class tuple_element<I, const T>;
|
| 482 |
template <size_t I, class T> class tuple_element<I, volatile T>;
|
|
|
|
| 486 |
Let *TE* denote `tuple_element<I, T>` of the cv-unqualified type `T`.
|
| 487 |
Then each of the three templates shall meet the `TransformationTrait`
|
| 488 |
requirements ([[meta.rqmts]]) with a member typedef `type` that names
|
| 489 |
the following type:
|
| 490 |
|
| 491 |
+
- for the first specialization, `add_const_t<`*`TE`*`::type>`,
|
| 492 |
+
- for the second specialization, `add_volatile_t<`*`TE`*`::type>`, and
|
| 493 |
+
- for the third specialization, `add_cv_t<`*`TE`*`::type>`.
|
|
|
|
| 494 |
|
| 495 |
#### Element access <a id="tuple.elem">[[tuple.elem]]</a>
|
| 496 |
|
| 497 |
``` cpp
|
| 498 |
template <size_t I, class... Types>
|
| 499 |
+
constexpr tuple_element_t<I, tuple<Types...> >& get(tuple<Types...>& t) noexcept;
|
| 500 |
```
|
| 501 |
|
| 502 |
*Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
|
| 503 |
out of bounds.
|
| 504 |
|
| 505 |
*Returns:* A reference to the `I`th element of `t`, where indexing is
|
| 506 |
zero-based.
|
| 507 |
|
| 508 |
``` cpp
|
| 509 |
+
template <size_t I, class... Types>
|
| 510 |
+
constexpr tuple_element_t<I, tuple<Types...> >&& get(tuple<Types...>&& t) noexcept;
|
| 511 |
```
|
| 512 |
|
| 513 |
*Effects:* Equivalent to
|
| 514 |
`return std::forward<typename tuple_element<I, tuple<Types...> >`
|
| 515 |
`::type&&>(get<I>(t));`
|
|
|
|
| 518 |
is `X&`, not `X&&`. However, if the element type is a non-reference type
|
| 519 |
`T`, the return type is `T&&`.
|
| 520 |
|
| 521 |
``` cpp
|
| 522 |
template <size_t I, class... Types>
|
| 523 |
+
constexpr tuple_element_t<I, tuple<Types...> > const& get(const tuple<Types...>& t) noexcept;
|
| 524 |
```
|
| 525 |
|
| 526 |
*Requires:* `I < sizeof...(Types)`. The program is ill-formed if `I` is
|
| 527 |
out of bounds.
|
| 528 |
|
|
|
|
| 533 |
the return type is `X&`, not `const X&`. However, if the element type is
|
| 534 |
non-reference type `T`, the return type is `const T&`. This is
|
| 535 |
consistent with how constness is defined to work for member variables of
|
| 536 |
reference type.
|
| 537 |
|
| 538 |
+
``` cpp
|
| 539 |
+
template <class T, class... Types>
|
| 540 |
+
constexpr T& get(tuple<Types...>& t) noexcept;
|
| 541 |
+
template <class T, class... Types>
|
| 542 |
+
constexpr T&& get(tuple<Types...>&& t) noexcept;
|
| 543 |
+
template <class T, class... Types>
|
| 544 |
+
constexpr const T& get(const tuple<Types...>& t) noexcept;
|
| 545 |
+
```
|
| 546 |
+
|
| 547 |
+
*Requires:* The type `T` occurs exactly once in `Types...`. Otherwise,
|
| 548 |
+
the program is ill-formed.
|
| 549 |
+
|
| 550 |
+
*Returns:* A reference to the element of `t` corresponding to the type
|
| 551 |
+
`T` in `Types...`.
|
| 552 |
+
|
| 553 |
+
``` cpp
|
| 554 |
+
const tuple<int, const int, double, double> t(1, 2, 3.4, 5.6);
|
| 555 |
+
const int &i1 = get<int>(t); // OK. Not ambiguous. i1 == 1
|
| 556 |
+
const int &i2 = get<const int>(t); // OK. Not ambiguous. i2 == 2
|
| 557 |
+
const double &d = get<double>(t); // ERROR. ill-formed
|
| 558 |
+
```
|
| 559 |
+
|
| 560 |
The reason `get` is a nonmember function is that if this functionality
|
| 561 |
had been provided as a member function, code where the type depended on
|
| 562 |
a template parameter would have required using the `template` keyword.
|
| 563 |
|
| 564 |
#### Relational operators <a id="tuple.rel">[[tuple.rel]]</a>
|
| 565 |
|
| 566 |
``` cpp
|
| 567 |
template<class... TTypes, class... UTypes>
|
| 568 |
+
constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 569 |
```
|
| 570 |
|
| 571 |
+
*Requires:* For all `i`, where `0 <= i` and `i < sizeof...(TTypes)`,
|
| 572 |
`get<i>(t) == get<i>(u)` is a valid expression returning a type that is
|
| 573 |
convertible to `bool`. `sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
|
| 574 |
|
| 575 |
+
*Returns:* `true` if `get<i>(t) == get<i>(u)` for all `i`, otherwise
|
| 576 |
+
`false`. For any two zero-length tuples `e` and `f`, `e == f` returns
|
| 577 |
+
`true`.
|
| 578 |
|
| 579 |
*Effects:* The elementary comparisons are performed in order from the
|
| 580 |
zeroth index upwards. No comparisons or element accesses are performed
|
| 581 |
after the first equality comparison that evaluates to `false`.
|
| 582 |
|
| 583 |
``` cpp
|
| 584 |
template<class... TTypes, class... UTypes>
|
| 585 |
+
constexpr bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 586 |
```
|
| 587 |
|
| 588 |
+
*Requires:* For all `i`, where `0 <= i` and `i < sizeof...(TTypes)`,
|
| 589 |
`get<i>(t) < get<i>(u)` and `get<i>(u) < get<i>(t)` are valid
|
| 590 |
expressions returning types that are convertible to `bool`.
|
| 591 |
`sizeof...(TTypes)` `==` `sizeof...(UTypes)`.
|
| 592 |
|
| 593 |
*Returns:* The result of a lexicographical comparison between `t` and
|
|
|
|
| 597 |
element of `r`. For any two zero-length tuples `e` and `f`, `e < f`
|
| 598 |
returns `false`.
|
| 599 |
|
| 600 |
``` cpp
|
| 601 |
template<class... TTypes, class... UTypes>
|
| 602 |
+
constexpr bool operator!=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 603 |
```
|
| 604 |
|
| 605 |
*Returns:* `!(t == u)`.
|
| 606 |
|
| 607 |
``` cpp
|
| 608 |
template<class... TTypes, class... UTypes>
|
| 609 |
+
constexpr bool operator>(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 610 |
```
|
| 611 |
|
| 612 |
*Returns:* `u < t`.
|
| 613 |
|
| 614 |
``` cpp
|
| 615 |
template<class... TTypes, class... UTypes>
|
| 616 |
+
constexpr bool operator<=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 617 |
```
|
| 618 |
|
| 619 |
*Returns:* `!(u < t)`
|
| 620 |
|
| 621 |
``` cpp
|
| 622 |
template<class... TTypes, class... UTypes>
|
| 623 |
+
constexpr bool operator>=(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
|
| 624 |
```
|
| 625 |
|
| 626 |
*Returns:* `!(t < u)`
|
| 627 |
|
| 628 |
The above definitions for comparison operators do not require `tₜₐᵢₗ`
|