<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  
  <style type="text/css">
.comment { color: #999999; font-style: italic; }
.pre { color: #000099; }
.string { color: #009900; }
.char { color: #009900; }
.float { color: #996600; }
.int { color: #999900; }
.bool { color: #000000; font-weight: bold; }
.type { color: #FF6633; }
.flow { color: #FF0000; }
.keyword { color: #990000; }
.operator { color: #663300; font-weight: bold; }
.operator { color: #663300; font-weight: bold; }
pre.code {
    border: 2px solid #666;
    background-color: #F4F4F4;
    padding-left: 10px;
    padding-top: 0px;
}
code {
    border: 2px solid #d0d0d0;
    background-color: LightYellow;
    padding: 2px;
    padding-left: 10px;
    display:table;
    white-space:pre;
    margin:2px;
    margin-bottom:10px;
}
dt
{
    font-weight: bold;
}
    
.ins {
    background-color:#A0FFA0;
}

.del {
    background-color:#FFA0A0;
    text-decoration:line-through
}    
  </style>
  <title>Wording for Addressing Tuples by Type: Revision 2</title>

  
</head><body>
<p>N3670<br>
Revision of: N3584<br>
2013-04-19<br>
Mike Spertus, Symantec<br>

<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a><br>

<br></p>

<h1>Wording for Addressing Tuples by Type: Revision 2</h1>

<p>In Portland, LWG accepted the "Addressing <span style="font-family: monospace;">tuple</span>s by type" portion of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3404.html">n3404</a>,
pending wording, which is provided below.
Note that the "Functoriality" proposal in that paper was not accepted.</p>

<h2>Overview<br>
</h2>

N3404 proposed allowing <span style="font-family: monospace;">tuple</span>s
to be addressed by type as well as by numerical index.<br>

<code>tuple&lt;string, string, int&gt; t("foo", "bar", 7);
int i = get&lt;int&gt;(t);<span class="comment"> // i == 7</span>
int j = get&lt;2&gt;(t); <span class="comment"> // Equivalent to the above: j == 7</span>
string s = get&lt;string&gt;(t);<span class="comment"> // Compile-time error. Ambiguous</span></code>
<h2>Wording</h2>
<p>Modify 20.2p2 [utility] as follows:</p>
<blockquote>
<pre style="padding:0;margin:0">template&lt;size_t I, class T1, class T2&gt;
  constexpr typename tuple_element&lt;I, std::pair&lt;T1, T2&gt; &gt;::type&amp; get(std::pair&lt;T1, T2&gt;&amp;) noexcept;
template&lt;size_t I, class T1, class T2&gt;
  constexpr typename tuple_element&lt;I, std::pair&lt;T1, T2&gt; &gt;::type&amp;&amp; get(std::pair&lt;T1, T2&gt;&amp;&amp;) noexcept;
template&lt;size_t I, class T1, class T2&gt;
  constexpr const typename tuple_element&lt;I, std::pair&lt;T1, T2&gt; &gt;::type&amp;
    get(const std::pair&lt;T1, T2&gt;&amp;) noexcept;
<span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp; get(pair&lt;T, U&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr const T&amp; get(const pair&lt;T, U&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp;&amp; get(pair&lt;T, U&gt;&amp;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp; get(pair&lt;U, T&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr const T&amp; get(const pair&lt;U, T&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp;&amp; get(pair&lt;U, T&gt;&amp;&amp; p) noexcept;</span></pre>
<span class="comment">// 20.3.5, pair piecewise construction</span></blockquote>

		<p>Add the following to the end of 20.3.4 [pair.astuple]:</p>
<blockquote>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp; get(pair&lt;T, U&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr const T&amp; get(const pair&lt;T, U&gt;&amp; p) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> <tt>T</tt> and 
        <tt>U</tt> are distinct types. Otherwise, the program is ill-formed.</span><br>
        <span class="ins"><em>Returns:</em> <tt>get&lt;0&gt;(p);</tt></span></blockquote>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp;&amp; get(pair&lt;T, U&gt;&amp;&amp; p) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> <tt>T</tt> and 
        <tt>U</tt> are distinct types. Otherwise, the program is ill-formed.</span><br>
        <span class="ins"><em>Returns:</em> <tt>get&lt;0&gt;(move(p));</tt></span></blockquote>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp; get(pair&lt;U, T&gt;&amp; p) noexcept;</span></pre>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr const T&amp; get(const pair&lt;U, T&gt;&amp; p) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> <tt>T</tt> and 
        <tt>U</tt> are distinct types. Otherwise, the program is ill-formed.</span><br>
        <span class="ins"><em>Returns:</em> <tt>get&lt;1&gt;(p);</tt></span></blockquote>
<pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class U&gt;</span>
<span class="ins">  constexpr T&amp;&amp; get(pair&lt;U, T&gt;&amp;&amp; p) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> <tt>T</tt> and 
        <tt>U</tt> are distinct types. Otherwise, the program is ill-formed.</span><br>
        <span class="ins"><em>Returns:</em> <tt>get&lt;1&gt;(move(p));</tt></span></blockquote></blockquote>
    <p>Modify 20.4.1p2 [tuple.general] as follows:</p>
<blockquote><pre style="padding:0;margin:0"><span class="comment">// 20.4.2.6, element access:</span>
template &lt;size_t I, class... Types&gt;
  constexpr typename tuple_element&lt;I, tuple&lt;Types...&gt; &gt;::type&amp; get(tuple&amp;lt;Types...&gt;&amp;) noexcept;
template &lt;size_t I, class... types&gt;
  constexpr typename tuple_element&lt;I, tuple&lt;Types...&gt; &gt;::type&amp;&amp; get(tuple&amp;lt;Types...&gt;&amp;&amp;) noexcept;
template &lt;size_t I, class... types&gt;
  constexpr typename tuple_element&lt;I, tuple&lt;Types...&gt; &gt;::type const&amp; get(const tuple&lt;Types...&gt;&amp;) noexcept;
<span class="ins">template &lt;class T, class... Types&gt;
  constexpr T&amp; get(tuple&lt;Types...&gt;&amp; t) noexcept;
template &lt;class T, class... Types&gt;
  constexpr T&amp;&amp; get(tuple&lt;Types...&gt;&amp;&amp; t) noexcept;
template &lt;class T, class... Types&gt;
  constexpr const T&amp; get(const tuple&lt;Types...&gt;&amp; t) noexcept;</span>
<span class="comment">// 20.4.2.7, relational operators:</span></pre></blockquote>
    <p>Add the following after 20.4.2.6p7 [tuple.elem]:</p>
<blockquote><pre style="padding:0;margin:0"><span class="ins">template &lt;class T, class... Types&gt;
  constexpr T&amp; get(tuple&lt;Types...&gt;&amp; t) noexcept;
template &lt;class T, class... Types&gt;
  constexpr T&amp;&amp; get(tuple&lt;Types...&gt;&amp;&amp; t) noexcept;
template &lt;class T, class... Types&gt;
  constexpr const T&amp; get(const tuple&lt;Types...&gt;&amp; t) noexcept;</span></pre>
    <blockquote style="padding:0;margin-top:0"><span class="ins"><em>Requires:</em> The type <tt>T</tt> occurs 
        exactly once in <tt>Types...</tt>. Otherwise, the program is ill-formed.</span><br>
<span class="ins"><em>Returns:</em> A reference to the element of <tt>t</tt> corresponding to the type <tt>T</tt> in <tt>Types...</tt>.</span></blockquote>
<span class="ins">[ <em>Example:</em></span>
<pre>  <span class="ins">const tuple&lt;int, const int, double, double&gt; t(1, 2, 3.4, 5.6);
  const int &amp;i1 = get&lt;int&gt;(t); <span class="comment"> // OK. Not ambiguous. i1 == 1</span>
  const int &amp;i2 = get&lt;const int&gt;(t); <span class="comment"> // OK. Not ambiguous. i2 == 2</span> 
  const double &amp;d = get&lt;double&gt;(t); <span class="comment"> // ERROR. ill-formed</span>
</span></pre><span class="ins"><em>&#8212; end example</em> ]</span></blockquote>
		
</body></html>