<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>
      N2533 Tuples and Pairs
    </title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <base href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/" />
<style type="text/css">
  p {text-align:justify}
  li {text-align:justify}
  ins {background-color:#FFFF99}
  del {background-color:#FF9999}
</style>
  </head>
  <body>
    document number: N2533=08-0043<br />
    Alisdair Meredith &lt;alisdair.meredith@codegear.com><br />
    2008-02-04

    <h1>Tuples and Pairs</h1>

    <h2>Motivation</h2>
<p>
A number of places in the original 1998 standard libary call for a generic type to handle a pair of values.  The template <code>std::pair</code> was born for this purpose.
</p>
<p>
The proposed library for C++0x includes a generic facility for containers of any fixed number of elements in <code>std::tuple</code>.  In retrospect it would be most convenient to maintain a single facility.  The addition of template aliases to the language makes that possible, although the semantics of a 2 element <code>tuple</code> are subtly different to <code>std::pair</code>.
</p>
This paper, inspired by a comment in <a href="2007/n2270.html">N2270</a>, examines how close we can get to assess if the risk is worthwhile.
</p>


    <h2>Differences between <code>pair</code> and 2-element <code>tuple</code></h2>
    <h3><code>first</code> and <code>second</code></h3>
<p>
The most obvious difference is that <code>pair</code> elements are traditionally accessed as public data members with the names <code>first</code> and <code>second</code>, where <code>tuple</code> elements are accessed with a free function interface <code>get&lt;N>( tuple )</code>.  While the tuple-like free function API is overloaded for <code>pair</code> it is not specifically used in the library wording.
</p>
    
    <h3><code>pair</code> value-initializes both members</h3>
<p>
Another key difference is that where a <code>tuple</code> default-initializes its elements, <code>pair</code> value-initializes them.  Therefore, a <code>pair&lt;double, double></code> will always zero initialize each <code>double</code> element, but a <code>tuple&lt;double, doube></code> will leave them un-initialized.
</p>

    <h3>Emplace support facilities</h3>
<p>
<code>pair</code> has an additional variadic constructor template to support argument forwarding to constructors in the new <code>emplace</code> API supported by most containers.
</p>

    <h3><code>pair</code> is Swappable</h3>
<p>
This oversight for <code>tuple</code> is LWG issue #522.
</p>

    <h3>Compressed-pair optimization</h3>
<p>
<code>tuple</code> permits an additional space-saving optimization, as exploited in the boost <code>compressed_pair</code> library.
</p>


    <h2>Proposal</h2>
    <h3>Redefine <code>std::pair</code> as a template alias</h3>
<p>
Add the following template alias to header <code>&lt;utility></code>:<br />
<code>template&lt; typename T1, typename T2> using pair = tuple&lt;T1,T2>;</code>
</p>
    
    <h3>Move whole of &lt;tuple> header into &lt;utility></h3>
<p>
It is simpler if the template alias and the template is aliases live in the same header.
</p>

    <h3>Provide a 2 element specialization for <code>tuple</code></h3>
<p>
This specialization has the identical specification as std::pair today.
</p>

    
    <h3><code>tuple</code> to value-initialize each element</h3>
<p>
It is not clear that the current <code>tuple</code> interface is completely thought out on this point.  One benefit of not mandating value-initialization is that a <code>tuple</code> might be a trivial class or POD, which is never the case for <code>pair</code>.  However, if this is the intent then additional wording would be required mandating the new <code>= default</code> syntax for the default constructor, at least in the case that all elements are trivial.
</p>
<p>
A more subtle problem with the current specification for the <code>tuple</code> default constructor is that it is not possible to safely zero-initialize the elements, unlike with a simple struct.  An example to illustrate:
</p>
<blockquote><pre>
struct pod { double x; double y; };
typedef tuple&lt;double, double > problem;

struct dangerous {
  pod a;
  problem b;

  dangerous() {};
};

struct safe {
  pod a;
  problem b;

  safe()
    : a()
    , b() <em>// no effect</em>
  {
    get&lt;0>(b) = 0.0;
    get&lt;1>(b) = 0.0;
  };

};
</pre></blockquote>
<p>
Here we use a couple of <code>double</code> elements to show the dangers of default-initialization.  As seen in the <code>dangerous</code> constructor a <code>double</code> (or any other trivial type) is not initialized by value-initialization - it could contain any valid state including a signalling NAN.  Technically any attempt to access the value of an uninitialized object is undefined behaviour, although this rarely bites in practice.
</p>
<p>
However, as demonstrated by the <code>safe</code> constructor, the simple struct will safely zero-initialize its elements when explicitly value-intialized because it is a trivial type. This is not the case with the <code>tuple</code>, requiring the suprising additional member-by-member initialization in the constructor body to guarantee safely initialized values.
</p>


    <h3>Remove redundant code</h3>
<p>
Remove the <code>pair</code> constructor/assignment operator overloads from <code>tuple</code> as they become illegal duplicate definitions.
</p>
<p>
Remove the overloads for tuple query API on <code>pair</code> as they become illegal partial specializations of a function template, and are no longer necessary.
</p>

    <h3>Define <code>swap</code> for <code>tuple</code></h3>
<p>
Resolve LWG issue 522 as indicated below.
</p>

    <h3>Replace all references to <code>pair</code> with <code>tuple</code></h3>
<p>
The following library facilities depend on <code>std::pair</code> and should be expressed using <code>tuple</code> instead.
  <ul>
  <li>20.6.3 get_temporary_buffer</li>
  <li>23 Associative Container requirements - Emplace/insert/equal_range</li>
  <li>23.3 map</li>
  <li>23.3 multimap</li>
  <li>23.3 unordered_map</li>
  <li>23.3 unordered_multimap</li>
  <li>25.1.7 mismatch result</li>
  <li>25.3.3.3 equal_range result</li>
  <li>25.3.7 minmax result</li>
  <li>25.3.7 minmax_element result</li>
  <li>28.9 regex sub_match</li>
  </ul>
</p>

    <h2>Implications</h2>
<p>
<code>pair</code> is automatically compatible with the <code>tie</code> and <code>tuple_cat</code> APIs.
</p>
<p>
Due to recursive definition, all tuples with 2 or more elements will have members first and second, but no higher named members such as third or fourth. Optionally, it might be worthwhile to add the named element <code>first</code> to tuples with a single element.
</p>
<p>
As all tuple elements are value-initialized, tuples will never be trivial types. There may be an efficiency penalty for code preferring the non-initialization of TR1 tuples, but there is a corresponding pay-off in safety.  Traditionally the library prefers efficiency over safety where the latter can be supplied by the diligent developer.  However, it is not clear in this case that the diligence required is reasonable.
</p>
<p>
As the template type name has changed from pair to tuple, it is almost certain to break ABI compatibility, even if the presence of the template alias guaranatees source compatibility.
</p>
<p>
As the basic template is now std::tuple, and std::pair is merely an alias, it is no longer possible for users to create specializations of pair with their own types.
</p>
    
    
    <h2>Discounted options</h2>
    <h3>Use default-initialization for pair members</h3>
<p>
This was discounted as it is reasonable to assume a large body of existing code relying on the value-initialization of pair's elements.
</p>

    <h3>Mandate trivial type for <code>tuple</code></h3>
<p>
Rather than forcing value-intializaiton for each member, mandate that <code>tuple</code> be trivial if all its elements are trivial.  This would solve the example given above, but the problem returns when only some of the elements are trivial.  For example:
<blockquote><pre>
struct mixed { double x; string y; };
typedef tuple&lt;double, string > problem;

struct safe {
  mixed a;
  problem b;

  safe()
    : a()
    , b() <em>// no effect</em>
  {
    get&lt;0>(b) = 0.0;
    <em>// no neeed to initialize get&lt;1>(b)</em>
  };

};
</pre></blockquote>
</p>


    <h2>Proposed Wording</h2>
<p>
Note that this wording also applies an alternative solution to LWG issue 706, currently in Ready status, by explicitly deferring to <code>make_tuple</code>. This new resolution relies on the proposed new function declaration syntax.
</p>
<p>
Move the whole of 20.2.3 [pairs] to 20.3.2[tuple.pairs].<br />
Remove the &lt;tuple> header synopsis (20.3p2).<br />
Ammend as follows:
</p>

Header &lt;utility> synopsis

<blockquote><pre>
namespace std {
  <em>// 20.2.1, operators:</em>
  namespace rel_ops {
    template&lt;class T> bool operator!=(const T&, const T&);
    template&lt;class T> bool operator> (const T&, const T&);
    template&lt;class T> bool operator&lt;=(const T&, const T&);
    template&lt;class T> bool operator>=(const T&, const T&);
  }
  
  <em>// 20.2.2, forward/move:</em>
  template &lt;class T> struct identity;
  template &lt;class T> T&& forward(typename identity&lt;T>::type&&);
  template &lt;class T> typename remove_reference&lt;T>::type&& move(T&&);

  <del><em>// 20.2.3, pairs:</em>
  template &lt;class T1, class T2> struct pair;
  template &lt;class T1, class T2>
  bool operator==(const pair&lt;T1,T2>&, const pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  bool operator&lt; (const pair&lt;T1,T2>&, const pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  bool operator!=(const pair&lt;T1,T2>&, const pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  bool operator> (const pair&lt;T1,T2>&, const pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  bool operator>=(const pair&lt;T1,T2>&, const pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  bool operator&lt;=(const pair&lt;T1,T2>&, const pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  void swap(pair&lt;T1,T2>&, pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  void swap(pair&lt;T1,T2>&&, pair&lt;T1,T2>&);
  template &lt;class T1, class T2>
  void swap(pair&lt;T1,T2>&, pair&lt;T1,T2>&&);
  template &lt;class T1, class T2>
  pair&lt;typename decay&lt;T1>::type, typename decay&lt;T2>::type> make_pair(T1&&, T2&&);

  <em>// 20.2.3, tuple-like access to pair:</em>
  template &lt;class T> class tuple_size;
  template &lt;int I, class T> class tuple_element;

  template &lt;class T1, class T2> struct tuple_size&lt;std::pair&lt;T1, T2> >;
  template &lt;class T1, class T2> struct tuple_element&lt;0, std::pair&lt;T1, T2> >;
  template &lt;class T1, class T2> struct tuple_element&lt;1, std::pair&lt;T1, T2> >;

  template&lt;int I, class T1, class T2> P& get(std::pair&lt;T1, T2>&);
  template&lt;int I, class T1, class T2> const P& get(const std::pair&lt;T1, T2>&);</del>
  
  <ins><em>// 20.3.1, class template tuple:</em>
  template &lt;class... Types> class tuple;

  <em>// 20.3.1.2, tuple creation functions:</em>
  const unspecified ignore;

  template &lt;class... Types>
  tuple&lt;VTypes...> make_tuple(Types&&...);

  template&lt;class... Types>
  tuple&lt;Types&...> tie(Types&...);

  template &lt;class... TTypes, class... UTypes>
  tuple&lt;TTypes..., UTypes...> tuple_cat(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);
  template &lt;class... TTypes, class... UTypes>
  tuple&lt;TTypes..., UTypes...> tuple_cat(tuple&lt;TTypes...>&&, const tuple&lt;UTypes...>&);
  template &lt;class... TTypes, class... UTypes>
  tuple&lt;TTypes..., UTypes...> tuple_cat(const tuple&lt;TTypes...>&, tuple&lt;UTypes...>&&);
  template &lt;class... TTypes, class... UTypes>
  tuple&lt;TTypes..., UTypes...> tuple_cat(tuple&lt;TTypes...>&&, tuple&lt;UTypes...>&&);

  <em>// 20.3.1.3, tuple helper classes:</em>
  template &lt;class T> class tuple_size; // undefined
  template &lt;class... Types> class tuple_size&lt;tuple&lt;Types...> >;
  template &lt;int I, class T> class tuple_element; // undefined
  template &lt;int I, class... Types> class tuple_element&lt;I, tuple&lt;Types...> >;

  <em>// 20.3.1.4, element access:</em>
  template &lt;int I, class... Types>
  typename tuple_element&lt;I, tuple&lt;Types...> >::type& get(tuple&lt;Types...>&);
  template &lt;int I, class ... types>
  typename tuple_element&lt;I, tuple&lt;Types...> >::type const& get(const tuple&lt;Types...>&);

  <em>// 20.3.1.5, relational operators:</em>
  template&lt;class... TTypes, class... UTypes>
  bool operator==(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);
  template&lt;class... TTypes, class... UTypes>
  bool operator&lt;(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);
  template&lt;class... TTypes, class... UTypes>
  bool operator!=(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);
  template&lt;class... TTypes, class... UTypes>
  bool operator>(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);
  template&lt;class... TTypes, class... UTypes>
  bool operator&lt;=(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);
  template&lt;class... TTypes, class... UTypes>
  bool operator>=(const tuple&lt;TTypes...>&, const tuple&lt;UTypes...>&);

  template &lt;class... Types>
  void swap(tuple&lt;Types...>&, tuple&lt;Types...>&);
  template &lt;class... Types>
  void swap(tuple&lt;Types...>&&, tuple&lt;Types...>&);
  template &lt;class... Types>
  void swap(tuple&lt;Types...>&, tuple&lt;Types...>&&);

  <em>// 20.3.2, specialization for pairs:</em>
  template &lt;class T1, class T2> using pair = tuple&lt; T1, T2 >;

  template &lt;class T1, class T2>
  auto make_pair(T1&& x, T2&& y) -> dectype(make_tuple(x,y));</ins>
}
</pre></blockquote>


<h3>20.3.1 Class template tuple [tuple.tuple]</h3>
<blockquote><pre>
template &lt;class... Types>
class tuple
{
public:
  tuple();
  explicit tuple(const Types&...);
  template &lt;class... UTypes>
    explicit tuple(UTypes&&...);
  
  tuple(const tuple&);
  tuple(tuple&&);
  
  template &lt;class... UTypes>
    tuple(const tuple&lt;UTypes...>&);
  template &lt;class... UTypes>
    tuple(tuple&lt;UTypes...>&&);
    
  <del>template &lt;class U1, class U2>
    tuple(const pair&lt;U1, U2>&); // iff sizeof...(Types) == 2
  template &lt;class U1, class U2>
    tuple(pair&lt;U1, U2>&&); // iff sizeof...(Types) == 2</del>
    
  tuple& operator=(const tuple&);
  tuple& operator=(tuple&&);
  
  template &lt;class... UTypes>
    tuple& operator=(const tuple&lt;UTypes...>&);
  template &lt;class... UTypes>
    tuple& operator=(tuple&lt;UTypes...>&&);
    
  <del>template &lt;class U1, class U2>
    tuple& operator=(const pair&lt;U1, U2>&); // iff sizeof...(Types) == 2
  template &lt;class U1, class U2>
    tuple& operator=(pair&lt;U1, U2>&&); // iff sizeof...(Types) == 2</del>
    
  <ins>void swap(tuple&&);</ins>
};
</pre></blockquote>

<h3>20.3.1.1 Construction [tuple.cnstr]</h3>
<p>
<code>tuple();</code>
</p>
<p>
1 <em>Requires:</em> Each type in <code>Types</code> shall be default constructible.
</p>
<p>
2 <em>Effects:</em> <del>Default</del><ins>Value</ins> initializes each element.
</p>

<del>
<p>
<code>template &lt;class U1, class U2> tuple(const pair&lt;U1, U2>& u);</code>
</p>
<p>
16 <em>Requires:</em> The first type in <code>Types</code> shall be constructible from <code>U1</code> and the second type in <code>Types</code> shall be constructible from <code>U2</code>. <code>sizeof...(Types) == 2</code>.
</p>
<p>
17 <em>Effects:</em> Constructs the first element with <code>u.first</code> and the second element with <code>u.second</code>.
</p>
<p>
<code>template &lt;class U1, class U2> tuple(pair&lt;U1, U2>&& u);</code>
</p>
<p>
18 <em>Requires:</em> The first type in <code>Types</code> shall be move constructible from <code>U1</code> and the second type in <code>Types</code> shall be move-constructible from <code>U2</code>. <code>sizeof...(Types) == 2</code>.
</p>
<p>
19 <em>Effects:</em> Constructs the first element with <code>std::move(u.first)</code> and the second element with <code>std::move(u.second)</code>.
</p>

<p>
<code>template &lt;class U1, class U2> tuple& operator=(const pair&lt;U1, U2>& u);</code>
</p>
<p>
32 <em>Requires:</em> The first type in <code>Types</code> shall be move assignable from <code>U1</code> and the second type in <code>Types</code> shall be move assignable from <code>U2</code>. <code>sizeof...(Types) == 2</code>.
</p>
<p>
33 <em>Effects:</em> Assigns <code>u.first</code> to the first element of <code>*this</code> and <code>u.second</code> to the second element of <code>*this</code>.
</p>
<p>
34 <em>Returns:</em> <code>*this</code>
</p>

<p>
<code>template &lt;class U1, class U2> tuple& operator=(pair&lt;U1, U2>&& u);</code>
</p>
<p>
36 <em>Requires:</em> The first type in <code>Types</code> shall be assignable from <code>U1</code> and the second type in <code>Types</code> shall be assignable from <code>U2</code>. <code>sizeof...(Types) == 2</code>.
</p>
<p>
37 <em>Effects:</em> Assigns <code>std::move(u.first)</code> to the first element of <code>*this</code> and <code>std::move(u.second)</code> to the second element of <code>*this</code>.
</p>
<p>
38 <em>Returns:</em> <code>*this</code>.
</p>

</del>

<ins>
<h3>20.3.1.6 <code>tuple</code> specialized algorithms [tuple.swap]</h3>
<p>
<code>void swap(tuple&& rhs);</code>
</p>
<p>
<em>Requires:</em> Each type in <code>Types</code> shall be <code>Swappable</code>.
</p>
<p>
<em>Effects:</em> Calls <code>swap</code> for each element in <code>*this</code> and its corresponding element in <code>rhs</code>.
</p>
<p>
<em>Throws:</em> Nothing, unless one of the element-wise <code>swap</code> calls throw an exception.
</p>

<h3>20.3.1.7 <code>tuple</code> specialized algorithms [tuple.special]</h3>
<p>
<code>template &lt;class... Types><br />
void swap(tuple&lt;Types...>& x, tuple&lt;Types...>& y);<br />
template &lt;class... Types><br />
void swap(tuple&lt;Types...>&& x, tuple&lt;Types...>& y);<br />
template &lt;class... Types><br />
void swap(tuple&lt;Types...>& x, tuple&lt;Types...>&& y);
</code>
</p>
<p>
<em>Effects:</em> <code>x.swap(y)</code>
</p>
</ins>

<h3>20.3.2 Pairs [<ins>tuple.</ins>pairs]</h3>
<p>
1 The library provides a <ins>partial specialization of class</ins> template <ins><code>tuple</code></ins> for heterogeneous pairs of values. The library also provides a matching function template to simplify their construction<del> and several templates that provide access to pair objects as if they were tuple objects (see 20.3.1.3 and 20.3.1.4)</del>.
</p>
<blockquote><pre>
template &lt;class T1, class T2>
struct <del>pair</del><ins>tuple&lt; T1, T2 ></ins> {
  typedef T1 first_type;
  typedef T2 second_type;
  T1 first;
  T2 second;
  <del>pair</del><ins>tuple</ins>();
  <del>pair</del><ins>tuple</ins>(const T1& x, const T2& y);
  template&lt;class U, class V> <del>pair</del><ins>tuple</ins>(U&& x, V&& y);
  <del>pair</del><ins>tuple</ins>(<del>pair</del><ins>tuple</ins>&& p);
  template&lt;class U, class V> <del>pair</del><ins>tuple</ins>(const <del>pair</del><ins>tuple</ins>&lt;U, V>& p);
  template&lt;class U, class V> <del>pair</del><ins>tuple</ins>(<del>pair</del><ins>tuple</ins>&lt;U, V>&& p);
  template&lt;class U, class... Args> <del>pair</del><ins>tuple</ins>(U&& x, Args&&... args);
  <del>pair</del><ins>tuple</ins>& operator=(<del>pair</del><ins>tuple</ins>&& p);
  template&lt;class U, class V> <del>pair</del><ins>tuple</ins>& operator=(<del>pair</del><ins>tuple</ins>&lt;U, V>&& p);
  void swap(<del>pair</del><ins>tuple</ins>&& p);
};

<ins>template &lt;class T1, class T2> using pair = tuple&lt; T1, T2 >;</ins>
</pre></blockquote>
<p>
<code><del>pair</del><ins>tuple</ins>();</code>
</p>
<p>
2 <em>Effects:</em> Initializes its members as if implemented: <code><del>pair</del><ins>tuple</ins>() : first(), second() {}</code>
</p>
<p>
<code><del>pair</del><ins>tuple</ins>(const T1& x, const T2& y);</code>
</p>
<p>
3 <em>Effects:</em> The constructor initializes <code>first</code> with <code>x</code> and <code>second</code> with <code>y</code>.
</p>
<p>
<code>template&lt;class U, class V> <del>pair</del><ins>tuple</ins>(U&& x, V&& y);</code>
</p>
<p>
4 <em>Effects:</em> The constructor initializes <code>first</code> with <code>std::forward&lt;U>(x)</code> and <code>second</code> with <code>std::forward&lt;T>(y)</code>.
</p>
<p>
<code>template&lt;class U, class... Args> <del>pair</del><ins>tuple</ins>(U&& x, Args&&... args);</code>
</p>
<p>
5 <em>Effects:</em> The constructor initializes <code>first</code> with <code>std::forward&lt;U>(x)</code> and <code>second</code> with <code>std::forward&lt;Args>(args)...</code>
</p>
<p>
<code><del>pair</del><ins>tuple</ins>(<del>pair</del><ins>tuple</ins>&& p);</code>
</p>
<p>
6 <em>Effects:</em> The constructor initializes <code>first</code> with <code>std::move(p.first)</code> and <code>second</code> with <code>std::move(p.second)</code>.
</p>
<p>
<code>template&lt;class U, class V> <del>pair</del><ins>tuple</ins>(const <del>pair</del><ins>tuple</ins>&lt;U, V>& p);</code>
</p>
<p>
7 <em>Effects:</em> Initializes members from the corresponding members of the argument, performing implicit conversions as needed.
</p>
<p>
<code>template&lt;class U, class V> <del>pair</del><ins>tuple</ins>(<del>pair</del><ins>tuple</ins>&lt;U, V>&& p);</code>
</p>
<p>
8 <em>Effects:</em> The constructor initializes <code>first</code> with <code>std::move(p.first)</code> and <code>second</code> with <code>std::move(p.second)</code>.
</p>
<p>
<code><del>pair</del><ins>tuple</ins>& operator=(<del>pair</del><ins>tuple</ins>&& p);</code>
</p>
<p>
9 <em>Effects:</em> Assigns to <code>first</code> with <code>std::move(p.first)</code> and to <code>second</code> with <code>std::move(p.second)</code>.
</p>
<p>
10 <em>Returns:</em> <code>*this</code>.
</p>
<p>
<code>template&lt;class U, class V> <del>pair</del><ins>tuple</ins>& operator=(<del>pair</del><ins>tuple</ins>&lt;U, V>&& p);</code>
</p>
<p>
11 <em>Effects:</em> Assigns to <code>first</code> with <code>std::move(p.first)</code> and to <code>second</code> with <code>std::move(p.second)</code>.
</p>
<p>
12 <em>Returns:</em> <code>*this</code>.
</p>
<p>
<code>void swap(<del>pair</del><ins>tuple</ins>&& p);</code>
</p>
<p>
13 <em>Effects:</em> Swaps <code>first</code> with <code>p.first</code> and <code>second</code> with <code>p.second</code>.
</p>
<p>
14 <em>Requires:</em> <code>first_type</code> and <code>second_type</code> must be <code>Swappable</code>.
</p>
<ins>
<p>
<code>template &lt;class T1, class T2><br />
auto make_pair(T1&& x, T2&& y) -> dectype(make_tuple(x,y));</code>
</p>
<p>
18 <em>Returns:</em> <code>make_tuple(x,y)</code>
</p>
</ins>
<del>
<p>
<code>template &lt;class T1, class T2><br />
bool operator==(const pair&lt;T1, T2>& x, const pair&lt;T1, T2>& y);</code>
</p>
<p>
15 <em>Returns:</em> <code>x.first == y.first && x.second == y.second.</code>
</p>
<p>
<code>template &lt;class T1, class T2><br />
bool operator&lt;(const pair&lt;T1, T2>& x, const pair&lt;T1, T2>& y);</code>
</p>
<p>
16 <em>Returns:</em> <code>x.first &lt; y.first || (!(y.first &lt; x.first) && x.second &lt; y.second)</code>.
</p>
<p>
<code>template&lt;class T1, class T2> void swap(pair&lt;T1, T2>& x, pair&lt;T1, T2>& y);<br />
template&lt;class T1, class T2> void swap(pair&lt;T1, T2>&& x, pair&lt;T1, T2>& y);<br />
template&lt;class T1, class T2> void swap(pair&lt;T1, T2>& x, pair&lt;T1, T2>&& y);</code>
</p>
<p>
17 <em>Effects:</em> <code>x.swap(y)</code>
</p>
<p>
<code>template &lt;class T1, class T2><br />
pair&lt;typename decay&lt;T1>::type, typename decay&lt;T2>::type> make_pair(T1&& x, T2&& y);</code>
</p>
<p>
18 <em>Returns:</em> <code>pair&lt;typename decay&lt;T1>::type, typename decay&lt;T2>::type>(std::forward&lt;T1>(x), std::forward&lt;T2>(y))</code>
</p>
<p>
19 [ <em>Example:</em> In place of:<br />
<pre>    return pair&lt;int, double>(5, 3.1415926); <em>// explicit types</em></pre>
a C++ program may contain:
<pre>    return make_pair(5, 3.1415926); <em>// types are deduced</em></pre>
<em>—end example</em> ]
</p>
<p>
tuple_size&lt;pair&lt;T1, T2> >::value
</p>
<p>
20 <em>Returns:</em> integral constant expression.
</p>
<p>
21 Value: 2.
</p>
<p>
tuple_element&lt;0, pair&lt;T1, T2> >::type
</p>
<p>
22 Value: the type T1.
</p>
<p>
tuple_element&lt;1, pair&lt;T1, T2> >::type
</p>
<p>
23 Value: the type T2.
</p>
<p>
template&lt;int I, class T1, class T2>
P& get(pair&lt;T1, T2>&);
template&lt;int I, class T1, class T2>
const P& get(const pair&lt;T1, T2>&);
</p>
<p>
24 Return type: If I == 0 then P is T1, if I == 1 then P is T2, and otherwise the program is ill-formed.
</p>
<p>
25 <em>Returns:</em> If I == 0 returns p.first, otherwise returns p.second.
</p>
</del>

<h3>20.6.3 Temporary buffers [temporary.buffer]</h3>
<p>
<code>template &ltclass T><br />
<del>pair</del><ins>tuple</ins>&lt;T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t n);</code>
</p>
<p>
1 <em>Effects:</em> Obtains a pointer to storage sufficient to store up to <code>n</code> adjacent <code>T</code> objects. It is implementation-defined
whether over-aligned types are supported (3.11).
</p>
<p>
2 <em>Returns:</em> A <code><del>pair</del><ins>tuple</ins></code> containing the buffer’s address and capacity (in the units of <code>sizeof(T)</code>), or a pair of 0 values if no storage can be obtained or if <code>n <= 0</code>.
</p>


<h3>23.1.2 Associative containers [associative.reqmts]</h3>

5 For <code>set</code> and <code>multiset</code> the value type is the same as the key type. For <code>map</code> and <code>multimap</code> it is equal to <code><del>pair</del><ins>tuple</ins>&lt;const Key, T></code>. Keys in an associative container are immutable.


<h3>23.1.3 Unordered associative containers [unord.req]</h3>

7 For <code>unordered_set</code> and <code>unordered_multiset</code> the value type is the same as the key type. For <code>unordered_map</code> and <code>unordered_multimap</code> it is <code>std::<del>pair</del><ins>tuple</ins>&lt;const Key, T></code>.



<h3>23.3 Associative containers [associative]</h3>
1 Headers &lt;map> and &lt;set>:

Header &lt;map> synopsis
<blockquote><pre>
namespace std {
  template &lt;class Key, class T, class Compare = less&lt;Key>,
            class Allocator = allocator&lt;<del>pair</del><ins>tuple</ins>&lt;const Key, T> > >
    class map;

...

  template &lt;class Key, class T, class Compare = less&lt;Key>,
            class Allocator = allocator&lt;<del>pair</del><ins>tuple</ins>&lt;const Key, T> > >
    class multimap;

...

}
</pre></blockquote>



<h3>23.3.1 Class template map [map]</h3>
<p>
1 A map is an associative container that supports unique keys (contains at most one of each key value) and provides for
fast retrieval of values of another type T based on the keys. The map class supports bidirectional iterators.
</p>
<p>
2 A map satisfies all of the requirements of a container and of a reversible container (23.1) and of an associative container
(23.1.2). A map also provides most operations described in (23.1.2) for unique keys. This means that a map supports the
a_uniq operations in (23.1.2) but not the a_eq operations. For a map&lt;Key,T> the key_type is Key and the value_-
type is <del>pair</del><ins>tuple</ins>&lt;const Key,T>. Descriptions are provided here only for operations on map that are not described in one
of those tables or for operations where there is additional semantic information.
</p>
<blockquote><pre>
namespace std {
  template &lt;class Key, class T, class Compare = less&lt;Key>,
            class Allocator = allocator&lt;<del>pair</del><ins>tuple</ins>&lt;const Key, T> > >
  class map {
  public:
    // types:
    typedef Key key_type;
    typedef T mapped_type;
    typedef <del>pair</del><ins>tuple</ins>&lt;const Key, T> value_type;
    typedef Compare key_compare;
    typedef Allocator allocator_type;
    typedef typename Allocator::reference reference;
    typedef typename Allocator::const_reference const_reference;
    typedef implementation-defined iterator; // See 23.1
    typedef implementation-defined const_iterator; // See 23.1
    typedef implementation-defined size_type; // See 23.1
    typedef implementation-defined difference_type;// See 23.1
    typedef typename Allocator::pointer pointer;
    typedef typename Allocator::const_pointer const_pointer;
    typedef std::reverse_iterator&lt;iterator> reverse_iterator;
    typedef std::reverse_iterator&lt;const_iterator> const_reverse_iterator;

    ...
    
    <em>// modifiers:</em>
    template &lt;class... Args> <del>pair</del><ins>tuple</ins>&lt;iterator, bool> emplace(Args&&... args);
    template &lt;class... Args> iterator emplace(const_iterator position, Args&&... args);
    <del>pair</del><ins>tuple</ins>&lt;iterator, bool> insert(const value_type& x);
    template &lt;class P> <del>pair</del><ins>tuple</ins>&lt;iterator, bool> insert(P&& x);
    iterator insert(const_iterator position, const value_type& x);
    template &lt;class P>
    iterator insert(const_iterator position, P&&);
    template &lt;class InputIterator>
    void insert(InputIterator first, InputIterator last);

    ...
    
    <em>// 23.3.1.4 map operations:</em>
    
    <del>pair</del><ins>tuple</ins>&lt;iterator,iterator>
      equal_range(const key_type& x);
    <del>pair</del><ins>tuple</ins>&lt;const_iterator,const_iterator>
      equal_range(const key_type& x) const;
};
</pre></blockquote>


<h3>23.3.2 Class template multimap [multimap]</h3>
<p>
1. A <code>multimap</code> is an associative container that supports equivalent keys (possibly containing multiple copies of the same key value) and provides for fast retrieval of values of another type <code>T</code> based on the keys. The <code>multimap</code> class supports bidirectional iterators.
</p>
<p>
2. A <code>multimap</code> satisfies all of the requirements of a container and of a reversible container (23.1) and of an associative container (23.1.2). A multimap also provides most operations described in (23.1.2) for equal keys. This means that a <code>multimap</code> supports the <code>a_eq</code> operations in (23.1.2) but not the <code>a_uniq</code> operations. For a <code>multimap&lt;Key,T></code> the <code>key_type</code> is <code>Key</code> and the <code>value_type</code> is <code><del>pair></del><ins>tuple</ins>&lt;const Key,T></code>. Descriptions are provided here only for operations on <code>multimap</code> that are not described in one of those tables or for operations where there is additional semantic information.
</p>
<blockquote><pre>
namespace std {
  template &lt;class Key, class T, class Compare = less&lt;Key>,
            class Allocator = allocator&lt;<del>pair></del><ins>tuple</ins>&lt;const Key, T> > >
  class multimap {
  public:
    <i>// types:</i>
    typedef Key key_type;
    typedef T mapped_type;
    typedef <del>pair></del><ins>tuple</ins>&lt;const Key,T> value_type;
    typedef Compare key_compare;
    typedef Allocator allocator_type;
    typedef typename Allocator::reference reference;
    typedef typename Allocator::const_reference const_reference;
    typedef implementation-defined iterator; // See 23.1
    typedef implementation-defined const_iterator; // See 23.1
    typedef implementation-defined size_type; // See 23.1
    typedef implementation-defined difference_type;// See 23.1
    typedef typename Allocator::pointer pointer;
    typedef typename Allocator::const_pointer const_pointer;
    typedef std::reverse_iterator&lt;iterator> reverse_iterator;
    typedef std::reverse_iterator&lt;const_iterator> const_reverse_iterator;

    ...

    <i>// map operations:</i>
    iterator find(const key_type& x);
    const_iterator find(const key_type& x) const;
    size_type count(const key_type& x) const;
    iterator lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    iterator upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;

    <del>pair></del><ins>tuple</ins>&lt;iterator,iterator>
equal_range(const key_type& x);
    <del>pair></del><ins>tuple</ins>&lt;const_iterator,const_iterator>
equal_range(const key_type& x) const;
  };
}
</pre></blockquote>


<h3>23.3.3 Class template set [set]</h3>
<blockquote><pre>
namespace std {
  template &lt;class Key, class Compare = less&lt;Key>,
            class Allocator = allocator&lt;Key> >
  class set {
  public:

    ....

    <i>// modifiers:</i>
    template &lt;class... Args> <del>pair></del><ins>tuple</ins>&lt;iterator, bool> emplace(Args&&... args);
    template &lt;class... Args> iterator emplace(const_iterator position, Args&&... args);
    <del>pair></del><ins>tuple</ins>&lt;iterator,bool> insert(const value_type& x);
    <del>pair></del><ins>tuple</ins>&lt;iterator,bool> insert(value_type&& x);
    iterator insert(const_iterator position, const value_type& x);
    iterator insert(const_iterator position, value_type&& x);
    template &lt;class InputIterator>
    void insert(InputIterator first, InputIterator last);
    iterator erase(const_iterator position);
    size_type erase(const key_type& x);
    iterator erase(const_iterator first, const_iterator last);
    void swap(set&lt;Key,Compare,Allocator>&);
    void clear();

    <i>// observers:</i>
    key_compare key_comp() const;
    value_compare value_comp() const;

    <i>// set operations:</i>
    iterator find(const key_type& x);
    const_iterator find(const key_type& x) const;
    size_type count(const key_type& x) const;
    iterator lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    iterator upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;
    <del>pair></del><ins>tuple</ins>&lt;iterator,iterator> equal_range(const key_type& x);
    <del>pair></del><ins>tuple</ins>&lt;const_iterator,const_iterator>   equal_range(const key_type& x) const;
  };
}
</pre></blockquote>


<h3>23.3.4 Class template multiset [multiset]</h3>
<blockquote><pre>
namespace std {
  template &lt;class Key, class Compare = less&lt;Key>,
            class Allocator = allocator&lt;Key> >
  class multiset {
  public:

    ....

    // set operations:
    iterator find(const key_type& x);
    const_iterator find(const key_type& x) const;
    size_type count(const key_type& x) const;
    iterator lower_bound(const key_type& x);
    const_iterator lower_bound(const key_type& x) const;
    iterator upper_bound(const key_type& x);
    const_iterator upper_bound(const key_type& x) const;
    <del>pair></del><ins>tuple</ins>&lt;iterator,iterator> equal_range(const key_type& x);
    <del>pair></del><ins>tuple</ins>&lt;const_iterator,const_iterator> equal_range(const key_type& x) const;
  };
}
</pre></blockquote>


<h3>25.1.7 Mismatch [mismatch]</h3>
<pre>template&lt;class InputIterator1, class InputIterator2>
  <del>pair</del><ins>tuple</ins>&lt;InputIterator1, InputIterator2>
    mismatch(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2);
             
template&lt;class InputIterator1, class InputIterator2,
class BinaryPredicate>
  <del>pair</del><ins>tuple</ins>&lt;InputIterator1, InputIterator2>
    mismatch(InputIterator1 first1, InputIterator1 last1,
             InputIterator2 first2, BinaryPredicate pred);</pre>
<p>
1 <em>Returns:</em> A pair of iterators <code>i</code> and <code>j</code> such that <code>j == first2 + (i - first1)</code> and <code>i</code> is the first iterator in the range <code>[first1,last1)</code> for which the following corresponding conditions hold:
<pre>!(*i == *(first2 + (i - first1)))
pred(*i, *(first2 + (i - first1))) == false</pre>
Returns the pair <code>last1</code> and <code>first2 + (last1 - first1)</code> if such an iterator <code>i</code> is not found.
</p>
<p>
2 <em>Complexity:</em> At most <code>last1 - first1</code> applications of the corresponding predicate.
</p>


<h3>25.3.3.3 equal_range [equal.range]</h3>

<pre>template&lt;class ForwardIterator, class T>
  <del>pair</del><ins>tuple</ins>&lt;ForwardIterator, ForwardIterator>
    equal_range(ForwardIterator first,
                ForwardIterator last, const T& value);
                
template&lt;class ForwardIterator, class T, class Compare>
  <del>pair</del><ins>tuple</ins>&lt;ForwardIterator, ForwardIterator>
    equal_range(ForwardIterator first,
                ForwardIterator last, const T& value, Compare comp);</pre>
<p>
1 <em>Requires:</em> The elements <code>e</code> of <code>[first,last)</code> are partitioned with respect to the expressions <code>e &lt; value</code> and
<code>!(value &lt; e)</code> or <code>comp(e, value)</code> and <code>!comp(value, e)</code>. Also, for all elements <code>e</code> of <code>[first, last)</code>, <code>e &lt; value</code> implies <code>!(value &lt; e)</code> or <code>comp(e, value)</code> implies <code>!comp(value, e)</code>.
</p>
<p>
2 <em>Returns:</em>
<pre>    make_<del>pair</del><ins>tuple</ins>(lower_bound(first, last, value),
               upper_bound(first, last, value))</pre>
or
<pre>    make_<del>pair</del><ins>tuple</ins>(lower_bound(first, last, value, comp),
               upper_bound(first, last, value, comp))</pre>
</p>
<p>
3 <em>Complexity:</em> At most <code>2*log2(last − f irst)+O(1)</code> comparisons.
</p>

<pre>template&lt;class ForwardIterator>
  <del>pair</del><ins>tuple</ins>&lt;ForwardIterator, ForwardIterator>
    minmax_element(ForwardIterator first, ForwardIterator last);

template&lt;class ForwardIterator, class Compare>
  <del>pair</del><ins>tuple</ins>&lt;ForwardIterator, ForwardIterator>
    minmax_element(ForwardIterator first, ForwardIterator last, Compare comp);</pre>
<p>
15 <em>Returns:</em> <code>make_<del>pair</del><ins>tuple</ins>(m, M)</code>, where <code>m</code> is <code>min_element(first, last)</code> or <code>min_element(first, last, comp)</code> and <code>M</code> is <code>max_element(first, last)</code> or <code>max_element(first, last, comp)</code>.
</p>
<p>
16 <em>Complexity:</em> At most <code>max(2 * (last - first) - 2, 0)</code> applications of the corresponding comparisons.
</p>



<h3>25.3.7 Minimum and maximum [alg.min.max]</h3>

<pre>template&lt;class T> <del>pair</del><ins>tuple</ins>&lt;const T&, const T&> minmax(const T& a, const T& b);

template&lt;class T, class Compare>
  <del>pair</del><ins>tuple</ins>&lt;const T&, const T&> minmax(const T& a, const T& b, Compare comp);</pre>
<p>
7 <em>Requires:</em> Type <code>T</code> shall be <code>LessThanComparable</code> (32).
</p>
<p>
8 <em>Returns:</em> <code><del>pair</del><ins>tuple</ins>&lt;const T&, const T&>(b, a)</code> if <code>b</code> is smaller than <code>a</code>, and <code><del>pair</del><ins>tuple</ins>&lt;const T&, const T&>(a, b)</code> otherwise.
</p>
<p>
9 <em>Remarks:</em> Returns <code><del>pair</del><ins>tuple</ins>&lt;const T&, const T&>(a, b)</code> when the arguments are equivalent.
</p>
<p>
10 <em>Complexity:</em> Exactly one comparison.
</p>










<h3>28.9 Class template sub_match [re.submatch]</h3>
1 Class template sub_match denotes the sequence of characters matched by a particular marked sub-expression.
<blockquote><pre>
template &lt;class BidirectionalIterator>
class sub_match : public std::<del>pair</del><ins>tuple</ins>&lt;BidirectionalIterator, BidirectionalIterator>
{
public:
  typedef typename iterator_traits&lt;BidirectionalIterator>::
    value_type                       value_type;
  typedef typename iterator_traits&lt;BidirectionalIterator>::
    difference_type                  difference_type;
  typedef BidirectionalIterator      iterator;
  
  bool matched;
  
  difference_type length() const;
  operator basic_string&lt;value_type>() const;
  basic_string&lt;value_type> str() const;
  
  int compare(const sub_match& s) const;
  int compare(const basic_string&lt;value_type>& s) const;
  int compare(const value_type* s) const;
};
</pre></blockquote>


  </body>
</html>
