<!DOCTYPE html>
<html>
	<head>
		<title>Proposing type_at&lt;&gt; and value_at&lt;&gt;</title>
	</head>
	<body>

		<div>
			Document Number: N3761<br>
			Date: 2013-08-29<br>
			Author: Sean Middleditch &lt;sean@seanmiddleditch.com&gt;<br>
			Project: Programming Language C++, Library Working Group<br>
			Reply-To: <a href="mailto:sean@seanmiddleditch.com">Sean Middleditch</a><br>
		</div>

		<h1>Proposing type_at&lt;&gt;</h1>

		<h2>Overview</h2>

		<p>The standard library currently is missing utility templates for extracting types from a variadic template type list, requiring users to instantiate a std::tuple&lt;&gt; in order to extract a type from a specific position within a variadic template type list.</p>

		<p>A simple library addition can make certain recurisve uses of variadic templates easier and not dependent on the unrelated concept of a tuple.</p>

		<p>This proposal is a pure library addition with no language changes or backwards compatibility regressions.  The proposed language for value_at&lt;&gt; depends on N3638, though it could be written without this requirement using type_at&lt;&gt; instead.</p>

		<h2>Discussion</h2>

		<p>This paper proposes the new library names type_at and value_at.  Some alternative names, should the proposed one be deemed unacceptable, include:</p>

		<ul>
			<li>nth_type and nth_value</li>
			<li>get_type and get_value</li>
			<li>unpack_type and unpack_value</li>
			<li>type_i and value_i</li>
			<li>index_type and index_value</li>
		</ul>

		<h2>Proposal</h2>

		<p>In <i>"Header <utility> synopsis" in [utility]</i>, add:
	
		<div style="font-family:monospace;background:#eee;border:1px solid black;padding:4px">
			template &lt;unsigned N, typename T, typename ...R&gt;<br>
			struct type_at {<br>
			&nbsp;&nbsp;&nbsp;&nbsp;using type = typename type_at&lt;N - 1, R...>::type;<br>
			};<br>
			<br>
			template &lt;typename T, typename ...R><br>
			struct type_at&lt;0, T, R...&gt; {<br>
			&nbsp;&nbsp;&nbsp;&nbsp;using type = T;<br>
			};<br>
			<br>
			template &lt;unsigned N, typename T, typename ...R><br>
			auto value_at(T&amp;&amp;, R&amp;&amp;... r) -&gt; decltype(auto)  {<br>
			&nbsp;&nbsp;&nbsp;&nbsp;return value_at&lt;N - 1, R...&gt;(std::forward&lt;R&gt;(r)...);<br>
			}<br>
			<br>
			template <typename T, typename ...R><br>
			auto value_at(T&amp;&amp; t, R&amp;&amp;...) -&gt; decltype(auto) {<br>
			&nbsp;&nbsp;&nbsp;&nbsp;return std::forward&lt;T&gt;(t);<br>
			}
		</div>
	</body>
</html>