<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<title>Cleanup of Pair and tuple</title>

<style type="text/css">
  p {text-align:justify}
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  blockquote.note
  {
   background-color:#E0E0E0;
   padding-left: 15px;
   padding-right: 15px;
   padding-top: 1px;
   padding-bottom: 1px;
  }
</style>
</head><body>
<address style="text-align: left;">
Document number: N3140=10-0130<br>
Date: 2010-10-02<br>
Author: Daniel Kr&uuml;gler<br>
Project: Programming Language C++, Library Working Group<br>
Reply-to: <a href="mailto:daniel.kruegler@googlemail.com">Daniel Kr&uuml;gler</a>
</address>
<hr>
<h1 style="text-align: center;">Cleanup of <tt>pair</tt> and <tt>tuple</tt></h1>
<p>
<strong>Addressed NB comments</strong>: 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#DE15">DE 15</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#DE16">DE 16</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#US95">US 95</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#US96">US 96</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3118.html#US97">US 97</a>
<p>
<strong>Addressed issues</strong>: 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#801">LWG 801</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1314">LWG 1314</a>,
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#1326">LWG 1326</a>
<p>
<h2><a name="Introduction"></a>Introduction</h2>
<p>
Several changes during the development of the <tt>C++0x</tt> Standard left their marks on the very fundamental
components <tt>pair</tt> and <tt>tuple</tt>. Originally, <tt>pair</tt> was only specified for non-reference 
types and with the addition of move-semantics, the suggested changes in terms of <tt>std::move</tt> where 
appropriate. Adding the new allocators model to the library as well as updates of the core rules in regard to 
reference conversions and in regard to special member functions left the types <tt>pair</tt> and <tt>tuple</tt> 
in a state that needs to be cleaned-up to make the specifications consistent.
<p>

<h2><a name="Discussion"></a>Discussion</h2>
<p>
The proposed fixes in this document can be devided into different categories:
<ul>
<li>Restoring or explicitly adding implied member functions (move constructor and copy assignment operator), especially
	because of semantics that we wish to clarify in regard to optional triviality (e.g. the move constructor should be
	trivial if possible) and in regard to specialities due to reference members (e.g. the built-in assignment operators
	won't work in the presence of references as members).</li>
<li>Fixing requirements and semantics that still use <tt>std::move</tt> or <tt>Move/CopyConstructible</tt>, but that need 
	to use <tt>std::forward</tt> and refer to <tt>std::is_constructible</tt> instead (Otherwise we produce ill-formed 
	code when attempting to bind an lvalue to an lvalue-reference).</li>
</ul>
<p>
During the Rapperwil meeting several examples came up where the explicit declaration of a move special member did
suppress the defaulted copy special member (and vice versa). This proposal suggests to explicitly add both defaulted
versions where possible to <tt>pair</tt> and <tt>tuple</tt> which has the least sensitivity to core rule changes. The 
specification gives freedom to implementations to omit both declarations equally, because that would not violate the
required semantics.
<p>
<h3><a name="MoveCopyConstructibleRefs"></a><tt>Move/CopyConstructible</tt> in the presence of reference members</h3>
<p>
The current specification of several member functions of <tt>pair</tt> and <tt>tuple</tt> use requirement
sets that are designed for object types, not for reference types. This becomes obvious by recognizing that
a <tt>MoveConstructible</tt> type (Table 34) can be initialized with an rvalue. This would mean that e.g.
an lvalue-reference to non-const violates this requirement but we don't have any constructor that requires
less! Both heterogeneous container-like types were intended to contain any form of reference, so we need
to ensure that they can hold them. A compiler-generated copy and move constructor of a class type with
reference members &quot;copies&quot; lvalue-references by just rebinding them similar to a pointer - this
should be done by <tt>pair</tt> and <tt>tuple</tt> as well!
<p>
There is another disadvantage to applying semantics-loaden requirements like <tt>MoveConstructible</tt> and
<tt>CopyConstructible</tt>: Both <tt>pair</tt> and <tt>tuple</tt> are only thin wrappers of the contained 
members and there are no member functions that would depend on special invariants of the container
as a whole, thus requiring more than necessary for such fundamental types should be prevented, if possible.
<p>
Given these boundary conditions it turns out that the constraint specified by
<p>
<blockquote><pre>
<b>is_constructible&lt;T, T&amp;&amp;&gt;</b>
</pre></blockquote>
<p>
is necessary and sufficient as a requirement for a move-constructor or move-like-constructor (a template that 
accepts potentially mutable rvalue arguments) of such a container for every type <tt>T</tt> including lvalue-references 
and rvalue-references of object types or function types and is identical in semantics compared to a compiler-generated 
move-constructor. The consequence is, that using
<p>
<blockquote><pre>
<b><tt>std::forward&lt;T&gt;(t)</tt></b>
</pre></blockquote>
<p>
to transfer the direct function argument <tt>t</tt> (or a corresponding member of a tuple-like rvalue)
to the corresponding member for initialization purposes is the correct way to realize the wanted effect: 
Any object type will behave as if <tt>std::move</tt> had been used instead, any lvalue-reference or 
rvalue-reference will just be initialized with the source of appropriate lvalueness.
<p>
What about the copy-constructor? For both lvalue-references and object types the intuitive semantics of 
a compiler-generated copy-constructor is a direct initialization of the corresponding member. This can
easily be expressed by
<p>
<blockquote><pre>
<b>is_constructible&lt;T, const T&amp;&gt;</b>
</pre></blockquote>
<p>
keeping in mind that for reference types reference-collapsing and &quot;<em>cv</em>-folding&quot; ensures the right
semantics in the presence or absence of <em>cv</em>-qualifiers of the referenced type. Neither this requirement
nor the effects of direct initialization will work for rvalue-references, because the corresponding named
argument is an lvalue that does not bind to the rvalue reference. What should be done here? The core-language is still
in the process of evolving but there is currently a tendency to consider that an rvalue-reference as a class
member deletes the copy-constructor. I strongly recommend this approach for the library, because of the following 
simple reason:
<p>
Any rvalue-reference is essentially pointing to an identity that has <strong>given up</strong> ownership of its
previous source; saying that we &quot;copy&quot; just the reference implies that the source of this initialization 
would remain unchanged and could produce an arbitrary number of such copies - but that would be a real trap for the programmer,
because every target of such a copy will legally assume that it is the sole destination of this move!
As an example consider the following situation where we have a string-like container type that takes ownership of 
resources:
<p>
<blockquote><pre>
class MyString { // A class similar to <tt>std::string</tt>  
  /*..*/
};
</pre></blockquote><p>
and where we use a transient <tt>std::tuple&lt;MyString&amp;&amp;&gt;</tt> - e.g. as the result of calling <tt>std::forward_as_tuple</tt> -
to construct a pair of strings like this:
<p>
<blockquote><pre>
void create_and_do(std::tuple&lt;MyString&amp;&amp;&gt; s) {
  std::pair&lt;MyString, MyString&gt; p(std::piecewise_construct, s, s);
  /*..*/
}
</pre></blockquote>
<p>
It would be a clear service to the programmer if this program would not compile, because we are silently moving
an object of type <tt>MyString</tt> twice!<br>
Being required to write instead:
<p>
<blockquote><pre>
void create_and_do(std::tuple&lt;MyString&amp;&amp;&gt; s) {
  std::pair&lt;MyString, MyString&gt; p(std::piecewise_construct, std::move(s), std::move(s)); // Oops?!
  /*..*/
}
</pre></blockquote>
<p>
strongly reduces the risk of such an error, because it becomes immediately visually clear what's happening here.
<p>
<h3><a name="MoveCopyAssignableRefs"></a><tt>Move/CopyAssignable</tt> in the presence of reference members</h3>
<p>
Additional to generalized forms of constructions, both tuple-like containers provide assignment operations, both
moving and copying. The question is, what the correct requirements and semantics of such members should be in
the potential presence of references as members. A first observation is, that both move-assignment and copy-assignment
can be supported by both rvalue-references and lvalue-references. This is different to the initialization situation
because now we are not binding a reference to a matching value, but instead we are just performing an assignment 
operation of the referenced objects (ignoring functions here for a moment, which cannot be assigned at all). The 
most easiest question to answer is what a copy-assignment(-like) operator should do, if the operands are references: 
Since both target and destination are named variables, they are lvalues and thus this is normal copy-assignment.
This is no surprising rule - not even for rvalue-reference members (considered as lvalues because they are named), 
which can also be assigned as in the following example:
<p>
<blockquote><pre>
void assign(int&amp;&amp; lhs, int&amp;&amp; rhs) {
  lhs = rhs;
}
</pre></blockquote>
<p>
Unfortunately we have no trait that properly describes this simple assigment situation. The nearest one would be 
the <tt>has_copy_assign</tt> trait, but it returns <tt>false</tt> for reference types. We could use other traits to 
remove the references from the member types, but actually the situation can be very simple described by an 
(unevaluated) expression of the form
<p>
<blockquote><pre>
std::declval&lt;T&amp;&gt;() = std::declval&lt;const U&amp;&gt;()
</pre></blockquote>
<p>
which is correct in the presence of references as well. Alternatively we could use the existing requirement set
<tt>CopyAssignable</tt>, but this set imposes additional semantic requirements that are not necessary for such
thin type wrappers. Neither <tt>pair</tt>'s nor <tt>tuple</tt>'s invariants of this operation make it necessary
that after the assignment the source remains unchanged - this is very different to normal containers, which
are broken without this guarantee. It is also not necessary that this direct assignment guarantees to be well-formed
with an rvalue or const lvalue as the right operand (again: if the members are reference types), because this 
assignment will <em>only</em> be performed with an lvalue to the left and to the right.
<p>
It would be very helpful, if the library would have a trait - equivalent to <tt>is_constructible</tt> - that just 
returns whether the assignment expression is well-formed. A proposal exists that refactors the current 
assignment-related traits, but in the absence of such component the most simple requirement is that the above 
expression - alternatively expressed via the tuple API as
<p>
<blockquote><pre>
std::get&lt;<em>i</em>&gt;(<em>lhs-tuple-like</em>) = std::get&lt;<em>i</em>&gt;(<em>rhs-tuple-like</em>)
</pre></blockquote>
<p>
is well-formed for all <em>i</em> in the range <tt>[0, std::tuple_size&lt;<em>tuple-like</em>&gt;::value)</tt>.
<p>
The less easier question to answer is what the correct requirements and semantics should be for the move-assignment
operator of tuple-like classes with members of reference type. For non-reference members the most intuitive
behaviour is to give these members the opportunity for a move operation, this would naturally reflect the owner-ship
relation between members that are values and the container type. A first start could be to specify that the required
effects are such that the expression
<p>
<blockquote><pre>
std::get&lt;<em>i</em>&gt;(<em>lhs-tuple-like</em>) = std::move(std::get&lt;<em>i</em>&gt;(<em>rhs-tuple-like</em>))
</pre></blockquote>
<p>
shall be valid for all <em>i</em>. It is uncontroversial for non-reference types and I assert that it is also
uncontroversial for rvalue-reference types, because the tuple-like that is the right operand is an rvalue
that is in the way of giving up it's ownership for these resources. But to the author's opinion it's not quite
so clear whether a similar move semantics as appropriate for lvalue-reference members as well. The reason is,
because such lvalue-references refer to objects (I ignore here functions again) that potentially have a complete
different life-cycle. This becomes much clearer when by an example: Assume we have a class type <tt>C</tt> that 
allows to read or to modify some of its properties via a single tuple:
<p>
<blockquote><pre>
class A {
  std::string value;
public:
  explicit A(const std::string&amp; value) : value(value) {}

  // Normal copy/move semantics:
  A(const A&amp;) = default;
  A(A&amp;&amp;) = default;
  A&amp; operator=(const A&amp;) = default;
  A&amp; operator=(A&amp;&amp;) = default;

  // IO support:
  friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const A&amp; a) {
    return os &lt;&lt; a.value;
  }
};

class C {
  A a;
  int i;
public:
  C(const A&amp; a, int i) : a(a), i(i) {}
  
  std::tuple&lt;const A&amp;, int&gt; data() const { return std::tie(a, i); }
  std::tuple&lt;A&amp;, int&amp;&gt; data() { return std::tie(a, i); }
};
</pre></blockquote>
<p>
Note that we use a very regular pattern here: Instead of providing <em>n</em> individual properties via <tt>2<em>n</em></tt> member functions 
we just provide a single pair of functions each to <em>n</em> properties at once. We can e.g. use this to modify all the properties of an 
object <tt>c</tt> of type <tt>C</tt> at once:
<p>
<blockquote><pre>
c.data() = std::make_tuple(A("Hi!"), 6);
</pre></blockquote>
<p>
Now lets do something with a <tt>C</tt> object:
<p>
<blockquote><pre>
int main() {
  C c(A("What-an-homunculus"), 4);
  A a("");
  int i = 0;
  std::tie(a, i) = c.data(); // #1
  std::cout &lt;&lt; "{" &lt;&lt; a &lt;&lt; ',' &lt;&lt; i &lt;&lt; "}" &lt;&lt; std::endl;
  auto t = c.data(); // #2
  std::cout &lt;&lt; "{" &lt;&lt; std::get&lt;0&gt;(t) &lt;&lt; ',' &lt;&lt; std::get&lt;1&gt;(t) &lt;&lt; "}" &lt;&lt; std::endl;
}
</pre></blockquote>
<p>
Assuming that <tt>tuple</tt>'s move-assignment operator would invoke <tt>std::move</tt> also for lvalue-reference members, the program output
could be:
<p>
<blockquote><pre>
  {What-an-homunculus,4}
  {,4}
</pre></blockquote>
<p>
What has happened here? The problem is that in the line marked with <tt>#1</tt> the move-assignment operator
of <tt>tuple</tt> was invoked, which again has - under the assumption that we would apply <tt>std::move</tt> to all
members - invoked the move-assignment operator of <tt>A</tt>, which again has invoked the move-assignment operator
of <tt>std::string</tt> (and I assume here that the implementation decided to clear the memory of the rvalue source 
string. The same result would occur for implementations that swap their internals). We can observe this silent change 
to <tt>c</tt> by reading the properties again in the line marked with <tt>#2</tt>. This is in my opinion a strong 
argument for <strong>not</strong> applying <tt>std::move</tt> to lvalue-references here. Another way of looking at 
the same problem is to recognize that an <em>rvalue</em> of type <tt>std::tuple&lt;T&amp;&gt;</tt> is actually 
still an <em>lvalue</em> wrapper and the internals behave like a normal lvalue. The most appropriate behavior is in 
fact, that we call <tt>std::forward&lt;T&gt;</tt> for any member of type <tt>T</tt>.
<p>
It should be highlighted that this suggestion is actually neither unusual or without any example: In fact this would 
be <strong>exactly</strong> the same semantics as the move-assignment operator of <tt>std::unique&lt;T, D&gt;</tt>, 
when <tt>D</tt> is a deleter of lvalue-reference type as specified in 20.9.10.2.3 p.1+5. 
<p>
Thus, the suggestion of this proposal is to specify that the effects of a move-assignment(-like)
operator of <tt>pair</tt> or <tt>tuple</tt> should require that the unevaluated expression
<p>
<blockquote><pre>
std::declval&lt;T&amp;&gt;() = std::declval&lt;U&amp;&amp;&gt;()
</pre></blockquote>
<p>
or the corresponding expression
<p>
<blockquote><pre>
std::get&lt;<em>i</em>&gt;(<em>lhs-tuple-like</em>) = std::forward&lt;Ui&gt;(std::get&lt;<em>i</em>&gt;(<em>rhs-tuple-like</em>))
</pre></blockquote>
<p>
shall be valid for all <em>i</em>.
<p>
<h2><a name="Proposed_resolution"></a>Proposed resolution</h2>
<p>
The proposed wording changes refer to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3126.pdf">N3126</a>.
<p>
At some locations this proposal would take advantage of a adjustment proposal in regard to the construction and assignment traits. In particular,
the following ones:
<p>
<blockquote><pre>
is_default_constructible&lt;T&gt; &equiv; is_constructible&lt;T&gt;

is_copy_constructible&lt;T&gt; &equiv; is_constructible&lt;T, const T&amp;&gt;

is_move_constructible&lt;T&gt; &equiv; is_constructible&lt;T, T&amp;&amp;&gt;
</pre></blockquote><p>
as well as this one:
<p>
<blockquote><pre>
template&lt;class T, class U&gt;
struct is_assignable;
</pre></blockquote><p>
which shall be a <tt>BinaryTypeTrait</tt> that evaluates to <tt>true</tt> if and only if the expression
<p>
<blockquote><pre>
std::declval&lt;T&gt;() = std::declval&lt;U&gt;()
</pre></blockquote><p>
is well-formed, and its derived forms:
<p>
<blockquote><pre>
is_copy_assignable&lt;T&gt; &equiv; is_assignable&lt;T&amp;, const T&amp;&gt;

is_move_assignable&lt;T&gt; &equiv; is_assignable&lt;T&amp;, T&amp;&amp;&gt;
</pre></blockquote><p>
At the places where either of these traits would perfectly match, the proposed resolution is split into parts <strong>[A]</strong> 
and <strong>[B]</strong>, where <strong>[A]</strong> assumes the acceptance of the above mentioned proposal, and <strong>[B]</strong> 
the proposal in absence of this trait. This should ease the process of possibly merging them.
<p>
<ol>
<li>Change 20.3.5.2 [pairs.pair], class template <tt>pair</tt> synopsis, as indicated. The intent is to make 
	copy and move constructor trivial, if the types <tt>T1</tt> and <tt>T2</tt> are themselves 
	trivial copyable/movable. Also, without any explicit declaration of the move constructor, its generation will be supressed, 
	because of the explicit declaration of the copy constructor. Finally, the copy/move assignment operators are <em>not</em> 
	defaulted, they must be implemented to allow for assignment semantics via references, as required by the specification and 
	intended by the originally proposing papers:
<p>
<blockquote><pre>
namespace std {
  template &lt;class T1, class T2&gt;
  struct pair {
    typedef T1 first_type;
    typedef T2 second_type;

    T1 first;
    T2 second;
    pair(const pair&amp;) = default;
    <ins>pair(pair&amp;&amp;) = default;</ins>
    constexpr pair();
    pair(const T1&amp; x, const T2&amp; y);
    template&lt;class U, class V&gt; pair(U&amp;&amp; x, V&amp;&amp; y);
    template&lt;class U, class V&gt; pair(const pair&lt;U, V&gt;&amp; p);
    template&lt;class U, class V&gt; pair(pair&lt;U, V&gt;&amp;&amp; p);
    template &lt;class... Args1, class... Args2&gt;
    pair(piecewise_construct_t,
      tuple&lt;Args1...&gt; first_args, tuple&lt;Args2...&gt; second_args);

    <ins>pair&amp; operator=(const pair&amp; p);</ins>
    template&lt;class U, class V&gt; pair&amp; operator=(const pair&lt;U, V&gt;&amp; p);
    pair&amp; operator=(pair&amp;&amp; p);
    template&lt;class U, class V&gt; pair&amp; operator=(pair&lt;U, V&gt;&amp;&amp; p);

    void swap(pair&amp; p);
  };
}
</pre></blockquote><p>
</li>
<li>Insert a new paragraph at the beginning of 20.3.5.2 [pairs.pair] that adds some exception-behaviour clarification that 
	is missing for <tt>pair</tt> (but given for <tt>tuple</tt>):
<p>
<ins>No constructor or member function of <tt>pair</tt> throws an exception unless one of the element-wise operations 
	that are specified to be called during this operation throws an exception.</ins>
</li>
<li>Change 20.3.5.2 [pairs.pair]/1 as indicated. The intent is to add the missing requirements and to describe the 
	initialization context more schematic [Intentionally the <tt>DefaultConstructible</tt> requirements are not imposed 
	here: Type <tt>pair</tt> does not depend on its semantic constraints]:
<p>
<blockquote><pre>
constexpr pair();
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_default_constructible&lt;first_type&gt;::value</tt> is <tt>true</tt> and <tt>is_default_constructible&lt;second_type&gt;::value</tt> is <tt>true</tt>.</ins>
</dd>
<dt><strong>[B]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_constructible&lt;first_type&gt;::value</tt> is <tt>true</tt> and <tt>is_constructible&lt;second_type&gt;::value</tt> is <tt>true</tt>.</ins>
</dd>
</dl>
<p>
1 <em>Effects</em>: <ins>Value-initializes <tt>first</tt> and <tt>second</tt>.</ins><del>Initializes its members as if implemented: <tt>pair() : first(), second() { }</tt></del>
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/2 as indicated. The intent is to add the missing requirements:
<p>
<blockquote><pre>
pair(const T1&amp; x, const T2&amp; y);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_copy_constructible&lt;first_type&gt;::value</tt> is <tt>true</tt> and <tt>is_copy_constructible&lt;second_type&gt;::value</tt> is <tt>true</tt>.</ins>
</dd>
<dt><strong>[B]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_constructible&lt;first_type, const first_type&amp;&gt;::value</tt> is <tt>true</tt> and <tt>is_constructible&lt;second_type, const second_type&amp;&gt;::value</tt> is <tt>true</tt>.</ins>
</dd>
</dl>
<p>
2 <em>Effects</em>: The constructor initializes <tt>first</tt> with <tt>x</tt> and <tt>second</tt> with <tt>y</tt>.
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/3 as indicated. The intent is to add the missing requirements:
<p>
<blockquote><pre>
template&lt;class U, class V&gt; pair(U&amp;&amp; x, V&amp;&amp; y);
</pre><blockquote><p>
<ins><em>Requires</em>: <tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and <tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>.</ins>
<p>
3 <em>Effects</em>: The constructor initializes first with <tt>std::forward&lt;U&gt;(x)</tt> and second with <tt>std::forward&lt;V&gt;(y)</tt>.
<p>
4 <em>Remarks</em>: If <tt>U</tt> is not implicitly convertible to <tt>first_type</tt> or <tt>V</tt> is not implicitly convertible to 
  <tt>second_type</tt> this constructor shall not participate in overload resolution.
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/5 as indicated. The intent is to add the missing requirements (The change in the effects element should be 
	non-normatively) and to add constraints to prevent silent explicit conversions implicitly:
<p>
<blockquote><pre>
template&lt;class U, class V&gt; pair(const pair&lt;U, V&gt;&amp; p);
</pre><blockquote><p>
<ins><em>Requires</em>: <tt>is_constructible&lt;first_type, const U&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, const V&amp;&gt;::value</tt> is <tt>true</tt>.</ins>
<p>
5 <em>Effects</em>: Initializes members from the corresponding members of the argument<del>, performing implicit conversions as needed</del>.
<p>
<ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless <tt>const U&amp;</tt> is implicitly convertible to 
	<tt>first_type</tt> and <tt>const V&amp;</tt> is implicitly convertible to <tt>second_type</tt>.</ins>
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/6 as indicated. The intent is to add the missing requirements, to fix incorrect semantics in terms of 
	<tt>std::move</tt>, and to add constraints to prevent silent explicit conversions implicitly:
<p>
<blockquote><pre>
template&lt;class U, class V&gt; pair(pair&lt;U, V&gt;&amp;&amp; p);
</pre><blockquote><p>
<ins><em>Requires</em>: <tt>is_constructible&lt;first_type, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>.</ins>
<p>
6 <em>Effects</em>: The constructor initializes <tt>first</tt> with <tt>std::<del>move</del><ins>forward&lt;U&gt;</ins>(p.first)</tt> 
and <tt>second</tt> with <tt>std::<del>move</del><ins>forward&lt;V&gt;</ins>(p.second)</tt>.
<p>
<ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless <tt>U</tt> is implicitly convertible to 
	<tt>first_type</tt> and <tt>V</tt> is implicitly convertible to <tt>second_type</tt>.</ins>
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/7 as indicated. The intent is to fix the current requirements:
<p>
<blockquote><pre>
template&lt;class... Args1, class... Args2&gt;
  pair(piecewise_construct_t,
    tuple&lt;Args1...&gt; first_args, tuple&lt;Args2...&gt; second_args);
</pre><blockquote><p>
<p>
7 <em>Requires</em>: <ins><tt>is_constructible&lt;first_type, Args1&amp;&amp;...&gt;::value</tt> is <tt>true</tt> and 
	<tt>is_constructible&lt;second_type, Args2&amp;&amp;...&gt;::value</tt> is <tt>true</tt>.</ins><del>All the types in 
	<tt>Args1</tt> and <tt>Args2</tt> shall be <tt>CopyConstructible</tt> (Table 35). <tt>T1</tt> shall be
  constructible from <tt>Args1</tt>. <tt>T2</tt> shall be constructible from <tt>Args2</tt></del>.
<p>
8 <em>Effects</em>: The constructor initializes <tt>first</tt> with arguments of types <tt>Args1...</tt> obtained by forwarding
the elements of <tt>first_args</tt> and initializes <tt>second</tt> with arguments of types <tt>Args2...</tt> obtained by
forwarding the elements of <tt>second_args</tt>. (Here, forwarding an element <tt>x</tt> of type <tt>U</tt> within a <tt>tuple</tt>
object means calling <tt>std::forward&lt;U&gt;(x)</tt>.) This form of construction, whereby constructor arguments
for <tt>first</tt> and <tt>second</tt> are each provided in a separate <tt>tuple</tt> object, is called <em>piecewise construction</em>.
</blockquote></blockquote><p>
</li>
<li>Add a new paragraph after 20.3.5.2 [pairs.pair]/8 as indicated. The intent is to add the prototype specification of
	the copy-assignment operator, which is intentionally different from the built-in one for reference types. The wording
	also intentionally does <em>not</em> specify its requirements in terms of the semantics-loaden <tt>CopyAssignable</tt> 
	requirements both for consistency with the remaining member function requirements and because the "weak" container
	<tt>pair</tt> does not depend on specific class-invariants that need to be conserved.
<p>
<blockquote><pre>
<ins>pair&amp; operator=(const pair&amp; p);</ins>
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_copy_assignable&lt;first_type&gt;::value</tt> is <tt>true</tt> and
	<tt>is_copy_assignable&lt;second_type&gt;::value</tt> is <tt>true</tt>.</ins>
</dd>
<dt><strong>[B]</strong></dt>
<dd>
<ins><em>Requires</em>: The expressions <tt>first = p.first</tt> and <tt>second = p.second</tt> shall be valid.</ins>
</dd>
</dl>
<p>
<ins><em>Effects</em>: Assigns <tt>p.first</tt> to <tt>first</tt> and <tt>p.second</tt> to <tt>second</tt>.</ins>
<p>
<ins><em>Returns</em>: <tt>*this</tt>.</ins>
<p>
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/9 as indicated. The intent is to fix the usage of "<tt>CopyAssignable</tt> from <tt>U</tt>",
	because the library does not define such a mixed requirement. Instead wording is used in terms of well-formed expressions 
	useful for heterogeneous assignments.
<p>
<blockquote><pre>
template&lt;class U, class V&gt; pair&amp; operator=(const pair&lt;U, V&gt;&amp; p);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
9 <em>Requires</em>: <ins><tt>is_assignable&lt;first_type&amp;, const U&amp;&gt;::value</tt> is <tt>true</tt> and
	<tt>is_assignable&lt;second_type&amp;, const V&amp;&gt;::value</tt> is <tt>true</tt></ins><del><tt>T1</tt> shall 
satisfy the requirements of <tt>CopyAssignable</tt> from <tt>U</tt>. <tt>T2</tt> shall satisfy the requirements of 
	<tt>CopyAssignable</tt> from <tt>V</tt></del>.
<dt><strong>[B]</strong></dt>
<dd>
9 <em>Requires</em>: <ins>The expressions <tt>first = p.first</tt> and <tt>second = p.second</tt> shall be valid</ins><del><tt>T1</tt> shall 
satisfy the requirements of <tt>CopyAssignable</tt> from <tt>U</tt>. <tt>T2</tt> shall satisfy the requirements of 
	<tt>CopyAssignable</tt> from <tt>V</tt></del>.
</dd>
</dl>
<p>
10 <em>Effects</em>: Assigns <tt>p.first</tt> to <tt>first</tt> and <tt>p.second</tt> to <tt>second</tt>.
<p>
11 <em>Returns</em>: <tt>*this</tt>.
<p>
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/12 as indicated. The intent is to add the missing requirements and to fix the current semantics
	in the presence of lvalue-references:
<p>
<blockquote><pre>
pair&amp; operator=(pair&amp;&amp; p);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_move_assignable&lt;first_type&gt;::value</tt> is <tt>true</tt> and
	<tt>is_move_assignable&lt;second_type&gt;::value</tt> is <tt>true</tt>.</ins>
<dt><strong>[B]</strong></dt>
<dd>
<ins><em>Requires</em>: The expressions <tt>first = std::forward&lt;first_type&gt;(p.first)</tt> and 
	<tt>second = std::forward&lt;second_type&gt;(p.second)</tt> shall be valid.</ins>
</dd>
</dl>
<p>
12 <em>Effects</em>: Assigns to <tt>first</tt> with <tt>std::<del>move</del><ins>forward&lt;first_type&gt;</ins>(p.first)</tt> and 
to <tt>second</tt> with <tt>std::<del>move</del><ins>forward&lt;second_type&gt;</ins>(p.second)</tt>.
<p>
13 <em>Returns</em>: <tt>*this</tt>.
<p>
</blockquote></blockquote><p>
</li>
<li>Change 20.3.5.2 [pairs.pair]/14 as indicated. The intent is to add the missing requirements and to fix the current semantics
	in the presence of lvalue-references:
<p>
<blockquote><pre>
template&lt;class U, class V&gt; pair&amp; operator=(pair&lt;U, V&gt;&amp;&amp; p);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
<ins><em>Requires</em>: <tt>is_assignable&lt;first_type&amp;, U&amp;&amp;&gt;::value</tt> is <tt>true</tt> and
	<tt>is_assignable&lt;second_type&amp;, V&amp;&amp;&gt;::value</tt> is <tt>true</tt>.</ins>
</dd>
<dt><strong>[B]</strong></dt>
<dd>
<ins><em>Requires</em>: The expressions <tt>first = std::forward&lt;U&gt;(p.first)</tt> and <tt>second = std::forward&lt;V&gt;(p.second)</tt> shall be valid.</ins>
</dd>
</dl>
<p>
14 <em>Effects</em>: Assigns to <tt>first</tt> with <tt>std::<del>move</del><ins>forward&lt;U&gt;</ins>(p.first)</tt> and to <tt>second</tt> 
with <tt>std::<del>move</del><ins>forward&lt;V&gt;</ins>(p.second)</tt>.
<p>
15 <em>Returns</em>: <tt>*this</tt>.
<p>
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2 [tuple.tuple], class template <tt>tuple</tt> synposis as indicated. The intent is to support a trivial
	move constructor, if the types <tt>T1</tt> and <tt>T2</tt> are themselves trivially movable. 
<p>
<blockquote><pre>
namespace std {
  template &lt;class... Types&gt;
  class tuple {
  public:
    // 20.4.2.1, tuple construction
    [..]
    
    tuple(const tuple&amp;) = default;
    tuple(tuple&amp;&amp;)<ins> = default</ins>;
    
    [..]
  };
}
</pre></blockquote><p>
</li>
<li>Change [tuple.cnstr]/1 as indicated. The intent is to introduce a common nomenclature to prevent unnecessary repetitions in the
	following text:
<p>
1 For each tuple constructor, an exception is thrown only if the construction of one of the types in <tt>Types</tt>
throws an exception. <ins>In the constructor descriptions that follow, let <em>i</em> be in the range <tt>[0, sizeof...(Types))</tt>
in order, <tt>Ti</tt> be the <em>i</em><sup>th</sup> type in <tt>Types</tt>, and <tt>Ui</tt> be the <em>i</em><sup>th</sup> 
type in a template parameter pack named <tt>UTypes</tt>, where indexing is zero-based.</ins>
</li>
<li>Change [tuple.cnstr]/2 as indicated. The intent is to use the proper requirements [Intentionally the <tt>DefaultConstructible</tt> 
	requirements are not imposed here: Type <tt>tuple</tt> does not depend on its semantic constraints]:
<p>
<blockquote><pre>
constexpr tuple();
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
2 <em>Requires</em>: <ins><tt>is_default_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em></ins><del>Each type in 
<tt>Types</tt> shall be default constructible</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
2 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em></ins><del>Each type in 
<tt>Types</tt> shall be default constructible</del>.
</dd>
</dl>
<p>
3 <em>Effects</em>: Value initializes each element.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/4+5 as indicated. The intent is to fix the current requirements and the semantics (which
	can be interpreted to require a copy-initialization):
<p>
<blockquote><pre>
explicit tuple(const Types&amp;...);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
4 <em>Requires</em>: <ins><tt>is_copy_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em></ins><del>Each 
type in <tt>Types</tt> shall be copy constructible</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
4 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, const Ti&amp;&gt;::value == true</tt> for all <em>i</em></ins><del>Each 
type in <tt>Types</tt> shall be copy constructible</del>.
</dd>
</dl>
<p>
5 <em>Effects</em>: <del>Copy i</del><ins>I</ins>nitializes each element with the value of the corresponding parameter.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/6 as indicated. The intent is to fix the current requirements and to constrain this
	constructor, which is extremely greedy:
<p>
<blockquote><pre>
template &lt;class... UTypes&gt;
  explicit tuple(UTypes&amp;&amp;... u);
</pre><blockquote><p>
6 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value == true</tt> for all <em>i</em></ins><del>Each type in 
<tt>Types</tt> shall satisfy the requirements of <tt>MoveConstructible</tt> (Table 34) from the 
corresponding type in <tt>UTypes</tt></del>. <tt>sizeof...(Types) == sizeof...(UTypes)</tt>.
<p>
7 <em>Effects</em>: Initializes the elements in the tuple with the corresponding value in <tt>std::forward&lt;UTypes&gt;(u)</tt>.
<p>
<ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless each type in <tt>UTypes</tt> is implicitly convertible 
	to its corresponding type in <tt>Types</tt>.</ins>
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/8+9 as indicated. The intent is to fix the current requirements (This proposal
	intentionally recommends to keep the additional specification of this defaulted constructor for <tt>tuple</tt> 
	but not for <tt>pair</tt>: This requirements are given to ensure that implementors of <tt>tuple</tt> need to satisfy 
	some minimum criteria).
<p>
<blockquote><pre>
tuple(const tuple&amp; u) = default;
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
8 <em>Requires</em>: <ins><tt>is_copy_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em></ins><del>Each 
 type in <tt>Types</tt> shall satisfy the requirements of <tt>CopyConstructible</tt>(Table 35)</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
8 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, const Ti&amp;&gt;::value == true</tt> for all <em>i</em></ins><del>Each 
 type in <tt>Types</tt> shall satisfy the requirements of <tt>CopyConstructible</tt>(Table 35)</del>.
</dd>
</dl>
<p>
9 <em>Effects</em>: <ins>Initializes</ins><del>Copy constructs</del> each element of <tt>*this</tt> with the corresponding element of <tt>u</tt>.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/10+11 as indicated. The intent is to fix the current requirements (This proposal
	intentionally recommends to keep the additional specification of this defaulted constructor for <tt>tuple</tt> but not for <tt>pair</tt>:
	The requirements are given to ensure that implementors of <tt>tuple</tt> need to satisfy some minimum criteria).
<p>
<blockquote><pre>
tuple(tuple&amp;&amp; u)<ins> = default</ins>;
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
10 <em>Requires</em>: <ins><tt>is_move_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em>.</ins><del>Each type in <tt>Types</tt> shall shall 
	satisfy the requirements of <tt>MoveConstructible</tt> (Table 34)</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
10 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, Ti&gt;::value == true</tt> for all <em>i</em>.</ins><del>Each type in <tt>Types</tt> shall shall 
	satisfy the requirements of <tt>MoveConstructible</tt> (Table 34)</del>.
</dd>
</dl>
<p>
11 <em>Effects</em>: <ins>For all <em>i</em>, initializes the <em>i</em><sup>th</sup></ins><del>Move-constructs each</del>
element of <tt>*this</tt> with <del>the corresponding element of</del><tt><ins>std::forward&lt;Ti&gt;(get&lt;<em>i</em>&gt;(</ins>u<ins>))</ins></tt>.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/12-14 as indicated. The intent is to harmonize the current requirements with the other member functions 
	and to constrain this member function accordingly.
<p>
<blockquote><pre>
template &lt;class... UTypes&gt; tuple(const tuple&lt;UTypes...&gt;&amp; u);
</pre><blockquote><p>
12 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, const Ui&amp;&gt;::value == true</tt> 
	for all <em>i</em></ins><del>Each type in <tt>Types</tt> shall be constructible from the corresponding type in 
	<tt>UTypes</tt></del>. <tt>sizeof...(Types) == sizeof...(UTypes)</tt>.
<p>
13 <em>Effects</em>: Constructs each element of <tt>*this</tt> with the corresponding element of <tt>u</tt>.
<p>
14 <ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless 
	<tt>const Ui&amp;</tt> is implicitly convertible to <tt>Ti</tt> for all <em>i</em>.</ins><del>[ <em>Note</em>: 
	<tt>enable_if</tt> can be used to make the converting constructor and assignment operator exist only in the cases where 
	the source and target have the same number of elements. &mdash; <em>end note</em> ]</del>
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/15+16 as indicated. The intent is to fix the current requirements and to constrain this member function 
	accordingly:
<p>
<blockquote><pre>
template &lt;class... UTypes&gt; tuple(tuple&lt;UTypes...&gt;&amp;&amp; u);
</pre><blockquote><p>
15 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, Ui&amp;&amp;&gt;::value == true</tt> 
	for all <em>i</em></ins><del>Each type in <tt>Types</tt> shall shall satisfy the requirements of 
	<tt>MoveConstructible</tt> (Table 34) from the corresponding type in <tt>UTypes</tt></del>. <tt>sizeof...(Types) == sizeof...(UTypes)</tt>.
<p>
16 Effects: <ins>For all <em>i</em>, initializes the <em>i</em><sup>th</sup></ins><del>Move-constructs each</del> element of 
<tt>*this</tt> with <del>the corresponding element of</del><tt><ins>std::forward&lt;Ui&gt;(get&lt;<em>i</em>&gt;(</ins>u<ins>))</ins></tt>.
<p>
<ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless each type in <tt>UTypes</tt> is implicitly 
	convertible to its corresponding type in <tt>Types</tt>.</ins><del>[ <em>Note</em>: <tt>enable_if</tt> can be used to make the 
	converting constructor and assignment operator exist only in the cases where the source and target have the same number of 
	elements. &mdash; <em>end note</em> ]</del>
</blockquote></blockquote><p>
</li>
<li>
Change 20.4.2.1 [tuple.cnstr]/17+18 as indicated. The intent is to harmonize the current requirements with the remaining member functions
and to add constraints to prevent silent explicit conversions implicitly:
<p>
<blockquote><pre>
template &lt;class U1, class U2&gt; tuple(const pair&lt;U1, U2&gt;&amp; u);
</pre><blockquote><p>
17 <em>Requires</em>: <ins><tt>is_constructible&lt;T0, const U1&amp;&gt;::value == true</tt> for t</ins><del>T</del>he first type 
<ins><tt>T0</tt></ins> in <tt>Types</tt> <del>shall be constructible from <tt>U1</tt></del> and <ins><tt>is_constructible&lt;T1, 
	const U2&amp;&gt;::value == true</tt> for</ins> the second type <ins><tt>T1</tt></ins> in <tt>Types</tt><del> shall be constructible 
	from <tt>U2</tt></del>. <tt>sizeof...(Types) == 2</tt>.
<p>
18 <em>Effects</em>: Constructs the first element with <tt>u.first</tt> and the second element with <tt>u.second</tt>.
<p>
<ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless <tt>const U1&amp;</tt> is implicitly convertible 
	to <tt>T0</tt> and <tt>const U2&amp;</tt> is implicitly convertible to <tt>T1</tt>.</ins>
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.1 [tuple.cnstr]/19+20 as indicated. The intent is to fix the current requirements and to add constraints to prevent 
	silent explicit conversions implicitly:
<p>
<blockquote><pre>
template &lt;class U1, class U2&gt; tuple(pair&lt;U1, U2&gt;&amp;&amp; u);
</pre><blockquote><p>
19 <em>Requires</em>: <ins><tt>is_constructible&lt;T0, U1&amp;&amp;&gt;::value == true</tt> for t</ins><del>T</del>he first type <ins><tt>T0</tt></ins> 
in <tt>Types</tt> <del>shall shall satisfy the requirements of <tt>MoveConstructible</tt>(Table 34) from <tt>U1</tt></del> and 
<ins><tt>is_constructible&lt;T1, U2&amp;&amp;&gt;::value == true</tt> for</ins> the second type <ins><tt>T1</tt></ins> in <tt>Types</tt><del> shall be 
move-constructible from <tt>U2</tt></del>. <tt>sizeof...(Types) == 2</tt>.
<p>
20 <em>Effects</em>: <ins>Initializes</ins><del>Constructs</del> the first element with <tt>std::<del>move</del><ins>forward&lt;U1&gt;</ins>(u.first)</tt> 
and the second element with <tt>std::<del>move</del><ins>forward&lt;U2&gt;</ins>(u.second)</tt>.
<p>
<ins><em>Remarks</em>: This constructor shall not participate in overload resolution unless <tt>U1</tt> is implicitly convertible 
	to <tt>T0</tt> and <tt>U2</tt> is implicitly convertible to <tt>T1</tt>.</ins>
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.2 [tuple.assign]/1 as indicated. The intent is to introduce a common nomenclature to prevent unnecessary repetitions
	in the following text:
<p>
1 For each <tt>tuple</tt> assignment operator, an exception is thrown only if the assignment of one of the types in
<tt>Types</tt> throws an exception.	<ins>In the function descriptions that follow, let <em>i</em> be in the range <tt>[0, sizeof...(Types))</tt>
in order, <tt>Ti</tt> be the <em>i</em><sup>th</sup> type in <tt>Types</tt>, and <tt>Ui</tt> be the <em>i</em><sup>th</sup> 
type in a template parameter pack named <tt>UTypes</tt>, where indexing is zero-based.</ins>
</li>
<li>Change 20.4.2.2 [tuple.assign]/2 as indicated. The intent is to harmonize the current requirements with the remaining member functions,
	there is no reason why tuple should depend on additional semantic constraints imposed on by the <tt>CopyAssignable</tt> requirements:
<p>
<blockquote><pre>
tuple&amp; operator=(const tuple&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
2 <em>Requires</em>: <ins><tt>is_copy_assignable&lt;Ti&gt;::value == true</tt> for all <em>i</em></ins><del>Each type 
	in <tt>Types</tt> shall be <tt>CopyAssignable</tt> (Table 37)</del>.
<dt><strong>[B]</strong></dt>
<dd>
2 <em>Requires</em>: <ins>For all <em>i</em>, the expression <tt>get&lt;<em>i</em>&gt;(*this) = get&lt;<em>i</em>&gt;(u)</tt> 
	shall be valid.</ins><del>Each type in <tt>Types</tt> shall be <tt>CopyAssignable</tt> (Table 37)</del>.
</dd>
</dl>
<p>
3 <em>Effects</em>: Assigns each element of <tt>u</tt> to the corresponding element of <tt>*this</tt>.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.2 [tuple.assign]/5+6 as indicated. The intent is to fix the current requirements, also there is no reason why tuple should 
	depend on additional semantic constraints imposed on by the <tt>MoveAssignable</tt> requirements. Additional the semantics are fixed
	for lvalue-reference members:
<p>
<blockquote><pre>
tuple&amp; operator=(tuple&amp;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
5 <em>Requires</em>: <ins><tt>is_move_assignable&lt;Ti&gt;::value == true</tt> for all <em>i</em></ins><del>Each type in <tt>Types</tt> 
	shall shall satisfy the requirements of <tt>MoveAssignable</tt> (Table 36)</del>.
<dt><strong>[B]</strong></dt>
<dd>
5 <em>Requires</em>: <ins>For all <em>i</em>, the expression <tt>get&lt;<em>i</em>&gt;(*this) = std::forward&lt;Ti&gt;(get&lt;<em>i</em>&gt;(u))</tt> 
	shall be valid</ins><del>Each type in <tt>Types</tt> shall shall satisfy the requirements of <tt>MoveAssignable</tt> 
	(Table 36)</del>.
</dd>
</dl>
<p>
6 <em>Effects</em>: <ins>For all <em>i</em>, assigns to <tt>get&lt;<em>i</em>&gt;(*this)</tt> with 
	<tt>std::forward&lt;Ti&gt;(get&lt;<em>i</em>&gt;(u))</tt></ins><del>Move-assigns each element of <tt>u</tt> to the corresponding 
	element of <tt>*this</tt></del>.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.2 [tuple.assign]/8 as indicated. The intent is to fix the current requirements (There does not exist a requirement set
	<tt>Assignable</tt> and in contrast to other corresponding function we miss to require that both tuple sizes are equal):
<p>
<blockquote><pre>
template &lt;class... UTypes&gt;
  tuple&amp; operator=(const tuple&lt;UTypes...&gt;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
8 <em>Requires</em>: <ins><tt>is_assignable&lt;Ti&amp;, const Ui&amp;&gt;::value == true</tt> for all <em>i</em></ins><del>Each type in 
	<tt>Types</tt> shall be <tt>Assignable</tt> from the corresponding type in <tt>UTypes</tt></del>.
<ins><tt>sizeof...(Types) == sizeof...(UTypes)</tt>.</ins>
<dt><strong>[B]</strong></dt>
<dd>
8 <em>Requires</em>: <ins>For all <em>i</em>, the expression <tt>get&lt;<em>i</em>&gt;(*this) = get&lt;<em>i</em>&gt;(u)</tt> 
	shall be valid</ins><del>Each type in <tt>Types</tt> shall be <tt>Assignable</tt> from the corresponding type in <tt>UTypes</tt></del>.
	<ins><tt>sizeof...(Types) == sizeof...(UTypes)</tt>.</ins>
</dd>
</dl>
<p>
9 <em>Effects</em>: Assigns each element of <tt>u</tt> to the corresponding element of <tt>*this</tt>.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.2 [tuple.assign]/11+12 as indicated. The intent is to fix the current requirements and the unwanted semantics for 
	lvalue-reference members:
<p>
<blockquote><pre>
template &lt;class... UTypes&gt;
  tuple&amp; operator=(tuple&lt;UTypes...&gt;&amp;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
11 <em>Requires</em>: <ins><tt>is_assignable&lt;Ti&amp;, Ui&amp;&amp;&gt;::value == true</tt> for all <em>i</em></ins><del>Each type in 
	<tt>Types</tt> shall satisfy the requirements of <tt>MoveAssignable</tt> (Table 36) from the corresponding type in 
	<tt>UTypes</tt></del>. <tt>sizeof...(Types) == sizeof...(UTypes)</tt>.
<dt><strong>[B]</strong></dt>
<dd>
11 <em>Requires</em>: <ins>For all <em>i</em>, the expression <tt>get&lt;<em>i</em>&gt;(*this) = std::forward&lt;Ui&gt;(get&lt;<em>i</em>&gt;(u))</tt> shall 
	be valid</ins><del>Each type in <tt>Types</tt> shall satisfy the requirements of <tt>MoveAssignable</tt> (Table 36) from the
corresponding type in <tt>UTypes</tt></del>.
	<tt>sizeof...(Types) == sizeof...(UTypes)</tt>.
</dd>
</dl>
<p>
12 <em>Effects</em>: <ins>For all <em>i</em>, assigns to <tt>get&lt;<em>i</em>&gt;(*this)</tt> with 
	<tt>std::forward&lt;Ui&gt;(get&lt;<em>i</em>&gt;(u))</tt></ins><del>Move-assigns each element of <tt>u</tt> to the 
	corresponding element of <tt>*this</tt></del>.
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.2 [tuple.assign]/14+17 as indicated. The intent is to fix the current requirements, also we remove
	the note in p. 17, because it is misplaced here and no longer relevant given the newly added constraints for
	some too greedy or too implicit constructors.
<p>
<blockquote><pre>
template &lt;class U1, class U2&gt; tuple&amp; operator=(const pair&lt;U1, U2&gt;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
14 <em>Requires</em>: <ins><tt>is_assignable&lt;T0&amp;, const U1&amp;&gt;::value == true</tt> for t</ins><del>T</del>he first 
type <ins><tt>T0</tt></ins> in <tt>Types</tt> <del>shall shall satisfy the requirements of <tt>MoveAssignable</tt> (Table 36) 
	from <tt>U1</tt></del> and <ins><tt>is_assignable&lt;T1&amp;, const U2&amp;&gt;::value == true</tt> for</ins> the second 
	type <ins><tt>T1</tt></ins> in <tt>Types</tt><del> shall shall satisfy the requirements of MoveAssignable (Table 36) from 
	<tt>U2</tt></del>. <tt>sizeof...(Types) == 2</tt>.
<dt><strong>[B]</strong></dt>
<dd>
14 <em>Requires</em>: <ins>The expressions <tt>get&lt;0&gt;(*this) = p.first</tt> and <tt>get&lt;1&gt;(*this) = p.second</tt> 
	shall be valid</ins><del>The first type in <tt>Types</tt> shall shall satisfy the requirements of <tt>MoveAssignable</tt> 
	(Table 36) from <tt>U1</tt> and the second type in <tt>Types</tt> shall shall satisfy the requirements of MoveAssignable 
	(Table 36) from <tt>U2</tt></del>. <tt>sizeof...(Types) == 2</tt>.
</dd>
</dl>
<p>
15 <em>Effects</em>: Assigns <tt>u.first</tt> to the first element of <tt>*this</tt> and <tt>u.second</tt> to the second element of <tt>*this</tt>.
<p>
16 <em>Returns</em>: <tt>*this</tt>
<p>
<del>17 [ <em>Note</em>: There are rare conditions where the converting copy constructor is a better match than the
element-wise construction, even though the user might intend differently. An example of this is if one
is constructing a one-element tuple where the element type is another tuple type T and if the parameter
passed to the constructor is not of type T, but rather a tuple type that is convertible to T. The effect of
the converting copy construction is most likely the same as the effect of the element-wise construction
would have been. However, is possible to compare the &quot;nesting depths&quot; of the source and target tuples
and decide to select the element-wise constructor if the source nesting depth is smaller than the target
nesting-depth. This can be accomplished using an enable_if template or other tools for constrained
templates. &mdash; <em>end note</em> ]</del>
</blockquote></blockquote><p>
</li>
<li>Change 20.4.2.2 [tuple.assign]/18+19 as indicated. The intent is to fix the current requirements and semantics:
<p>
<blockquote><pre>
template &lt;class U1, class U2&gt; tuple&amp; operator=(pair&lt;U1, U2&gt;&amp;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
18 <em>Requires</em>: <ins><tt>is_assignable&lt;T0&amp;, U1&amp;&amp;&gt;::value == true</tt> for t</ins><del>T</del>he first type <ins><tt>T0</tt></ins> in 
<tt>Types</tt> <del>shall be <tt>Assignable</tt> from <tt>U1</tt></del> and <ins><tt>is_assignable&lt;T1&amp;, U2&amp;&amp;&gt;::value == true</tt> for</ins> 
the second type <ins><tt>T1</tt></ins> in <tt>Types</tt> <del>shall be <tt>Assignable</tt> from <tt>U2</tt></del>. <tt>sizeof...(Types) == 2</tt>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
18 <em>Requires</em>: <ins>The expressions <tt>get&lt;0&gt;(*this) = std::forward&lt;U1&gt;(p.first)</tt> and <tt>get&lt;1&gt;(*this) = std::forward&lt;U2&gt;(p.second)</tt> 
	shall be valid</ins><del>The first type in <tt>Types</tt> shall be <tt>Assignable</tt> from <tt>U1</tt> and the second type 
	in <tt>Types</tt> shall be <tt>Assignable</tt> from <tt>U2</tt></del>. <tt>sizeof...(Types) == 2</tt>.
</dd>
</dl>
<p>
19 <em>Effects</em>: Assigns <tt>std::<del>move</del><ins>std::forward&lt;U1&gt;</ins>(u.first)</tt> to the first element of 
<tt>*this</tt> and <tt>std::<del>move</del><ins>std::forward&lt;U2&gt;</ins>(u.second)</tt> to the second element of <tt>*this</tt>.
</blockquote></blockquote><p>
</li>
<li>Insert a new paragraph at the very beginning to 20.4.2.4 [tuple.creation]. The intent is to introduce a common nomenclature 
to prevent unnecessary repetitions in the following text:
<p>
<ins>In the function descriptions that follow, let <em>i</em> be in the range <tt>[0, sizeof...(TTypes))</tt>
in order and <tt>Ti</tt> be the <em>i</em><sup>th</sup> type in a template parameter pack named <tt>TTypes</tt>, 
let <em>j</em> be in the range <tt>[0, sizeof...(UTypes))</tt> in order and <tt>Uj</tt> be the <em>j</em><sup>th</sup> 
type in a template parameter pack named <tt>UTypes</tt>, where indexing is zero-based.</ins>
</li>
<li>Change 20.4.2.4 [tuple.creation]/8-15 as indicated. The intent is to fix the current requirements and semantics: 
<p>
<blockquote><pre>
template &lt;class... TTypes, class... UTypes&gt;
  tuple&lt;TTypes..., UTypes...&gt; tuple_cat(const tuple&lt;TTypes...&gt;&amp; t, const tuple&lt;UTypes...&gt;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
8 <em>Requires</em>: <ins><tt>is_copy_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_copy_constructible&lt;Uj&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>CopyConstructible</tt> (Table 35). All the types in <tt>UTypes</tt> shall be 
	<tt>CopyConstructible</tt> (Table 35)</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
8 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, const Ti&amp;&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_constructible&lt;Uj, const Uj&amp;&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>CopyConstructible</tt> (Table 35). All the types in <tt>UTypes</tt> shall be 
	<tt>CopyConstructible</tt> (Table 35)</del>.
</dd>
</dl>
<p>
9 <em>Returns</em>: A <tt>tuple</tt> object constructed by <ins>initializing</ins><del>copy constructing</del> its 
first <tt>sizeof...(TTypes)</tt> elements from the corresponding elements of <tt>t</tt> and <ins>initializing</ins><del>copy constructing</del> 
its last <tt>sizeof...(UTypes)</tt> elements from the corresponding elements of <tt>u</tt>.
</blockquote></blockquote>
<p>
<blockquote><pre>
template &lt;class... TTypes, class... UTypes&gt;
  tuple&lt;TTypes..., UTypes...&gt; tuple_cat(tuple&lt;TTypes...&lt;&amp;&amp; t, const tuple&lt;UTypes...&gt;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
10 <em>Requires</em>: <ins><tt>is_move_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_copy_constructible&lt;Uj&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>MoveConstructible</tt> (Table 34). All the types in <tt>UTypes</tt>
  shall be <tt>CopyConstructible</tt> (Table 35)</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
10 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, Ti&amp;&amp;&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_constructible&lt;Uj, const Uj&amp;&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>MoveConstructible</tt> (Table 34). All the types in <tt>UTypes</tt>
  shall be <tt>CopyConstructible</tt> (Table 35)</del>.
</dd>
</dl>
<p>
11 <em>Returns</em>: A <tt>tuple</tt> object constructed by <ins>initializing the <em>i</em><sup>th</sup> element with 
<tt>std::forward&lt;Ti&gt;(get&lt;<em>i</em>&gt;(t))</tt> for all <em>i</em> and initializing the <tt>(<em>j</em>+sizeof...(TTypes))</tt><sup>th</sup> 
element with <tt>get&lt;<em>j</em>&gt;(u)</tt> for all <em>j</em></ins><del>move constructing its first 
<tt>sizeof...(TTypes)</tt> elements from the corresponding elements of <tt>t</tt> and copy constructing its 
last <tt>sizeof...(UTypes)</tt> elements from the corresponding elements of <tt>u</tt></del>.
</blockquote></blockquote>
<p>
<blockquote><pre>
template &lt;class... TTypes, class... UTypes&gt;
  tuple&lt;TTypes..., UTypes...&gt; tuple_cat(const tuple&lt;TTypes...&gt;&amp; t, tuple&lt;UTypes...&gt;&amp;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
12 <em>Requires</em>: <ins><tt>is_copy_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_move_constructible&lt;Uj&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>CopyConstructible</tt> (Table 35). All the types in <tt>UTypes</tt> shall
  be <tt>MoveConstructible</tt> (Table 34)</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
12 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, const Ti&amp;&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_constructible&lt;Uj, Uj&amp;&amp;&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>CopyConstructible</tt> (Table 35). All the types in <tt>UTypes</tt> shall
  be <tt>MoveConstructible</tt> (Table 34)</del>.
</dd>
</dl>
<p>
13 <em>Returns</em>: A <tt>tuple</tt> object constructed by <ins>initializing the <em>i</em><sup>th</sup> element with 
<tt>get&lt;<em>i</em>&gt;(t)</tt> for all <em>i</em> and initializing the <tt>(<em>j</em>+sizeof...(TTypes))</tt><sup>th</sup> 
element with <tt>std::forward&lt;Uj&gt;(get&lt;<em>j</em>&gt;(u))</tt> for all <em>j</em></ins><del>copy constructing 
its first <tt>sizeof...(TTypes)</tt> elements from the corresponding elements of <tt>t</tt> and move constructing its 
last <tt>sizeof...(UTypes)</tt> elements from the corresponding elements of <tt>u</tt></del>.
</blockquote></blockquote>
<p>
<blockquote><pre>
template &lt;class... TTypes, class... UTypes&gt;
  tuple&lt;TTypes..., UTypes...&gt; tuple_cat(tuple&lt;TTypes...&gt;&amp;&amp; t, tuple&lt;UTypes...&gt;&amp;&amp; u);
</pre><blockquote><p>
<dl>
<dt><strong>[A]</strong></dt>
<dd>
14 <em>Requires</em>: <ins><tt>is_move_constructible&lt;Ti&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_move_constructible&lt;Uj&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>MoveConstructible</tt> (Table 34). All the types in <tt>UTypes</tt>
  shall be <tt>MoveConstructible</tt> (Table 34)</del>.
</dd>
<dt><strong>[B]</strong></dt>
<dd>
14 <em>Requires</em>: <ins><tt>is_constructible&lt;Ti, Ti&amp;&amp;&gt;::value == true</tt> for all <em>i</em> and
	<tt>is_constructible&lt;Uj, Uj&amp;&amp;&gt;::value == true</tt> for all <em>j</em></ins><del>All the types in 
	<tt>TTypes</tt> shall be <tt>MoveConstructible</tt> (Table 34). All the types in <tt>UTypes</tt>
  shall be <tt>MoveConstructible</tt> (Table 34)</del>.
</dd>
</dl>
<p>
15 <em>Returns</em>: A <tt>tuple</tt> object constructed by <ins>initializing the <em>i</em><sup>th</sup> element with 
<tt>std::forward&lt;Ti&gt;(get&lt;<em>i</em>&gt;(t)</tt> for all <em>i</em> and initializing the <tt>(<em>j</em>+sizeof...(TTypes))</tt><sup>th</sup> 
element with <tt>std::forward&lt;Uj&gt;(get&lt;<em>j</em>&gt;(u))</tt> for all <em>j</em></ins><del>move constructing 
its first <tt>sizeof...(TTypes)</tt> elements from the corresponding elements of <tt>t</tt> and move constructing its 
last <tt>sizeof...(UTypes)</tt> elements from the corresponding elements of <tt>u</tt></del>.
</blockquote></blockquote>
<p>
</li>
</ol>
<p>
</p>
<h2><a name="Akn"></a>Acknowledgements</h2>
<p>
I would like to thank Howard Hinnant for his very helpful discussions and comments during reviews of this paper.
</p>
</body></html>