﻿<!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>
<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>Packaging Parameter Packs</title>
</head>
<body>
N3416=12-0106<br />
    2012-09-21<br />
    Mike Spertus<br />
    <a href="mailto:mike_spertus@symantec.com"><tt>mike_spertus@symantec.com</tt></a><br/>

    <h1>
        Packaging 
        Parameter Packs</h1>
    <h2>
        Overview</h2>
    <p>
        The purpose of this paper is to propose mechanisms and rationale for named parameter packs and literal parameter packs. In particular, 
        this proposal makes parameter packs suitable for use as typelists [<a href="#ref_1">1</a>] 
        and allows them to be defined and referenced from outside of template classes.</p>
<h2>Proposed changes</h2>
This section informally describes our proposal. See the Wording section 
    <a href="#wording">below</a> for precise details.
    <ul>
        <li>A parameter pack literal is a  <em>template-parameter-list</em> (§14p1) 
            surrounded by angle brackets, like <code>&lt;int, std::basic_ostream&lt;char&gt;, 7&gt;</code>
        </li>
        <li>To name a parameter list, we just <tt>typedef</tt> it, like <code>typedef&lt;signed char, short int, int, long int, long long int&gt; signed_integral_types;
cout &lt;&lt; contains&lt;signed_integral_types, int&gt;::value;<span class="comment"> // Prints true</span></code>
        </li>
       <li>Template parameters can be (unexpanded) parameter packs
            lists<code><span class="comment">// Inherits from true_type if typelist TL includes the type T</span>
template&lt;&lt;typename...&gt; TL, typename T&gt; struct includes;
<span class="comment">// Inherits from true_type if typelist TL includes all the types in TL2</span>
template&lt;&lt;typename...&gt; TL, &lt;typename...&gt; TL2&gt; struct contains;

<span class="comment">// The following asserts will not fire</span>
static_assert(includes&lt;&lt;double, int&gt;, int&gt;::value, "unexpected compile error");
static_assert(contains&lt;&lt;double, float, int&gt;, &lt;float, int&gt;&gt;, "unexpected compile error");</code></li>
        <li>As usual, parameter packs can be expanded with <tt>...</tt>
        <code>tuple&lt;signed_integral_types...&gt; tsit;</code></li>
        <li>Named parameter packs can be accessed outside of classes. This example uses a <tt>direct_bases</tt> type trait similar to
        proposed in [<a href="#ref 2">2</a>], with a local parameter pack typedef <tt>types</tt> giving all of the direct base classes of
            a class
<code><span class="comment">// B has the same base classes as A</span>
struct B : public direct_bases&lt;A&gt;::types... {};</code></li>
        <li>Since template declarations can create parsing ambiguities (see Doug Gregor&#39;s 
            examples in&nbsp; [<a href="#ref_5">5</a>]), we adopt the now 
            familiar approach of explicitly identifying ambiguous members as parameter packs<code>template&lt;typename T&gt;
struct same_bases_as_T : public typename&lt;typename...&gt; direct_bases&lt;T&gt;::types... {};</code>
Note that part of how we reduce ambiguity is by supporting a more limited problem domain than
considered in [<a href="#ref_5">5</a>].</li>
    </ul>
    &nbsp;<h2>Rationale - Why we need language support</h2>
    <p>The first question to ask of course is whether typelists belong in library or 
        evolution. Many people have taken a library-based approach to typelists</p>
    <ul>
        <li>In [<a href="#ref_2">2</a>], it is suggested that <tt>tuple</tt> be used as a typelist 
        in lieu of language support. </li>
        <li>Nearly an entire book [<a href="#ref_1">1</a>] has been written about using 
            typelists provided by the Loki library [<a href="#ref_6">6</a>].</li>
        <li>It is also common to create a simple typelist class 
        like <code>template&lt;typename... T&gt; struct typelist {};</code></li>
        <li>Boost.MPL [<a href="#ref_4">4</a>] provides a panoply of type containers, generalizing typelists</li>
        </ul>
        This plethora of libraries leveraging typelists 
    testifies to their value. 
    However, the primitive templates the typelists are based on form a weak 
    foundation, limiting the applicability of those libraries. It is not our aim to replace
    these libraries, merely to give them a robust, scalable, and usable parameter pack
    primitive to build off. We illustrate this by comparing the &ldquo;<tt>tuple</tt> as typelist&rdquo; 
    suggestion from [<a href="#ref_2">2</a>] to packaged parameter packs:
    <dl>
    <dt>Performance</dt>
    <dd>Compilation speed is paramount in metaprogramming. In implementating the <tt>bases</tt> trait proposed in [<a href="#ref_3">3</a>] 
            as a g++4.7 extension, I compared the performance of returning a <tt>tuple</tt> 
            type giving all the base classes of a class with returning a simple typelist 
            class containing no members and no recursive expansion. The simple typelist class was 60 
            times faster to compile. A built-in parameter list would presumably be even faster than 
            that. Given that the recursive member generation in <tt>tuple</tt> provides no benefit for 
            typelists, <tt>tuple</tt>-based typelists should probably be avoided for performance reasons 
            alone.</dd>
<dt>Interoperability</dt>
<dd>If <tt>tuple</tt>s are used as typelists, it is difficult to convert between <tt>tuple</tt>s 
    and parameter packs, meaning sometimes you will have code that expects a <tt>tuple</tt> 
    and other times code expecting a parameter pack. For example, passing a <tt>tuple</tt>&#39;s arguments to another template&#39;s argument 
        list is awkward.
 <code><span class="comment">// Passing tuple's parameters to another template</span>
template&lt;template&lt;typename...&gt; class F, typename T&gt; struct unwrap_into;

template&lt;template&lt;typename...&gt; class F, typename... Ts&gt;
struct unwrap_into&lt;F, tuple&lt;Ts...&gt;&gt; {
  typedef F&lt;Ts...&gt; type;
};

typedef tuple&lt;double, string&gt; tds;
unwrap_into&lt;map, tds&gt;::type map_double_to_string;
</code>
By contrast, this is almost trivial when using parameter packs.
<code>typedef&lt;double, string&gt; tds;
map&lt;tds...&gt; map_double_to_string;</code>
<p>What makes it worse is that how to expand the tuple&#39;s parameters can vary case by case. For example, to inherit from all of the types in a <tt>tuple</tt>, you might do something like</p>
<code>template&lt;typename T&gt; struct inherit;
template&lt;typename... Ts&gt;
struct inherit&lt;tuple&lt;Ts...&gt;&gt; : public Ts... {};

typedef tuple&lt;interface1, interface2&gt; interfaces;
struct myType : public inherit&lt;interfaces&gt; {};</code>
With parameter pack-based typelists, it's no contest
<code>typedef&lt;interface1, interface2&gt; interfaces;
struct myType : public interfaces... {};
</code></dd>
<dt>Non-type parameters</dt>
<dd>A <tt>tuple</tt> cannot have non-type template parameters, so it cannot encapsulate 
    general lists of template parameters (OK. Maybe a <tt>constexpr tuple</tt> could be used. 
    But even that wouldn&#39;t work if some parameters are types and others are non-type 
    parameters). Consider this example, which returns the 
    methods of a particular class. Note that a putative reflection trait for enumerating 
    methods would also have the same issue.
<code>struct A {
  void f();
  int g();
};
<span class="comment">// Package the methods of A</span>
typedef&lt;&amp;A::f, &amp;A::g&gt; A_methods;
</code></dd>
    <dt>Template expansion limits</dt>
    <dd>Tuples are subject to severe template expansion limits. Under 
            Visual Studio, a template can have at most 64 template parameters. This is 
            insufficient for many important use cases for typelists. For example, 
            compile-time reflection proposals often propose returning a typelist of 
            metaobjects for all of the members of a class or all of the symbols in a 
            namespace. This could far overrun the limits for template parameters (Just consider 
            enumerating the symbols in namespace <tt>std</tt>).&nbsp; By contrast, parameter 
        packs are a kind of degenerate template type, which cannot have members, cannot 
        be specialized, etc. My expectation, which should be discussed in 
        Oregon) is that the (partly) new primitive parameter pack type proposed here that merely 
        encapsulates a <em>template-parameter-list</em> could relax these limits.</dd>

</dl>


<h2>Bonus feature: weakly specifying parameters</h2>
    <p>For routines that manipulate parameter packs structurally regardless of type, it 
        would be nice to declare parameter packs with arbitrary parameters using a naked <tt>...</tt>.
		we use &ldquo;<tt>.</tt>&rdquo; (by analogy with &ldquo;<tt>...</tt>&rdquo;) to represent 
    a single arbitrary template parameter.
        For example, suppose we want to calculate the length of an (unexpanded) parameter pack without 
        resorting to the built-in <tt>sizeof...</tt> operator:
<code>template&lt;typename T&gt; struct length;

template&lt;&gt;
struct length&lt;&lt;&gt;&gt; {
  static constexpr int value = 0;
};

template&lt;. t&gt;
struct length&lt;&lt;t, ... Rest&gt;&gt; {
  static constexpr int value = 1 + length&lt;Rest&gt;
};

template&lt;typename T&gt;
struct length&lt;&lt;T, ... Rest&gt;&gt; {
  static constexpr int value = 1 + length&lt;Rest&gt;
};

typedef&lt;int, 5, double, 6&gt; pp;
static_assert(length&lt;pp&gt;::value == sizeof...(pp), "unexpected compile error");
</code>
    </p>
    It is a little clumsy to have to provide distinct partial specializations 
    depending on whether the first parameter is a type or non-type parameter. To 
    improve on this,  The following example illustrates a 
    template for reversing an arbitrary (expanded) parameter pack:
<code>template&lt;... Ts&gt; struct reverse;

template&lt;&gt;
struct reverse&lt;&gt; {
  typedef&lt;&gt; type;
};

template&lt;. T, ... Rest&gt;
struct reverse&lt;T, Rest...&gt;
struct {
  typedef &lt;reverse&lt;Rest...&gt;::type..., T&gt; type;
};

static_assert(is_same&lt;reverse&lt;char, int, vector&lt;string&gt;&gt;::type, &lt;vector&lt;string&gt;, int, char&gt;&gt;, "Unexpected compile error");
</code>
This also gives us a nice way of getting the i<sup>th</sup> item from a parameter pack, which Doug Gregor describes 
in [] as &ldquo;probably the most-requested feature for variadic templates&rdquo; Perhaps something along the lines of
<code>
template&lt;int i, typename T&gt; struct at;

template&lt;int i, . T, ... Rest&gt;
struct at&lt;i, &lt;T, Rest...&gt;&gt; : public at&lt;i - 1, Rest&gt; {};

template&lt;. t, ... Rest&gt;<span class="comment"> // Notation from N3405</span>
struct at&lt;0, &lt;t, Rest...&gt;&gt; {
    static constexpr T value = t;
};

template&lt;typename T, ... Rest&gt;
struct at&lt;0, &lt;T, Rest...&gt;&gt; {
  typedef T type;
};

typedef &lt;int, 7&gt; int7;

at&lt;0, int7&gt;::type i7 = at&lt;1, int7&gt;::value;
</code>

    <h2>
        References</h2>
    <p>
        <a name="ref_1"></a>[1] Alexandrescu, <em>Modern C++ Design: Generic Programming and Design Patterns 
        Applied</em>. Addison Wesley, 2001.</p>
    <p>
        <a name="ref_2"></a>[2] Gregor, Järvi, Variadic Templates for C++0x; Journal of Object Technology 
        (2008) 31-51. <a href="http://www.jot.fm/issues/issue_2008_02/article2/">
        http://www.jot.fm/issues/issue_2008_02/article2/</a></p>
    <p>
        <a name="ref_3"></a>[3] Spertus, Type traits and base classes, N2965=09-0155.
        <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html">
        http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2965.html</a>.</p>
    <p>
        <a name="ref_4"></a>[4] The Boost MPL Library.
        <a href="http://www.boost.org/doc/libs/1_51_0/libs/mpl/doc/index.html">
        http://www.boost.org/doc/libs/1_51_0/libs/mpl/doc/index.html</a>.</p>
    <p>
        <a name="ref_5"></a>[5] Variadic Templates in C++0x need some additional features to come closer to 
        fulfilling their promise.
        <a href="https://groups.google.com/forum/?fromgroups=#!topic/comp.std.c++/_-6X_xZlKlA">
        https://groups.google.com/forum/?fromgroups=#!topic/comp.std.c++/_-6X_xZlKlA</a>.</p>
    <p>
        <a name="ref_6"></a>[6] Loki Library.
        <a href="http://loki-lib.sourceforge.net/">
        http://loki-lib.sourceforge.net/</a>.</p>
    <p>
        <a name="ref_7"></a>[7] “unpacking” a tuple to call a matching function pointer.
        <a href="http://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer">
        http://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer/</a>.</p>
    <p>
        <a name="ref_8"></a>[8] Gregor, Powell, Järvi, Typesafe Variable-Length Function and 
		Template Argument Lists</p>

</body>
</html>
