<html>
<head><title>N4115, Parameter Pack Searching</title></head>
<body>
<table border=0>
<tr><td><b>Doc No:</b></td><td>N4115</td></tr>
<tr><td><b>Date:</b></td><td>2014-07-04</td></tr>
<tr><td><b>Reply to:</b></td><td><tt>stdbill.h@pobox.com</tt></td></tr>
</table>
<center>
<h2>Searching for Types in Parameter Packs</h2>
<h3>Bill Seymour<br>Stephan T. Lavavej<br>2014-07-04</h3>
</center>
<hr size=5>
<h3>Abstract:</h3>

This paper proposes that a mechanism for finding types in parameter packs
be added to the standard library.

<p><hr size=5>
<h3>The basic idea:</h3>
This paper proposes three new class templates for <tt>&lt;type_traits&gt;</tt>.
One is just a holder of a parameter pack; the other two report
at compile time whether a parameter pack contains one or more types.

<p>Possible implementations of the last two are shown as proof of concept.
They both compile to either <tt>std::true_type</tt> or <tt>std::false_type</tt>.

<p>And in the spirit of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3854.htm">N3854</a>,
this paper also adds the &ldquo;<tt>_v</tt>&rdquo; values.

<p><a name="packer"><hr></a>
<h4>A class template that just holds a parameter pack:</h4>
<pre>
    template &lt;class... T&gt; struct packer { };
</pre>
This is inspired by <tt>std::tuple</tt>, but it lacks members,
so it could serve as an empty base class,
and an object of the ultimate type could always be instantiated
(even if the parameter pack contains <tt>void</tt>
or some type that lacks a default constructor).

<p><hr>
<h4>Whether type T is in parameter pack P:</h4>
<pre>
    template &lt;class T, class... P&gt; struct is_contained_in;

    template &lt;class T, class... P&gt;
      constexpr bool is_contained_in_v = is_contained_in&lt;T,P&gt;::value;
</pre>
<h4>One possible implementation:</h4>
<pre>
    template &lt;class T&gt; struct is_contained_in&lt;T&gt; : false_type { };

    template &lt;class First, class... Rest&gt;
      struct is_contained_in&lt;First, First, Rest...&gt; : true_type { };

    template &lt;class T, class First, class... Rest&gt;
      struct is_contained_in&lt;T, First, Rest...&gt;
        : is_contained_in&lt;T, Rest...&gt; { };
</pre>
<hr>
<h4>
  Whether a <a href="#packer"><tt>packer</tt></a>, T, has a parameter pack that&rsquo;s
  a superset of the pack of some minimum <tt>packer</tt>, U:
</h4>
<pre>
    template &lt;class T, class U&gt; struct contains_types;

    template &lt;class T, class U&gt;
      constexpr bool contains_types_v = contains_types&lt;T,U&gt;::value;
</pre>
<h4>One possible implementation:</h4>
<pre>
    template &lt;class... TPack&gt;
      struct contains_types&lt;packer&lt;TPack...&gt;, packer&lt;&gt;&gt; : true_type { };

    template &lt;class... TPack, class UFirst, class... URest&gt;
      struct contains_types&lt;packer&lt;TPack...&gt;, packer&lt;UFirst, URest...&gt;&gt;
        : integral_constant&lt;bool,
            is_contained_in&lt;UFirst, TPack...&gt;::value &amp;&amp;
            contains_types&lt;packer&lt;TPack...&gt;, packer&lt;URest...&gt;&gt;::value&gt; { };
</pre>

<p><hr size=5>
<h3>
  Standardese relative to
  <a href="http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n3936.pdf">N3936</a>:
</h3>

In <b>20.10.2 Header <tt>&lt;type_traits&gt;</tt> synopsis</b> [meta.type.synop]:

<ul>
<li>Change &ldquo;// 20.10.3, <i>helper class:</i>&rdquo;
<ul>
<p><li>Make the heading plural:
<blockquote>
// 20.10.3, <i>helper class<ins>es</ins>:</i>
</blockquote>
<p><li>Add at the end:
<pre>
    template&lt;class... T&gt; struct packer;
</pre>
</ul>
<p><li>Add to &ldquo;// 20.10.6, <i>type relations:</i>&rdquo;
<pre>
    template &lt;class T, class... P&gt; struct is_contained_in;
    template &lt;class T, class U&gt; struct contains_types;

    template &lt;class T, class... P&gt;
      constexpr bool is_contained_in_v = is_contained_in&lt;T,P&gt;::value;
    template &lt;class T, class U&gt;
      constexpr bool contains_types_v = contains_types&lt;T,U&gt;::value;
</pre>
</ul>

<hr>
<p>In <b>20.10.3 Helper classes</b> [meta.help]:
<ul>
<li>Add just before the closing brace of <tt>namespace</tt>&nbsp;<tt>std</tt>:
<pre>
    template&lt;class... T&gt; struct packer { };
</pre>
<p><li>Add a new paragraph after paragraph 1:
<blockquote>
The class template <tt>packer</tt> simply holds a parameter pack.
</blockquote>
</ul>

<hr>
<p>In <b>20.10.6 Relationships between types</b> [meta.rel], add to the end of Table 51:
<blockquote>
<table border>
<tr>
  <td>
    <tt>template &lt;class T, class... P&gt;<br>struct is_contained_in;</tt>
  </td>
  <td>
    Type <tt>T</tt> is contained<br>in
    parameter pack <tt>P</tt>
  </td>
  <td>&nbsp;</td>
</tr>
<tr>
  <td>
    <tt>template &lt;class T, class U&gt;<br>struct contains_types;</tt>
  </td>
  <td>
    <tt>T</tt>&rsquo;s parameter pack contains<br>at
    least one instance<br>of each of the types<br>in
    <tt>U</tt>&rsquo;s parameter pack
  </td>
  <td>
    <tt>T</tt> and <tt>U</tt> are <tt>packer</tt>s (20.10.3).
  </td>
</tr>
</table>
</blockquote>

<p><hr size=5>
<b>Reply to:</b>&nbsp;&nbsp;<tt>stdbill.h@pobox.com</tt>
</body>
</html>
