From Jason Turner

[tuple]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpj4ia0jem/{from.md → to.md} +68 -53
tmp/tmpj4ia0jem/{from.md → to.md} RENAMED
@@ -1,17 +1,21 @@
1
  ## Tuples <a id="tuple">[[tuple]]</a>
2
 
3
- ### In general <a id="tuple.general">[[tuple.general]]</a>
4
 
5
  Subclause  [[tuple]] describes the tuple library that provides a tuple
6
  type as the class template `tuple` that can be instantiated with any
7
  number of arguments. Each template argument specifies the type of an
8
  element in the `tuple`. Consequently, tuples are heterogeneous,
9
  fixed-size collections of values. An instantiation of `tuple` with two
10
  arguments is similar to an instantiation of `pair` with the same two
11
  arguments. See  [[pairs]].
12
 
 
 
 
 
13
  ### Header `<tuple>` synopsis <a id="tuple.syn">[[tuple.syn]]</a>
14
 
15
  ``` cpp
16
  // all freestanding
17
  #include <compare> // see [compare.syn]
@@ -33,13 +37,18 @@ namespace std {
33
  template<class> class TQual, template<class> class UQual>
34
  struct basic_common_reference<TTuple, UTuple, TQual, UQual>;
35
  template<exposition onlyconceptnc{tuple-like} TTuple, exposition onlyconceptnc{tuple-like} UTuple>
36
  struct common_type<TTuple, UTuple>;
37
 
 
 
 
 
 
 
 
38
  // [tuple.creation], tuple creation functions
39
- inline constexpr unspecified ignore;
40
-
41
  template<class... TTypes>
42
  constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&...);
43
 
44
  template<class... TTypes>
45
  constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;
@@ -50,11 +59,12 @@ namespace std {
50
  template<exposition onlyconceptnc{tuple-like}... Tuples>
51
  constexpr tuple<CTypes...> tuple_cat(Tuples&&...);
52
 
53
  // [tuple.apply], calling a function with a tuple of arguments
54
  template<class F, exposition onlyconceptnc{tuple-like} Tuple>
55
- constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(see below);
 
56
 
57
  template<class T, exposition onlyconceptnc{tuple-like} Tuple>
58
  constexpr T make_from_tuple(Tuple&& t);
59
 
60
  // [tuple.helper], tuple helper classes
@@ -68,11 +78,11 @@ namespace std {
68
 
69
  template<size_t I, class... Types>
70
  struct tuple_element<I, tuple<Types...>>;
71
 
72
  template<size_t I, class T>
73
- using tuple_element_t = typename tuple_element<I, T>::type;
74
 
75
  // [tuple.elem], element access
76
  template<size_t I, class... Types>
77
  constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept;
78
  template<size_t I, class... Types>
@@ -123,15 +133,17 @@ namespace std {
123
  template<class T>
124
  concept tuple-like = see belownc; // exposition only
125
  ```
126
 
127
  A type `T` models and satisfies the exposition-only concept `tuple-like`
128
- if `remove_cvref_t<T>` is a specialization of `array`, `pair`, `tuple`,
129
- or `ranges::subrange`.
130
 
131
  ### Class template `tuple` <a id="tuple.tuple">[[tuple.tuple]]</a>
132
 
 
 
133
  ``` cpp
134
  namespace std {
135
  template<class... Types>
136
  class tuple {
137
  public:
@@ -253,10 +265,13 @@ namespace std {
253
  template<class Alloc, class... UTypes>
254
  tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
255
  }
256
  ```
257
 
 
 
 
258
  #### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
259
 
260
  In the descriptions that follow, let i be in the range \[`0`,
261
  `sizeof...(Types)`) in order, `Tᵢ` be the iᵗʰ type in `Types`, and `Uᵢ`
262
  be the iᵗʰ type in a template parameter pack named `UTypes`, where
@@ -367,11 +382,11 @@ template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&
367
  template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u);
368
  template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u);
369
  template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&& u);
370
  ```
371
 
372
- Let `I` be the pack `0, 1, ..., (sizeof...(Types) - 1)`. Let
373
  *`FWD`*`(u)` be `static_cast<decltype(u)>(u)`.
374
 
375
  *Constraints:*
376
 
377
  - `sizeof...(Types)` equals `sizeof...(UTypes)`, and
@@ -438,21 +453,21 @@ is `true`.
438
  ``` cpp
439
  template<tuple-like UTuple>
440
  constexpr explicit(see below) tuple(UTuple&& u);
441
  ```
442
 
443
- Let `I` be the pack `0, 1, …, (sizeof...(Types) - 1)`.
444
 
445
  *Constraints:*
446
 
447
  - `different-from<UTuple, tuple>` [[range.utility.helpers]] is `true`,
448
  - `remove_cvref_t<UTuple>` is not a specialization of
449
  `ranges::subrange`,
450
  - `sizeof...(Types)` equals `tuple_size_v<remove_cvref_t<UTuple>>`,
451
  - `(is_constructible_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> && ...)`
452
  is `true`, and
453
- - either `sizeof...(Types)` is not `1`, or (when `Types...` expands to
454
  `T`) `is_convertible_v<UTuple, T>` and `is_constructible_v<T, UTuple>`
455
  are both `false`.
456
 
457
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
458
  `get<`i`>(std::forward<UTuple>(u))`.
@@ -461,10 +476,19 @@ Let `I` be the pack `0, 1, …, (sizeof...(Types) - 1)`.
461
 
462
  ``` cpp
463
  !(is_convertible_v<decltype(get<I>(std::forward<UTuple>(u))), Types> && ...)
464
  ```
465
 
 
 
 
 
 
 
 
 
 
466
  ``` cpp
467
  template<class Alloc>
468
  constexpr explicit(see below)
469
  tuple(allocator_arg_t, const Alloc& a);
470
  template<class Alloc>
@@ -703,11 +727,11 @@ template<tuple-like UTuple>
703
  *Constraints:*
704
 
705
  - `different-from<UTuple, tuple>` [[range.utility.helpers]] is `true`,
706
  - `remove_cvref_t<UTuple>` is not a specialization of
707
  `ranges::subrange`,
708
- - `sizeof...(Types)` equals `tuple_size_v<remove_cvref_t<UTuple>>`, and,
709
  - `is_assignable_v<``Tᵢ``&, decltype(get<`i`>(std::forward<UTuple>(u)))>`
710
  is `true` for all i.
711
 
712
  *Effects:* For all i, assigns `get<`i`>(std::forward<UTuple>(u))` to
713
  `get<`i`>(*this)`.
@@ -722,11 +746,11 @@ template<tuple-like UTuple>
722
  *Constraints:*
723
 
724
  - `different-from<UTuple, tuple>` [[range.utility.helpers]] is `true`,
725
  - `remove_cvref_t<UTuple>` is not a specialization of
726
  `ranges::subrange`,
727
- - `sizeof...(Types)` equals `tuple_size_v<remove_cvref_t<UTuple>>`, and,
728
  - `is_assignable_v<const ``Tᵢ``&, decltype(get<`i`>(std::forward<UTuple>(u)))>`
729
  is `true` for all i.
730
 
731
  *Effects:* For all i, assigns `get<`i`>(std::forward<UTuple>(u))` to
732
  `get<`i`>(*this)`.
@@ -749,11 +773,11 @@ Let i be in the range \[`0`, `sizeof...(Types)`) in order.
749
  `true`.
750
 
751
  *Preconditions:* For all i, `get<`i`>(*this)` is swappable
752
  with [[swappable.requirements]] `get<`i`>(rhs)`.
753
 
754
- *Effects:* For each i, calls `swap` for `get<`i`>(*this)` with
755
  `get<`i`>(rhs)`.
756
 
757
  *Throws:* Nothing unless one of the element-wise `swap` calls throws an
758
  exception.
759
 
@@ -801,13 +825,11 @@ variable).
801
  ``` cpp
802
  template<class... TTypes>
803
  constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
804
  ```
805
 
806
- *Returns:* `tuple<TTypes&...>(t...)`. When an argument in `t` is
807
- `ignore`, assigning any value to the corresponding tuple element has no
808
- effect.
809
 
810
  [*Example 2*:
811
 
812
  `tie` functions allow one to create tuples that unpack tuples into
813
  variables. `ignore` can be used for elements that are not needed:
@@ -849,14 +871,15 @@ elems₀`...`, …, elemsₙ₋₁`...`.
849
 
850
  ### Calling a function with a `tuple` of arguments <a id="tuple.apply">[[tuple.apply]]</a>
851
 
852
  ``` cpp
853
  template<class F, tuple-like Tuple>
854
- constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(see below);
 
855
  ```
856
 
857
- *Effects:* Given the exposition-only function:
858
 
859
  ``` cpp
860
  namespace std {
861
  template<class F, tuple-like Tuple, size_t... I>
862
  constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, index_sequence<I...>) {
@@ -871,28 +894,20 @@ Equivalent to:
871
  ``` cpp
872
  return apply-impl(std::forward<F>(f), std::forward<Tuple>(t),
873
  make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
874
  ```
875
 
876
- *Remarks:* Let `I` be the pack
877
- `0, 1, ..., (tuple_size_v<remove_reference_t<Tuple>> - 1)`. The
878
- exception specification is equivalent to:
879
-
880
- ``` cpp
881
- noexcept(invoke(std::forward<F>(f), get<I>(std::forward<Tuple>(t))...))
882
- ```
883
-
884
  ``` cpp
885
  template<class T, tuple-like Tuple>
886
  constexpr T make_from_tuple(Tuple&& t);
887
  ```
888
 
889
  *Mandates:* If `tuple_size_v<remove_reference_t<Tuple>>` is 1, then
890
  `reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))>`
891
  is `false`.
892
 
893
- *Effects:* Given the exposition-only function:
894
 
895
  ``` cpp
896
  namespace std {
897
  template<class T, tuple-like Tuple, size_t... I>
898
  requires is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...>
@@ -918,17 +933,17 @@ list. — *end note*]
918
 
919
  ``` cpp
920
  template<class T> struct tuple_size;
921
  ```
922
 
923
- All specializations of `tuple_size` meet the *Cpp17UnaryTypeTrait*
924
- requirements [[meta.rqmts]] with a base characteristic of
925
- `integral_constant<size_t, N>` for some `N`.
926
 
927
  ``` cpp
928
  template<class... Types>
929
- struct tuple_size<tuple<Types...>> : public integral_constant<size_t, sizeof...(Types)> { };
930
  ```
931
 
932
  ``` cpp
933
  template<size_t I, class... Types>
934
  struct tuple_element<I, tuple<Types...>> {
@@ -936,12 +951,12 @@ template<size_t I, class... Types>
936
  };
937
  ```
938
 
939
  *Mandates:* `I` < `sizeof...(Types)`.
940
 
941
- *Type:* `TI` is the type of the `I`ᵗʰ element of `Types`, where indexing
942
- is zero-based.
943
 
944
  ``` cpp
945
  template<class T> struct tuple_size<const T>;
946
  ```
947
 
@@ -976,11 +991,11 @@ template<size_t I, class T> struct tuple_element<I, const T>;
976
  ```
977
 
978
  Let `TE` denote `tuple_element_t<I, T>` of the cv-unqualified type `T`.
979
  Then each specialization of the template meets the
980
  *Cpp17TransformationTrait* requirements [[meta.rqmts]] with a member
981
- typedef `type` that names the type `add_const_t<TE>`.
982
 
983
  In addition to being available via inclusion of the `<tuple>` header,
984
  the template is available when any of the headers `<array>`, `<ranges>`,
985
  or `<utility>` are included.
986
 
@@ -990,32 +1005,34 @@ or `<utility>` are included.
990
  template<size_t I, class... Types>
991
  constexpr tuple_element_t<I, tuple<Types...>>&
992
  get(tuple<Types...>& t) noexcept;
993
  template<size_t I, class... Types>
994
  constexpr tuple_element_t<I, tuple<Types...>>&&
995
- get(tuple<Types...>&& t) noexcept; // Note A
996
  template<size_t I, class... Types>
997
  constexpr const tuple_element_t<I, tuple<Types...>>&
998
- get(const tuple<Types...>& t) noexcept; // Note B
999
  template<size_t I, class... Types>
1000
  constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
1001
  ```
1002
 
1003
  *Mandates:* `I` < `sizeof...(Types)`.
1004
 
1005
  *Returns:* A reference to the `I`ᵗʰ element of `t`, where indexing is
1006
  zero-based.
1007
 
1008
- [*Note 1*: \[Note A\]If a type `T` in `Types` is some reference type
1009
- `X&`, the return type is `X&`, not `X&&`. However, if the element type
1010
- is a non-reference type `T`, the return type is `T&&`. — *end note*]
 
1011
 
1012
- [*Note 2*: \[Note B\]Constness is shallow. If a type `T` in `Types` is
1013
- some reference type `X&`, the return type is `X&`, not `const X&`.
1014
- However, if the element type is a non-reference type `T`, the return
1015
- type is `const T&`. This is consistent with how constness is defined to
1016
- work for non-static data members of reference type. — *end note*]
 
1017
 
1018
  ``` cpp
1019
  template<class T, class... Types>
1020
  constexpr T& get(tuple<Types...>& t) noexcept;
1021
  template<class T, class... Types>
@@ -1056,16 +1073,14 @@ template<class... TTypes, tuple-like UTuple>
1056
  constexpr bool operator==(const tuple<TTypes...>& t, const UTuple& u);
1057
  ```
1058
 
1059
  For the first overload let `UTuple` be `tuple<UTypes...>`.
1060
 
1061
- *Mandates:* For all `i`, where 0 ≤ `i` < `sizeof...(TTypes)`,
1062
- `get<i>(t) == get<i>(u)` is a valid expression. `sizeof...(TTypes)`
1063
- equals `tuple_size_v<UTuple>`.
1064
-
1065
- *Preconditions:* For all `i`, `decltype(get<i>(t) == get<i>(u))` models
1066
- `boolean-testable`.
1067
 
1068
  *Returns:* `true` if `get<i>(t) == get<i>(u)` for all `i`, otherwise
1069
  `false`.
1070
 
1071
  [*Note 1*: If `sizeof...(TTypes)` equals zero, returns
@@ -1109,11 +1124,11 @@ lookup [[basic.lookup.argdep]] only.
1109
 
1110
  [*Note 1*: The above definition does not require `tₜₐᵢₗ` (or `uₜₐᵢₗ`)
1111
  to be constructed. It might not even be possible, as `t` and `u` are not
1112
  required to be copy constructible. Also, all comparison operator
1113
  functions are short circuited; they do not perform element accesses
1114
- beyond what is required to determine the result of the
1115
  comparison. — *end note*]
1116
 
1117
  ### `common_reference` related specializations <a id="tuple.common.ref">[[tuple.common.ref]]</a>
1118
 
1119
  In the descriptions that follow:
@@ -1141,11 +1156,11 @@ struct basic_common_reference<TTuple, UTuple, TQual, UQual> {
1141
  - `is_same_v<UTuple, decay_t<UTuple>>` is `true`.
1142
  - `tuple_size_v<TTuple>` equals `tuple_size_v<UTuple>`.
1143
  - `tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>` denotes a
1144
  type.
1145
 
1146
- The member *typedef-name* `type` denotes the type
1147
  `tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>`.
1148
 
1149
  ``` cpp
1150
  template<tuple-like TTuple, tuple-like UTuple>
1151
  struct common_type<TTuple, UTuple> {
@@ -1160,11 +1175,11 @@ struct common_type<TTuple, UTuple> {
1160
  - `is_same_v<TTuple, decay_t<TTuple>>` is `true`.
1161
  - `is_same_v<UTuple, decay_t<UTuple>>` is `true`.
1162
  - `tuple_size_v<TTuple>` equals `tuple_size_v<UTuple>`.
1163
  - `tuple<common_type_t<TTypes, UTypes>...>` denotes a type.
1164
 
1165
- The member *typedef-name* `type` denotes the type
1166
  `tuple<common_type_t<TTypes, UTypes>...>`.
1167
 
1168
  ### Tuple traits <a id="tuple.traits">[[tuple.traits]]</a>
1169
 
1170
  ``` cpp
 
1
  ## Tuples <a id="tuple">[[tuple]]</a>
2
 
3
+ ### General <a id="tuple.general">[[tuple.general]]</a>
4
 
5
  Subclause  [[tuple]] describes the tuple library that provides a tuple
6
  type as the class template `tuple` that can be instantiated with any
7
  number of arguments. Each template argument specifies the type of an
8
  element in the `tuple`. Consequently, tuples are heterogeneous,
9
  fixed-size collections of values. An instantiation of `tuple` with two
10
  arguments is similar to an instantiation of `pair` with the same two
11
  arguments. See  [[pairs]].
12
 
13
+ In addition to being available via inclusion of the `<tuple>` header,
14
+ `ignore` [[tuple.syn]] is available when `<utility>` [[utility]] is
15
+ included.
16
+
17
  ### Header `<tuple>` synopsis <a id="tuple.syn">[[tuple.syn]]</a>
18
 
19
  ``` cpp
20
  // all freestanding
21
  #include <compare> // see [compare.syn]
 
37
  template<class> class TQual, template<class> class UQual>
38
  struct basic_common_reference<TTuple, UTuple, TQual, UQual>;
39
  template<exposition onlyconceptnc{tuple-like} TTuple, exposition onlyconceptnc{tuple-like} UTuple>
40
  struct common_type<TTuple, UTuple>;
41
 
42
+ // ignore
43
+ struct ignore-type { // exposition only
44
+ constexpr const ignore-type&
45
+ operator=(const auto &) const noexcept { return *this; }
46
+ };
47
+ inline constexpr ignore-type ignore;
48
+
49
  // [tuple.creation], tuple creation functions
 
 
50
  template<class... TTypes>
51
  constexpr tuple<unwrap_ref_decay_t<TTypes>...> make_tuple(TTypes&&...);
52
 
53
  template<class... TTypes>
54
  constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;
 
59
  template<exposition onlyconceptnc{tuple-like}... Tuples>
60
  constexpr tuple<CTypes...> tuple_cat(Tuples&&...);
61
 
62
  // [tuple.apply], calling a function with a tuple of arguments
63
  template<class F, exposition onlyconceptnc{tuple-like} Tuple>
64
+ constexpr apply_result_t<F, Tuple> apply(F&& f, Tuple&& t)
65
+ noexcept(is_nothrow_applicable_v<F, Tuple>);
66
 
67
  template<class T, exposition onlyconceptnc{tuple-like} Tuple>
68
  constexpr T make_from_tuple(Tuple&& t);
69
 
70
  // [tuple.helper], tuple helper classes
 
78
 
79
  template<size_t I, class... Types>
80
  struct tuple_element<I, tuple<Types...>>;
81
 
82
  template<size_t I, class T>
83
+ using tuple_element_t = tuple_element<I, T>::type;
84
 
85
  // [tuple.elem], element access
86
  template<size_t I, class... Types>
87
  constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&) noexcept;
88
  template<size_t I, class... Types>
 
133
  template<class T>
134
  concept tuple-like = see belownc; // exposition only
135
  ```
136
 
137
  A type `T` models and satisfies the exposition-only concept `tuple-like`
138
+ if `remove_cvref_t<T>` is a specialization of `array`, `complex`,
139
+ `pair`, `tuple`, or `ranges::subrange`.
140
 
141
  ### Class template `tuple` <a id="tuple.tuple">[[tuple.tuple]]</a>
142
 
143
+ #### General <a id="tuple.tuple.general">[[tuple.tuple.general]]</a>
144
+
145
  ``` cpp
146
  namespace std {
147
  template<class... Types>
148
  class tuple {
149
  public:
 
265
  template<class Alloc, class... UTypes>
266
  tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
267
  }
268
  ```
269
 
270
+ If a program declares an explicit or partial specialization of `tuple`,
271
+ the program is ill-formed, no diagnostic required.
272
+
273
  #### Construction <a id="tuple.cnstr">[[tuple.cnstr]]</a>
274
 
275
  In the descriptions that follow, let i be in the range \[`0`,
276
  `sizeof...(Types)`) in order, `Tᵢ` be the iᵗʰ type in `Types`, and `Uᵢ`
277
  be the iᵗʰ type in a template parameter pack named `UTypes`, where
 
382
  template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>& u);
383
  template<class... UTypes> constexpr explicit(see below) tuple(tuple<UTypes...>&& u);
384
  template<class... UTypes> constexpr explicit(see below) tuple(const tuple<UTypes...>&& u);
385
  ```
386
 
387
+ Let `I` be the pack `0, 1, `…`, (sizeof...(Types) - 1)`. Let
388
  *`FWD`*`(u)` be `static_cast<decltype(u)>(u)`.
389
 
390
  *Constraints:*
391
 
392
  - `sizeof...(Types)` equals `sizeof...(UTypes)`, and
 
453
  ``` cpp
454
  template<tuple-like UTuple>
455
  constexpr explicit(see below) tuple(UTuple&& u);
456
  ```
457
 
458
+ Let `I` be the pack `0, 1, ``, (sizeof...(Types) - 1)`.
459
 
460
  *Constraints:*
461
 
462
  - `different-from<UTuple, tuple>` [[range.utility.helpers]] is `true`,
463
  - `remove_cvref_t<UTuple>` is not a specialization of
464
  `ranges::subrange`,
465
  - `sizeof...(Types)` equals `tuple_size_v<remove_cvref_t<UTuple>>`,
466
  - `(is_constructible_v<Types, decltype(get<I>(std::forward<UTuple>(u)))> && ...)`
467
  is `true`, and
468
+ - either `sizeof...(Types)` is not 1, or (when `Types...` expands to
469
  `T`) `is_convertible_v<UTuple, T>` and `is_constructible_v<T, UTuple>`
470
  are both `false`.
471
 
472
  *Effects:* For all i, initializes the iᵗʰ element of `*this` with
473
  `get<`i`>(std::forward<UTuple>(u))`.
 
476
 
477
  ``` cpp
478
  !(is_convertible_v<decltype(get<I>(std::forward<UTuple>(u))), Types> && ...)
479
  ```
480
 
481
+ The constructor is defined as deleted if
482
+
483
+ ``` cpp
484
+ (reference_constructs_from_temporary_v<Types, decltype(get<I>(std::forward<UTuple>(u)))>
485
+ || ...)
486
+ ```
487
+
488
+ is `true`.
489
+
490
  ``` cpp
491
  template<class Alloc>
492
  constexpr explicit(see below)
493
  tuple(allocator_arg_t, const Alloc& a);
494
  template<class Alloc>
 
727
  *Constraints:*
728
 
729
  - `different-from<UTuple, tuple>` [[range.utility.helpers]] is `true`,
730
  - `remove_cvref_t<UTuple>` is not a specialization of
731
  `ranges::subrange`,
732
+ - `sizeof...(Types)` equals `tuple_size_v<remove_cvref_t<UTuple>>`, and
733
  - `is_assignable_v<``Tᵢ``&, decltype(get<`i`>(std::forward<UTuple>(u)))>`
734
  is `true` for all i.
735
 
736
  *Effects:* For all i, assigns `get<`i`>(std::forward<UTuple>(u))` to
737
  `get<`i`>(*this)`.
 
746
  *Constraints:*
747
 
748
  - `different-from<UTuple, tuple>` [[range.utility.helpers]] is `true`,
749
  - `remove_cvref_t<UTuple>` is not a specialization of
750
  `ranges::subrange`,
751
+ - `sizeof...(Types)` equals `tuple_size_v<remove_cvref_t<UTuple>>`, and
752
  - `is_assignable_v<const ``Tᵢ``&, decltype(get<`i`>(std::forward<UTuple>(u)))>`
753
  is `true` for all i.
754
 
755
  *Effects:* For all i, assigns `get<`i`>(std::forward<UTuple>(u))` to
756
  `get<`i`>(*this)`.
 
773
  `true`.
774
 
775
  *Preconditions:* For all i, `get<`i`>(*this)` is swappable
776
  with [[swappable.requirements]] `get<`i`>(rhs)`.
777
 
778
+ *Effects:* For each i, calls `swap` for `get<`i`>(*this)` and
779
  `get<`i`>(rhs)`.
780
 
781
  *Throws:* Nothing unless one of the element-wise `swap` calls throws an
782
  exception.
783
 
 
825
  ``` cpp
826
  template<class... TTypes>
827
  constexpr tuple<TTypes&...> tie(TTypes&... t) noexcept;
828
  ```
829
 
830
+ *Returns:* `tuple<TTypes&...>(t...)`.
 
 
831
 
832
  [*Example 2*:
833
 
834
  `tie` functions allow one to create tuples that unpack tuples into
835
  variables. `ignore` can be used for elements that are not needed:
 
871
 
872
  ### Calling a function with a `tuple` of arguments <a id="tuple.apply">[[tuple.apply]]</a>
873
 
874
  ``` cpp
875
  template<class F, tuple-like Tuple>
876
+ constexpr apply_result_t<F, Tuple> apply(F&& f, Tuple&& t)
877
+ noexcept(is_nothrow_applicable_v<F, Tuple>);
878
  ```
879
 
880
+ *Effects:* Given the exposition-only function template:
881
 
882
  ``` cpp
883
  namespace std {
884
  template<class F, tuple-like Tuple, size_t... I>
885
  constexpr decltype(auto) apply-impl(F&& f, Tuple&& t, index_sequence<I...>) {
 
894
  ``` cpp
895
  return apply-impl(std::forward<F>(f), std::forward<Tuple>(t),
896
  make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
897
  ```
898
 
 
 
 
 
 
 
 
 
899
  ``` cpp
900
  template<class T, tuple-like Tuple>
901
  constexpr T make_from_tuple(Tuple&& t);
902
  ```
903
 
904
  *Mandates:* If `tuple_size_v<remove_reference_t<Tuple>>` is 1, then
905
  `reference_constructs_from_temporary_v<T, decltype(get<0>(declval<Tuple>()))>`
906
  is `false`.
907
 
908
+ *Effects:* Given the exposition-only function template:
909
 
910
  ``` cpp
911
  namespace std {
912
  template<class T, tuple-like Tuple, size_t... I>
913
  requires is_constructible_v<T, decltype(get<I>(declval<Tuple>()))...>
 
933
 
934
  ``` cpp
935
  template<class T> struct tuple_size;
936
  ```
937
 
938
+ Except where specified otherwise, all specializations of `tuple_size`
939
+ meet the *Cpp17UnaryTypeTrait* requirements [[meta.rqmts]] with a base
940
+ characteristic of `integral_constant<size_t, N>` for some `N`.
941
 
942
  ``` cpp
943
  template<class... Types>
944
+ struct tuple_size<tuple<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
945
  ```
946
 
947
  ``` cpp
948
  template<size_t I, class... Types>
949
  struct tuple_element<I, tuple<Types...>> {
 
951
  };
952
  ```
953
 
954
  *Mandates:* `I` < `sizeof...(Types)`.
955
 
956
+ *Result:* `TI` is the type of the `I`ᵗʰ element of `Types`, where
957
+ indexing is zero-based.
958
 
959
  ``` cpp
960
  template<class T> struct tuple_size<const T>;
961
  ```
962
 
 
991
  ```
992
 
993
  Let `TE` denote `tuple_element_t<I, T>` of the cv-unqualified type `T`.
994
  Then each specialization of the template meets the
995
  *Cpp17TransformationTrait* requirements [[meta.rqmts]] with a member
996
+ typedef `type` that names the type `const TE`.
997
 
998
  In addition to being available via inclusion of the `<tuple>` header,
999
  the template is available when any of the headers `<array>`, `<ranges>`,
1000
  or `<utility>` are included.
1001
 
 
1005
  template<size_t I, class... Types>
1006
  constexpr tuple_element_t<I, tuple<Types...>>&
1007
  get(tuple<Types...>& t) noexcept;
1008
  template<size_t I, class... Types>
1009
  constexpr tuple_element_t<I, tuple<Types...>>&&
1010
+ get(tuple<Types...>&& t) noexcept; // #1
1011
  template<size_t I, class... Types>
1012
  constexpr const tuple_element_t<I, tuple<Types...>>&
1013
+ get(const tuple<Types...>& t) noexcept; // #2
1014
  template<size_t I, class... Types>
1015
  constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&& t) noexcept;
1016
  ```
1017
 
1018
  *Mandates:* `I` < `sizeof...(Types)`.
1019
 
1020
  *Returns:* A reference to the `I`ᵗʰ element of `t`, where indexing is
1021
  zero-based.
1022
 
1023
+ [*Note 1*: For the overload marked \#1, if a type `T` in `Types` is
1024
+ some reference type `X&`, the return type is `X&`, not `X&&`. However,
1025
+ if the element type is a non-reference type `T`, the return type is
1026
+ `T&&`. — *end note*]
1027
 
1028
+ [*Note 2*: Constness is shallow. For the overload marked \#2, if a type
1029
+ `T` in `Types` is some reference type `X&`, the return type is `X&`, not
1030
+ `const X&`. However, if the element type is a non-reference type `T`,
1031
+ the return type is `const T&`. This is consistent with how constness is
1032
+ defined to work for non-static data members of reference
1033
+ type. — *end note*]
1034
 
1035
  ``` cpp
1036
  template<class T, class... Types>
1037
  constexpr T& get(tuple<Types...>& t) noexcept;
1038
  template<class T, class... Types>
 
1073
  constexpr bool operator==(const tuple<TTypes...>& t, const UTuple& u);
1074
  ```
1075
 
1076
  For the first overload let `UTuple` be `tuple<UTypes...>`.
1077
 
1078
+ *Constraints:* For all `i`, where 0 ≤ `i` < `sizeof...(TTypes)`,
1079
+ `get<i>(t) == get<i>(u)` is a valid expression and
1080
+ `decltype(get<i>(t) == get<i>(u))` models `boolean-testable`.
1081
+ `sizeof...(TTypes)` equals `tuple_size_v<UTuple>`.
 
 
1082
 
1083
  *Returns:* `true` if `get<i>(t) == get<i>(u)` for all `i`, otherwise
1084
  `false`.
1085
 
1086
  [*Note 1*: If `sizeof...(TTypes)` equals zero, returns
 
1124
 
1125
  [*Note 1*: The above definition does not require `tₜₐᵢₗ` (or `uₜₐᵢₗ`)
1126
  to be constructed. It might not even be possible, as `t` and `u` are not
1127
  required to be copy constructible. Also, all comparison operator
1128
  functions are short circuited; they do not perform element accesses
1129
+ beyond what is needed to determine the result of the
1130
  comparison. — *end note*]
1131
 
1132
  ### `common_reference` related specializations <a id="tuple.common.ref">[[tuple.common.ref]]</a>
1133
 
1134
  In the descriptions that follow:
 
1156
  - `is_same_v<UTuple, decay_t<UTuple>>` is `true`.
1157
  - `tuple_size_v<TTuple>` equals `tuple_size_v<UTuple>`.
1158
  - `tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>` denotes a
1159
  type.
1160
 
1161
+ *Result:* The member *typedef-name* `type` denotes the type
1162
  `tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>`.
1163
 
1164
  ``` cpp
1165
  template<tuple-like TTuple, tuple-like UTuple>
1166
  struct common_type<TTuple, UTuple> {
 
1175
  - `is_same_v<TTuple, decay_t<TTuple>>` is `true`.
1176
  - `is_same_v<UTuple, decay_t<UTuple>>` is `true`.
1177
  - `tuple_size_v<TTuple>` equals `tuple_size_v<UTuple>`.
1178
  - `tuple<common_type_t<TTypes, UTypes>...>` denotes a type.
1179
 
1180
+ *Result:* The member *typedef-name* `type` denotes the type
1181
  `tuple<common_type_t<TTypes, UTypes>...>`.
1182
 
1183
  ### Tuple traits <a id="tuple.traits">[[tuple.traits]]</a>
1184
 
1185
  ``` cpp