<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US"><head>
<meta http-equiv="Content-Language" content="en-US" />
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII" />
<title>Matching Types: 404 Syntax Not found</title>

<style type="text/css">/*<![CDATA[*/
body { color: #000000; background-color: #FFFFFF; max-width: 40em; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.std del { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC; }
blockquote.std ins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em padding-right: 0.5em; }
blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3;
  padding-left: 0.5em; padding-right: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

table.table { border-spacing: 2px; border-collapse: separate; }
.table * th, .table * td { border: 1px solid black; }

table.frontmatter { border: 0;  margin: 0; }

ul.dash { list-style-type: none; }
ul.dash li:before { content: '\2014'; margin-left: -1em }

span.highlight { background-color: #7FDFFF }

.nowrap { white-space: nowrap; }
/*]]>*/
</style>

<script type="text/javascript" src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
</head>

<body>
<h1>Matching Types: 404 Syntax Not found</h1>
<table class="frontmatter" border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" width="619">
    <tr>
        <td align="left" valign="top">Document number:</td>
        <td>P0404R0</td>
    </tr>
    <tr>
        <td align="left" valign="top">Date:</td>
        <td>2016-07-11</td>
    </tr>
    <tr>
        <td align="left" valign="top">Project:</td>
        <td>ISO/IEC JTC 1/SC 22/WG 21/C++</td>
    </tr>
    <tr>
        <td align="left" valign="top">Working Group:</td>
        <td>Evolution</td>
    </tr>
    <tr>
        <td align="left" valign="top">Revises:</td>
        <td><!-- a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/pXXXXrY.html"></a -->None</td>
    </tr>
    <tr>
        <td align="left" valign="top">Reply-to:</td>
        <td><span class="nowrap">Hubert Tong</span>, IBM &lt;<a href="mailto:hubert.reinterpretcast@gmail.com">hubert.reinterpretcast@gmail.com</a>&gt;<br />
        <span class="nowrap">James Touton</span> &lt;<a href="mailto:bekenn@gmail.com">bekenn@gmail.com</a>&gt;</td>
    </tr>
</table>

<h2><a id="TableOfContents">Table of Contents</a></h2>
<ol>
    <li><a href="#TableOfContents">Table of Contents</a></li>
    <!-- li><a href="#WhatsNew">What's New</a></li -->
    <li><a href="#Introduction">Introduction</a></li>
    <li><a href="#MotivationAndScope">Motivation and Scope</a></li>
    <li><a href="#ImpactOnTheStandard">Impact On the Standard</a></li>
    <li><a href="#DesignDecisions">Design Decisions</a></li>
    <li><a href="#TechnicalSpecifications">Technical Specifications</a></li>
    <li><a href="#Wording">Wording</a></li>
    <li><a href="#References">References</a></li>
    <li><a href="#Acknowledgments">Acknowledgments</a></li>
    <li><a href="#Appendix">Appendix</a></li>
</ol>

<!-- h2><a id="WhatsNew">What's New</a></h2 -->

<h2><a id="Introduction">Introduction</a></h2>
<p>With the recent addition of <span class="nowrap"><code>constexpr</code> if</span> statements to C++,
we now have a mechanism to express separately-instantiated alternatives based on type properties without adding additional <span class="nowrap">&#x201c;top-level&#x201d;</span> templates.
However, the checking for said type properties are limited by the use of boolean expressions in series.
In this paper, we propose a new construct to perform compile-time selection of alternatives by pattern-matching on <span class="nowrap">(static)</span> types in type, expression, and statement contexts.</p>
<p>The construct is designed to evoke class template partial specialization, and adapts the <i>template-introduction</i> syntax from the Concepts TS.</p>
<p>The authors are aware of <span class="nowrap">David Sankel&#x2019;s</span> paper <span class="nowrap">[<a href="#P0095R1">P0095R1</a>]</span>,
and have worked with David on a syntax for his <code>inspect</code> construct which, outside of the pattern portion, is similar to what is presented here.</p>

<p>In this paper, <code>generic</code> (styled after <code>_Generic</code> from C11) is used as a convenience to identify the new construct in code.</p>

<h3>Examples</h3>
<pre class="prettyprint lang-cpp"
>// Select on types for types
template &lt;typename T&gt;
struct remove_const {
  using type = typename generic&lt;T&gt;(
    typename{U} const U: U, // introduces U for the purpose of matching against
                            // pattern "const U"
    default: T
  );
};</pre>

<pre class="prettyprint lang-cpp"
>// Select for <i>statement</i>s
template &lt;typename It&gt;
std::iterator_traits&lt;It&gt;::difference_type distance(It first, It last) {
  generic&lt;It&gt; {
    RandomAccessIterator{U}: return last - first; // introduces U; implied
                                                  // pattern is "U"
    typename{U}: { // same as "default"
      std::iterator_traits&lt;It&gt;::difference_type dist = 0;
      for (It it = first; it != last; ++it, ++dist) { }
      return dist;
    }
  }
}</pre>

<pre class="prettyprint lang-cpp"
>// Select for expressions; result types do not need to be the same
template &lt;typename T&gt;
auto make_pair_or_tuple(T &amp;&amp;...t) {
  return generic&lt;std::integral_constant&lt;size_t, sizeof ...(T)&gt; &gt;(
    std::integral_constant&lt;size_t, 2&gt;:
      std::make_pair(std::forward&lt;T&gt;(t) ...),
    default:
      std::make_tuple(std::forward&lt;T&gt;(t) ...)
  );
}</pre>

<p>An additional syntax closer to David&#x2019;s <code>inspect</code> is also a possibility for future exploration.
Notice that the bound names are declared on first use.</p>
<pre class="prettyprint lang-cpp"
>template &lt;typename T&gt;
constexpr auto array_size_v = inspect&lt;T&gt;(
  [std::array&lt;&lt;!T!&gt;, &lt;!(size_t)N!&gt;&gt;]: N, // typename (see next line) is implied
  [&lt;!typename T!&gt; [&lt;!(auto)N!&gt;]: N
);</pre>
<p>For the purposes of generating discussion, <code>inspect</code> is used as the keyword in the example above.
The authors are open to guidance from the committee and opinions from the community.</p>

<h2><a id="MotivationAndScope">Motivation and Scope</a></h2>
<p>Like <span class="nowrap"><code>constexpr</code> if</span>, the proposed constructs allow for better locality of code.
Much of the motivation for this feature is common with that of <span class="nowrap"><code>constexpr</code> if</span>,
which <span class="nowrap">Ville Voutilainen&#x2019;s</span> paper <span class="nowrap">[<a href="#P0128R1">P0128R1</a>]</span> explains,
and will not be repeated here.</p>

<p>The following demonstrates the reduction of duplicated code and the resulting better reflection of the cohesion inherent to the expressed logic:</p>
<table class="table" style="width: 100%"><tbody><tr><th>Before</th><th>After</th></tr>
<tr><td><pre><code class="prettyprint lang-cpp"
>template &lt;typename T&gt;
struct declared_return_type { };

template &lt;typename R, typename ...Args&gt;
struct declared_return_type&lt;
    R (Args ...)&gt; {
  using type = R;
};

template &lt;typename R, typename ...Args&gt;
struct declared_return_type&lt;
    R (Args ..., ...)&gt; {
  using type = R;
};</code></pre>
</td><td><pre><code class="prettyprint lang-cpp"
>template &lt;typename T&gt;
using declared_return_type =
  typename generic&lt;T&gt;(
    &lt;typename R, typename ...Args&gt;
        R (Args ...):
      std::enable_if&lt;true, R&gt;,
    &lt;typename R, typename ...Args&gt;
        R (Args ..., ...):
      std::enable_if&lt;true, R&gt;,
    default:
      std::enable_if&lt;false, void&gt;
  );</code></pre>
</td></tr>
</tbody></table>

<p>This paper seeks to compliment <span class="nowrap"><code>constexpr</code> if</span> with constructs which implement a <span class="nowrap">&#x201c;best match&#x201d;</span> (as opposed to first match) policy.
The existing rules for matching specializations of class templates are leveraged, allowing for rather direct mapping from existing code.</p>

<h2><a id="ImpactOnTheStandard">Impact On the Standard</a></h2>
<p>For syntactic convenience, the use of a keyword would be useful for this feature.
To prevent adding a new keyword, <code>switch</code> may be considered, with or without an additional contextual keyword.
The authors are aware that some members of the C++ committee have serious reservations on the use of <code>switch</code>.</p>

<p>This feature adds a new form of <i>primary-expression</i>, a new form of <i>type-specifier</i>, and a new form of <i>selection-statement</i> to the language.
For the cases except the last, further consideration is necessary to examine the impact of allowing the constructs in contexts which may trigger SFINAE.</p>

<p>These constructs are highly teachable when given a base of knowledge extending to <span class="nowrap"><code>constexpr</code> if</span> and class template partial specialization.
For those who find class template partial specialization to be arcane, the terser, pattern-like syntax may be more approachable.</p>

<p>The authors believe that this feature has a good amount of synergy with Concepts, and have received confirmation from <span class="nowrap">Andrew Sutton</span> that this proposal does not conflict with the evolution of
<span class="nowrap">Concepts Lite</span>.</p>

<h2><a id="DesignDecisions">Design Decisions</a></h2>
<p><em>This section contains items identified as warranting special note and further discussion.
As such, the possibilities presented in this section are not incorporated into later sections of this paper.</em></p>

<h3>Semantics of no match</h3>
<p>When there is no match, we propose for the construct to be ill-formed for the type and expression cases.
For the statement case, we propose that the construct be treated as having a match on an implied default that selects a null statement.</p>

<p>An alternative for the expression case is to treat the construct as having a match on an implied default that selects <code class="nowrap">void()</code>.</p>

<h3>Type, value category, etc. properties of the expression form</h3>
<p>We propose that the type and value category of the expression form be that of the chosen alternative.
The result of the construct is a bit-field if and only if the chosen alternative is a bit-field, and similarly for its being a core constant expression.</p>

<p>Similarly, if the chosen alternative is a <i>braced-init-list</i>, then the construct should be treated as that <i>braced-init-list</i>.</p>

<h3>Introduction syntax for unconstrained non-type template parameters</h3>
<p>A form of template introduction, restricted to contexts where it would not be confused with a cast, with a
<i>simple-type-specifier</i> or <i>typename-specifier</i> in place of the <i>qualified-concept-name</i>
is a natural extension of the introduction syntax.</p>
<p>The authors are aware that additional overloading of similar syntax, which may jeopardize the ability of the language to move in this direction,
is being proposed for structured bindings due to dissatisfaction with the use of square brackets.</p>

<h3>Multiple patterns selecting the same alternative</h3>
<p>It may be desired to be able to have multiple patterns (that are parameterized on the same template parameters) select the same alternative;
that is, a syntax for a limited form of fallthrough purely as a shorthand may be useful.</p>

<p>We do not propose adding such a &#x201c;list&#x201d; to the set of pack expansion contexts.</p>

<h4>Example</h4>
<pre class="prettyprint lang-cpp"
>// Using comma to separate patterns
template &lt;typename T&gt;
struct remove_cv {
  using type = typename generic&lt;T&gt;(
    typename{U} const volatile U, const U, volatile U: U,
    default: T
  );
};</pre>

<h3>Selection of templates</h3>
<p>The selection of templates, e.g., as a template template argument, is not proposed by this paper.</p>

<h3>Selection on non-type values</h3>
<p>Selecting based on non-type values can be effected with the use of <code>std::integral_constant</code> (<code>integral_constant</code> being a misnomer).
Special support need not be added.</p>

<h3>Selection on multiple arguments</h3>
<p>Selecting on multiple arguments can be effected with the use of <code>std::tuple</code>.
For simplicity, special support is not presented at this time.</p>

<h3>Appearance in signatures</h3>
<p>It is an open question whether these constructs should be allowed in signatures or contexts which may directly trigger SFINAE.
If they are allowed, a further question&#x2014;for the case where the selection process is dependent on the arguments of the nearest enclosing template<!--
-->&#x2014;is whether the selected alternative should be considered to be within the immediate context
(much like the substituted <i>type-id</i> from a specialization of an alias template).</p>

<p>It is observed that the state of the language is such that &#x201c;non-dependent&#x201d; cases of these constructs can be used to redeclare otherwise plainly-declared entities.</p>
<pre class="example prettyprint lang-cpp">void f(wchar_t); // #1
void f(char16_t); // #2
template &lt;typename T&gt;
struct A {
  friend void f(typename generic&lt;T&gt;(char16_t: char16_t,
                                    default: wchar_t)); // redeclaration
                                                        // of #1 or #2
};</pre>

<p>Of note is that the appearance of the proposed constructs in <i>alias-declaration</i>s and typedef declarations is an important use case.
If the intent is to prevent these constructs from appearing in a signature,
then it would be necessary to make dependent cases of said <i>alias-declarations</i> and typedef declarations opaque for the purposes of determining signatures.</p>

<h3>Placeholder types</h3>
<p>Allowing the selection of placeholder types is an idea which could be entertained.</p>
<pre class="example prettyprint lang-cpp">template &lt;typename T&gt;
struct A {
  A(const T &amp;);
};

template &lt;typename T&gt;
struct B {
  B(const T &amp;);
};

template &lt;typename Tag, typename T, typename U&gt;
auto f(const T &amp;t, const U &amp;u) {
  return typename generic&lt;Tag&gt;(struct AA: A, struct BB: B, default: auto)(
      std::make_pair(t, u)
      );
}</pre>

<h2><a id="TechnicalSpecifications">Technical Specifications</a></h2>
<h3>Type patterns</h3>
<p>A <i>type-pattern</i> is either <code>default</code>, an optionally-parameterized <i>type-id</i>, or a <i>template-introduction</i> introducing a single template type parameter.
The parameters for a <i>type-pattern</i> are to be provided before the <i>type-id</i> via either a <i>template-introduction</i> or a <i>template-parameter-list</i> delimited by angle brackets.
The latter case can be constrained by an optional <i>requires-clause</i>.</p>

<p>A <i>template-introduction</i> with <code>typename</code> in place of a <i>qualified-concept-name</i> introduces an unconstrained template type parameter or parameter pack for each
<i>identifier</i> of its <i>introduction-list</i>.</p>

<p>When a <i>type-pattern</i> contains no <i>type-id</i>, then the <i>type-id</i> is implied to be the single template type parameter introduced by the pattern.
A <i>type-pattern</i> of the form <code>default</code> corresponds to <code class="nowrap">typename{<i>unique</i>}</code>, where <i>unique</i> is a name which is otherwise unbound.</p>

<pre class="example prettyprint lang-cpp">// the following <i>type-pattern</i>s are equivalent
default
typename{T}
typename{T} T
&lt;class T&gt; T</pre>

<h3>Generic selection constructs</h3>
<p>A <i>generic selection construct</i> accepts a <i>type-id</i> as an argument, and selects the alternative associated with the <i>type-pattern</i> that is the best match for the argument.
The semantics for determining the best match is equivalent, except for the treatment of the primary template, to that of selecting the definition to be used for a template specialization.</p>

<p>The primary template has the form</p>
<pre class="example prettyprint lang-cpp">template &lt;typename T&gt; struct <i>unique</i> { };</pre>
<p>and each alternative is a definition of either an explicit or partial specialization of said primary template where the <i>template-argument-list</i>
of the <i>simple-template-id</i> consists of the (possibly implicit) <i>type-id</i> from the associated <i>type-pattern</i>.
Selecting the primary template is considered to be a &#x201c;no match&#x201d; situation,
and a partial specialization whose argument list is identical to the implicit argument list of the primary template is considered to be more specialized in this context.</p>
<p>If there is no best match, the generic selection construct is ill-formed.</p>
<p>If the set of definitions would be ill-formed, e.g., because of multiple definitions of the same entity, then the generic selection construct is ill-formed.</p>
<p>A generic selection expression is type-dependent if its argument or any of its <i>type-pattern</i>s is type-dependent; otherwise,
it is type-dependent or value dependent if and only if its selected alternative is so.
Similarly, <i>mutatis mutandis</i>, for a generic selection type being a dependent type.</p>

<h3>Validity of alternatives</h3>
<p>Unlike <code>constexpr</code> if, alternatives in a generic selection construct can remain dependent (on the arguments to be deduced for the parameters in its pattern) and not instantiated.</p>
<p>If an alternative is unselected and at all dependent (even if only on arguments to an enclosing template), the implementation shall not instantiate it; otherwise, the alternative shall be well-formed.
If there is no valid instantiation of an unselected alternative, the program is ill-formed; no diagnostic required.</p>

<h3>Syntax</h3>
<p>In every form of generic selection statement, the alternative is separated from the <i>type-pattern</i> by a colon.
In the type form, the alternative is a <i>type-id</i>.
In the expression form, the alternative is an <i>initializer-clause</i>.
In the statement form, the alternative is a <i>statement</i>;
if it is not a <i>compound-statement</i>,
it is as if it was rewritten to be a compound-statement containing the original alternative.</p>

<p>In the type and expression forms, comma is used to separate alternatives from the following <i>type-pattern</i>.
In the statement form, no such separator is necessary; the alternative is either delimited by braces or ends in a semicolon.</p>

<p>The type form begins with the keyword <code>typename</code>.
In the type and expression forms, parentheses are used to delimit the set of alternatives; braces are used for the statement form.</p>

<!-- h2><a id="Wording">Wording</a></h2 -->

<h2><a id="References">References</a></h2>
<p>[<a id="P0095R1">P0095R1</a>] Sankel, D. &#x201c;Pattern Matching and Language Variants&#x201d;
&lt;<a href="http://wg21.link/p0095r1"
>http://wg21.link/p0095r1</a>&gt;</p>

<p>[<a id="P0128R1">P0128R1</a>] Voutilainen, V. &#x201c;constexpr_if&#x201d;
&lt;<a href="http://wg21.link/p0128r1"
>http://wg21.link/p0128r1</a>&gt;</p>

<h2><a id="Acknowledgments">Acknowledgments</a></h2>
<p>The authors would like to thank David Sankel and Andrew Sutton&#x2014;and any others who may have been unintentionally missed&#x2014;for their feedback and encouragement.
Any mistakes in this paper are the responsibility of the authors.</p>

<h2><a id="Appendix">Appendix</a></h2>
<h3>Type list example</h3>
<pre class="prettyprint lang-cpp"
>template &lt;typename ...&gt; struct type_list { };

template &lt;typename List&gt;
using list_head = typename generic&lt;List&gt;(
  &lt;typename Elem, typename ...Elems&gt; type_list&lt;Elem, Elems ...&gt;: Elem
);

template &lt;typename List&gt;
using list_tail = typename generic&lt;List&gt;(
  &lt;typename Elem, typename ...Elems&gt;
      type_list&lt;Elem, Elems ...&gt;: type_list&lt;Elems ...&gt;
);</pre>

<h3>Example of copying top-level <i>cv</i>-qualification</h3>
<pre class="prettyprint lang-cpp"
>template &lt;typename T, typename U&gt;
struct preserve_cv {
  using type = typename generic&lt;T&gt;(
    typename{V} const V: const std::remove_cv_t&lt;U&gt;,
    typename{V} volatile V: volatile std::remove_cv_t&lt;U&gt;,
    typename{V} const volatile V: const volatile U,
    default: std::remove_cv_t&lt;U&gt;
  );
};

template &lt;typename T, typename U&gt;
using preserve_cv_t = typename preserve_cv&lt;T, U&gt;::type;</pre>

</body>
</html>
