<!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=windows-1252">
  <style type="text/css">
h3 {  margin-bottom: 0;}
.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>Leveraging parameter packs outside of templates</title>
</head>

<body>
<p>Document number: P0341R0<br>
Date: 2016-05-30<br>
Reply-To:&nbsp;&nbsp;Mike Spertus, Symantec (<a href="mailto:mike_spertus@symantec.com">mike_spertus@symantec.com</a>)<br>
Audience: SG7 Reflection possibly also Evolution Working Group
</p>
<h1><title>Leveraging parameter packs outside of templates</title>
 parameter packs outside of templates</h1> 
	<h2>Abstract</h2>
<p>Parameter packs have proven exceedingly useful within templates but are unavailable
in other contexts where they could prove equally useful. This paper addresses this by
 extending and generalizing the concept of parameter pack, and more generally of template argument lists,
	to a much wider range of contexts. Numerous use cases are given.</p>
<h2>Proposal</h2>
	<p>We will build up our definitions incrementally from consideration of natural use cases.</p>
<h3>Parameter pack declarations</h3>
		We start by observing that even within a template class, the use of parameter packs
		is uncomfortably restricted:
<code>template&lt;typename ...T&gt;
struct easy_tuple {
	template&lt;typename U&gt; easy_tuple(U &amp;&amp;u) : t{u}... {}
	T ...t;  <span class="comment">// Ill-formed. Parameter pack members not allowed</span>
};</code></p>
<p>The above code appears perfectly natural and leads to a far cleaner and 
	easier to understand implementation	of tuple than the usual one. Motivated by this,
	we propose removing the restriction that only parameter declarations can be packs.</p>
	
	<p>Here is another useful example of non-parameter declarations of packs.</p>
<code>template&lt;typename ...T&gt; T cleanData(T t); <span class="comment">// Performs data cleaning: normalizing, removing outliers, etc.</span>
template&lt;typename ...T&gt; void processData(T ...rawData) {
	T ...cleanedData{cleanData(raw_data)...};
	<span class="comment">/* Work with cleanedData */</span>
};</code>
<h3>Accessing a template parameter pack outside the template</h3>
	Accessing the member
	packs from outside the template is useful as well, for example to implement <tt>easy_tuple</tt>s <tt>get</tt> accessor.
	</p>
<code>template &lt;int i, typename ...T&gt; auto ith_argument(T &amp;&amp; ...t) { <span class="comment">/* Usual code to return ith argument</span> }
	
template&lt;typename int i; typename ...T&gt; auto get(easy_tuple&lt;T...&gt; tup) {
	return ith_argument&lt;i&gt;(tup....t&amp; ...);  <span class="comment">// Access parameter pack from outside its defining template</span>
}</code>
<b>Note:</b> By analogy with how we write <tt>a.template b&lt;int&gt;</tt>
	to indicate that a member is a template, the above code adopt as a bikeshed Richard Smith's suggestion to use <tt>...</tt> to indicate
	a member of a dependent type is a pack.
<h3>Pack literals</h3>
So far, our only way to create a parameter pack is via a template. This means that
	to create a &ldquo;typelist&rdquo; consisting of <tt>int</tt> and <tt>double</tt> would
	require detouring through the cumbersome <tt>easy_tuple&lt;int, double&gt;::t</tt>. To
	simplify the creation of packs, we propose angle bracket-enclosed template argument lists, such as <tt>&lt;int, double&gt;</tt> as pack literals.
	As an example, we can reduce the amount of &ldquo;special cases&rdquo; in the C++ standard by eliminating
    the following carve out from &sect14.1p9[temp.param] which says that &ldquo;
	A default <em>template-argument</em> may be specified for any kind of <em>template-parameter</em>
	(type, non-type, template) <span class="del">that is not a template parameter pack</span>.&rdquo;
<code>template&lt;typename...T = &lt;double, double&gt; &gt; <span class="comment">// default to 2-dimensional double-valued Euclidean space</span>
struct euclidean_space { <span class="comment">/* ... */</span> };</code>


<h3>Pack values</h3>
To the uninitiated, it may seem surprising that the following is ill-formed.
<code>auto f() { return {2, "foo"}; <span class="comment">// Ill-formed. braced-init-list is not an expression</span>}</code>
<p>The code <em>looks like</em> it is returning an expression, and it <em>seems like</em>
	the expression should have a type. However, there is special language in the standard
	for returning a <em>braced-init-list</em> because, although it may often be used like an expression, 
	it is not one. With packs representing their type, <em>braced-init-list</em>s can be first-class expressions,
	again reducing the number of special cases:</p>
<code>auto f() { return {2, "foo"}; } <span class="comment">// Now OK. Return type is &lt;int, char const *&gt;</span></code>
<p>As in the last section, we can also remove the restriction on packs having default arguments for
for function parameters from &sect;8.3.6p3 [dcl.fct.default].</p>
<code>template&lt;typename ...T&gt; 
void recognize(T ...ourHeroes = {"Alan Turing", "Dennis Ritchie", "Bjarne Stroustrup"});</code>
<p>Of course, a parameter packs values can also be returned directly.</p>
<code>template&lt;typename ...T&gt;
auto truncate(T ...t) { return min(100, t)...; }</code>
<p>Returning a pack rather than a <tt>std::pair</tt> or a <tt>std::tuple</tt> eases
composition and functional programming by increasing loose coupling.
<code>&lt;double, double&gt; calculateTargetCoordinates();
double distanceFromMe(double x, double y);
	
void launch() {
	if(distanceFromMe(calculateTargetCoordinates()...))
		getOuttaHere();
}</code>
	
<p><b>Note:</b> As mentioned above. Our packs generalize template parameter lists.
All packs are types and have instantiable values (provided the types in the pack do).
This is straightforward for type parameter packs. E.g., <tt>{2, 'c'}</tt> is a valid value of
the pack type <tt>&lt;int, char&gt;</tt>. A more interesting example would be the
type &lt;string, 7, int&gt; which is a valid template parameter list and therefore represents a pack type.
A valid value for this type is <tt>{"C++"S, 7, 5}</tt>. By encoding known values in the pack type,
(possibly significant) storage can be saved in templatized programs.</p>
<h3>Named packs</h3>
<p>Pack literals can also name their members, providing a very natural solution to
the pack analogue of &ldquo;named tuples&rdquo; problem, making it easy
	to create functions that return multiple values descriptively.</p>
<code>&lt;string topSong, person president, double avgTemp&gt; someFactsAboutYear(int year) {
  if(year==1962)
    return {"Stranger On The Shore", Presidents.get("Kennedy"), 14};
}</code>
<p>Named packs are implicitly convertible to and from unnamed packs but not
each other for added static type safety beyond what is provided in <tt>pair</tt>
and <tt>tuple</tt>.</p>
<h3>Typelists</h3>
<p>Another use case we would like to cover with parameter packs is as typelists.
For this and other reasons, we propose that packs are types and can be used as 
types without being expanded. We illustrate the notation for partially specializing
a template on typelists
with an <tt>append</tt> metafunction for concatenating two typelists.
<code>template&lt;typename L, typename R&gt; struct append;
	
template&lt;typename ...Ls, typename ...Rs&gt;
struct append&lt; &lt;Ls...&gt;, &lt;Rs...&gt; &gt; {
	using type = &lt;Ls..., Rs...&gt;;
};</code>

<p>Note that we are not limited to types and can also do intlists, etc.</p>
<code>template&lt;typename theoretical, typename actual> struct accuracy;

template&lt;double... predictions, double... measurements&gt; 
struct accuracy&lt; &lt;predictions...&gt;, &lt;measurements...&gt; &gt;) { <span class="comment">/* ... */</span> };</code>

<p>Using packs as a base typelist type also makes it easier to coexist with the myriad
	of existing and experimental typelist classes, such as those in <a href="http://www.boost.org/doc/libs/1_61_0/libs/mpl/doc/index.html">Boost MPL</a>,
	<a href="http://loki-lib.sourceforge.net/">Loki</a>, with <a href="http://www.boost.org/doc/libs/1_61_0/libs/hana/doc/html/index.html">more</a>
	<a href="http://ericniebler.com/2014/11/13/tiny-metaprogramming-library/">under</a> <a href="http://pdimov.com/cpp2/simple_cxx11_metaprogramming_2.html">development</a>. For
example, given a pack <tt>T = &lt;int, double, long&gt;</tt>, we can convert it
to a <tt>boost::mpl::vector</tt> as simply as <tt>mpl::vector&lt;T...&gt;</tt></p>
<p>Note that we do not make any claim that packs are the only way to do typelists, but
merely that they co-exist well with and between other approaches. See the discussion below
about user-defined classes.

<h3>Reflection</h3>	
We think packs are a reasonable choice for reflection typelists. For example, it 
naturally implements all of the motivating examples from <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html">N2965</a>, which benefit from
C++ pack expansion of base classes. Packs also lend themselves to reflection facilities
like allowing a function to get a pack of all of its parameters or a pack of all of
the fields of a class. At the same time, other, perhaps richer, models of typelists could
well be considered by SG7 as an alternative to the low-level packs used here (Of course, that
would not be an argument against any of the pack enhancements in this paper).
<h3>Iterator interface</h3>
Like <tt>boost::MPL</tt>, parameter packs have iterator interfaces. They have <tt>pack_begin</tt> and <tt>pack_end</tt>
type traits. E.g., <tt>pack_begin_t&lt; &lt;int, double&gt; &gt;</tt> gives an &ldquo;iterator&rdquo; that
has <tt>current</tt> and <tt>next</tt> members. It also has a <tt>get</tt> member that accepts
a value for that type and returns the corresponding element. In the above case, 
<tt>get&lt;pack_begin_t&lt; &lt;int, double&gt; &gt; &gt;({3, 4.5})</tt> returns <tt>3</tt>.
Indexed versions should also be available. Together, this allows iteration and Boost::Fusion-style processing of packs.
<h3>User-defined types</h3>
C++ strives for user-defined constructs are generally designed to be as close to
built-in constructs as possible. While providing a pack interface to user-defined
types is separable from the pack deserves a separate proposal, we provide a brief
sketch here with significant inspiration from Richard Smith's ideas on <tt>operator...()</tt>.
<p>We consider <tt>tuple</tt> as a prototype. For example, we would want <tt>tuple&lt;int, double&gt;...</tt>
	to be the pack <tt>&lt;int, double&gt;</tt> and <tt>tuple&lt;int, double&gt;{2, 3.5}...</tt>
to be the <tt>{2, 3.5}</tt> value of the pack type <tt>&lt;int &amp;, double &amp;&gt;</tt>. Here is
how these could be implemented in the <tt>easy_tuple</tt> example above.</p>
<code>template&lt;typename ...T&gt;
struct easy_tuple {
	<span class="comment">/* ... */</span>
	&lt;T&amp;...&gt; operator...() { return t...; }
};
	
template&lt;typename ...T&gt;
using easy_tuple&lt;T...&gt;... = &lt;T...&gt;;
</code>
Notes:
<ul><li>This makes the much-desired feature of simply expanding a tuple into
	the arguments of a function trivial: <tt>f(...t...);</tt>. It is instructive to
	look at DRayX's long and complexly metaprogrammed C++14 <a href="http://stackoverflow.com/questions/687490/how-do-i-expand-a-tuple-into-variadic-template-functions-arguments">workaround</a> for this feature by comparison.</li>
	<li>As Richard Smith has pointed out, we want the <tt>...t...</tt> above to "pack-ize" the <tt>t</tt> because
	otherwise any pack expression containing a tuple would suddenly unpack the tuple, breaking compatibility, and 
	likely not what would be desired regardless.</li>
<li>By default, it <tt>T</tt> is a user-defined type that defines an <tt>operator...</tt>, then <tt>...T...</tt> will
	be <tt>&lt;...declval&lt;T&gt;()...&gt;</tt>. However, it is possible, and maybe desirable as illustrated by
	the <tt>easy_tuple</tt> code, to override that.</li>
<li>If a class defines an <tt>pack_begin</tt> iterator interface, then pack expansion is automatically generated
	without need to write an <tt>operator...()</tt>.</li>
<li>For some types, like intlists, <tt>...</tt> should be able to produce a value rather than just a type, just
	like with non-type template pack parameters. In this case, a static <tt>operator...</tt> method may be supplied.</li></ul>

</body>
</html>