<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0670R4, ISO/IEC JTC1 SC22 WG21">

<link rel="stylesheet" href="http://cdn.jsdelivr.net/font-hack/2.015/css/hack.min.css"/>
<style type="text/css">
pre {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  margin-left:20pt;
  line-height: 1.1em;
  font-size: small;
}
code {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-size: small;
}
pre > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "Hack", "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body {
    color: #000000; background-color: #FFFFFF; 
    font-family: "Book Antiqua", "Times New Roman", "Times", serif;
    padding: 2em;
}
/*del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }*/
del { text-decoration: line-through; color: #8B0040; background-color: rgb(248, 215, 231); }
ins { text-decoration: none;
    border-bottom: 1px solid #005100;
    color: #005100;
    background-color: #dbf8db;
    line-height: 1.4em;
}

ins.edit { text-decoration: none;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
del.edit {
  text-decoration: line-through;
    border-bottom: 1px solid #0000c1;
    color: #0000c1;
    line-height: 1.4em;
    background-color: #eeeeff;
}
span.section_name {
    float: right;
    font-weight: bold;
}

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

div.std {
  margin-left: 1em;
  border-left: 1px gray solid;
  padding-left: 1em;}
div.ins { text-decoration: none;
    border-left: 1px solid #005100;
    color: #005100;
    background-color: #dbf8db;
    line-height: 1.4em;
}
tr.ins { text-decoration: none;
    border-left: 1px solid #005100;
    color: #005100;
    background-color: #dbf8db;
    line-height: 1.4em;
}

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; margin-bottom: 0.5em;}

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
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: #dbf8db;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto;
  margin-top: 2em; margin-bottom: 2em;}

table.withBorder {
  border-top: none;
  border-left: none;
  border-right: 1px solid black;
  border-bottom: 1px solid black;
}
.withBorder th {
  border-top: 1px solid black;
  border-bottom: 1px solid black;
  border-left: 1px solid black;
/*  border-top: 2px solid black;
  border-left: 2px solid black;
  border-bottom: 1px solid black;
  border-right: 1px solid black;*/
}
.withBorder td {
  border-top: 1px solid black;
  border-left: 1px solid black;
}

table.header {
  margin-left: 0em;
  border: none;
    margin-bottom: 2em;
}
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; 
  padding-right: 0.4em;  }

ul.nobullet {
    list-style-type: none;
    /*margin: 0;
    padding: 0;*/
}
</style>

<title>Function reflection</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td><b>P0670R4</b>, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>CWG, LWG</td></tr>
   <tr><td>Date:</td><td>2018-06-08</td></tr>
  <tr><td rowspan="3">Authors:</td><td>Matúš Chochlík (chochlik@gmail.com)</td></tr>
  <tr><td>Axel Naumann (axel@cern.ch)</td></tr>
  <tr><td>David Sankel (camior@gmail.com)</td></tr>
</table>
<h1>Function reflection</h1>

<!--    <h2>Table of Contents</h2>
<nav id="TOC">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#other-proposals">Interplay with other proposals</a></li>
<li><a href="#design">Concepts and Operations</a></l>
< ! - - li><a href="#proposed-wording">Proposed wording</a></li - - >
<li><a href="#acknowledgments">Acknowledgments</a></li>
< ! - -li><a href="#history">Revision history</a></li- - >
<li><a href="#references">References</a></li>
</ul>
</nav>-->

  <!--
    <h2>&nbsp;</h2>
<blockquote>
<p></p>
</blockquote>
-->

<h3 id="introduction">0. Introduction</h3>
<p><a href="http://wg21.link/p0194">P0194</a> introduced static reflection for types and variables. This paper adds static reflection of functions.</p>
 
<p>Reflection proposed here behaves as follows:</p>
<pre><code>
void func(int);
void func(std::string);
using func_call_m = reflexpr(func(123));
using func_m = get_callable_t&lt;func_call_m&gt;; // reflects void func(int)
using param0_m = get_element_t&lt;0, get_parameters_t&lt;func_m&gt;&gt;;
cout &lt;&lt; get_name_v&lt;get_type_t&lt;param0_m&gt;&gt; &lt;&lt; '\n'; // prints "int"
</code></pre>

<p>The functionality introduced here allows for reflection of calls of concrete
functions. This enables, for instance, GUI generation, building a catalogue for
remote procedure calls, documentation generation, and signal/slot frameworks.
  Like P0194, this proposal omits attributes, templates, and reification
(i.e. conversion of a meta object to the base level): all warrant a separate paper.
  We would welcome a paper especially on static reflection of attributes, matching the interface-style of P0194 and this paper!
  Linkage and friends will be part of a follow-up paper to P0194; they will have a combined "effect" on P0194 and this paper.</p>

<h4 id="other-proposals">0.1 Interplay with other proposals</h4>
<p>Most notably, this proposal relies on the Reflection TS and the Concepts TS.</p>
<p><a href="http://wg21.link/p0385">P0385</a> discusses use cases, rationale,
design decisions, and the future evolution of the proposed reflection
facility. It also has usage examples and replies to frequently asked questions.</p>


<h3>1 Scope <span class="section_name">[intro.scope]</span></h3>

<p>This document is written as a set of changes against the Reflection TS (<a href="http://wg21.link/N4746">N4746</a>).
   Instructions to modify or add paragraphs are written as explicit instructions.
   Modifications made directly to existing text from the Reflection TS use <ins>underlining</ins> to represent added text and <del>strikethrough</del> to represent deleted text.</p>

<h3>2 Normative references <span class="section_name">[intro.refs]</span></h3>
<p>No changes are made to Clause 2 of the Reflection TS.</p>

<h3>3 Terms and definitions <span class="section_name">[intro.defs]</span></h3>
<p>No changes are made to Clause 3 of the Reflection TS.</p>

<h3>4 General <span class="section_name">[intro]</span></h3>
<h4>4.3 Acknowledgements <span class="section_name">[intro.ack]</span></h4>
<p>Modify the section as follows:</p>
<div class="std">
<p>This work is the result of a collaboration of researchers in industry and academia.
   We wish to thank people who made valuable contributions within and outside these groups, including
   Ricardo Fabiano de Andrade, Roland Bock, Chandler Carruth, <ins>Jackie Kay, </ins>Klaim-Jo&euml;l Lamotte, Jens Maurer,
   and many others not named here who contributed to the discussion.</p>
</div>

<h3>5 Lexical conventions <span class="section_name">[lex]</span></h3>
<p>No changes are made to Clause 5 of the Reflection TS.</p>

<h3>6 Basic concepts <span class="section_name">[basic]</span></h3>
<h4>6.2 One-definition rule <span class="section_name">[basic.def.odr]</span></h4>
<p>In C++ [basic.def.odr], insert a new paragraph after the existing paragraph 8:</p>
<div class="std">
<ins>A function or static variable reflected by <code>T</code> [dcl.type.reflexpr] is odr-used by the specialization <code>std::experimental::reflect::get_pointer&lt;T&gt;</code> (21.11.4.10, 21.11.4.18), as if by taking the address of an <em>id-expression</em> nominating the function or variable.</ins>
</div>
<p>In C++ [basic.def.odr], insert a new bullet (12.2.3) after (12.2.2):</p>
<div class="std"><ins>
&nbsp;&nbsp;&nbsp;or<br/></ins>
<ul>
   <li><ins>a type implementing <code>std::experimental::reflect::Object</code> (21.11.3.1), as long as all operations (21.11.4) on this type yield the same constant expression results.</ins></li>
</ul>
</div>


<h3>7 Standard conversions<span class="section_name">[conv]</span></h3>
<p>No changes are made to Clause 7 of the Reflection TS.</p>

<h3>8 Expressions<span class="section_name">[expr]</span></h3>
<h4>8.4 Primary expressions <span class="section_name">[expr.prim]</span></h4>
<h4>8.4.5 Lambda expressions <span class="section_name">[expr.prim.lambda]</span></h4>
<h4>8.4.5.2 Captures <span class="section_name">[expr.prim.lambda.capture]</span></h4>

<p>In C++ [expr.prim.lambda.capture], apply the following change to paragraph 7:</p>
<div class="std">
If an expression potentially references a local entity within a declarative region in which it is odr-usable, and the expression would be potentially evaluated if the effect of any enclosing <code>typeid</code> expressions (8.5.1.8) <ins>or use of a <em>reflexpr-specifier</em> (10.1.7.6)</ins> were ignored, the entity is said to be <em>implicitly captured</em> by each intervening <em>lambda-expression</em> with an associated <em>capture-default</em> that does not explicitly capture it.
</div>

<p>In C++ [expr.prim.lambda.capture], apply the following change to paragraph 11:</p>
<div class="std">
Every <em>id-expression</em> within the <em>compound-statement</em> of a <em>lambda-expression</em> that is an odr-use (6.2) of an entity captured by copy<ins>, as well as every use of an entity captured by copy in a <em>reflexpr-operand</em>, </ins>is transformed into an access to the corresponding unnamed data member of the closure type.
</div>

<h4>8.5 Compound expressions <span class="section_name">[expr.compound]</span></h4>
<h4>8.5.1 Postfix expressions <span class="section_name">[expr.post]</span></h4>
<p>In C++ [expr.post], apply the following change:</p>
<div class="std">
<ul class="nobullet">
<li><em>postfix-expression</em> :
<ul class="nobullet">
<li><em>primary-expression</em></li>
<li><em>postfix-expression</em> [ <em>expr-or-braced-init-list</em> ]</li>
<li><del><em>postfix-expression</em> ( <em>expression-list</em><sub>opt</sub> ) </del></li>
<li><ins><em>function-call-expression</em></ins></li>
<li><del><em>simple-type-specifier</em> ( <em>expression-list</em><sub>opt</sub> )</del></li>
<li><del><em>typename-specifier</em> ( <em>expression-list</em><sub>opt</sub> )</del></li>
<li><del><em>simple-type-specifier braced-init-list</em></del></li>
<li><del><em>typename-specifier braced-init-list</em></del></li>
<li><ins><em>functional-type-conv-expression</em></ins></li>
<li><em>postfix-expression</em> . <code>template</code><sub>opt</sub> <em>id-expression</em></li>
<li><em>postfix-expression</em> -&gt; <code>template</code><sub>opt</sub> <em>id-expression</em></li>
<li><em>postfix-expression</em> . <em>pseudo-destructor-name</em></li>
<li><em>postfix-expression</em> -&gt; <em>pseudo-destructor-name</em></li>
<li><em>postfix-expression</em> ++</li>
<li><em>postfix-expression</em> --</li>
<li><code>dynamic_cast</code> &lt; <em>type-id</em> &gt; ( <em>expression</em> )</li>
<li><code>static_cast</code> &lt; <em>type-id</em> &gt; ( <em>expression</em> )</li>
<li><code>reinterpret_cast</code> &lt; <em>type-id</em> &gt; ( <em>expression</em> )</li>
<li><code>const_cast</code> &lt; <em>type-id</em> &gt; ( <em>expression</em> )</li>
<li><code>typeid</code> ( <em>expression</em> )</li>
<li><code>typeid</code> ( <em>type-id</em> )</li>
</ul></li>
<li><ins><em>function-call-expression</em> :</ins>
   <ul class="nobullet">
   <li><ins><em>postfix-expression</em>  ( <em>expression-list</em><sub>opt</sub> )</ins></li></ul>
</li>
<li><ins><em>functional-type-conv-expression</em> :</ins>
   <ul class="nobullet">
   <li><ins><em>simple-type-specifier</em> ( <em>expression-list</em><sub>opt</sub> )</ins></li>
   <li><ins><em>typename-specifier</em> ( <em>expression-list</em><sub>opt</sub> )</ins></li>
   <li><ins><em>simple-type-specifier braced-init-list</em></ins></li>
   <li><ins><em>typename-specifier braced-init-list</em></ins></li>
</ul></li>
<li><em>expression-list</em> :
   <ul class="nobullet">
      <li><em>initializer-list</em></li>
   </ul>
</li>
</ul>
</div>

<h3>9 Statements<span class="section_name">[stmt.stmt]</span></h3>
<p>No changes are made to Clause 9 of the Reflection TS.</p>

<h3>10 Declarations <span class="section_name">[dcl.dcl]</span></h3>
<h4>10.1 Specifiers [dcl.spec]</h4>
<h4>10.1.7 Type specifiers [dcl.type]</h4>
<h4>10.1.7.2 Simple type specifiers <span class="section_name">[dcl.type.simple]</span></h4>
<p>In C++ [dcl.type.simple], apply the following change</p>
<div class="std">
<ul class="nobullet">
   <li>...</li>
   <li><em>reflexpr-operand</em>:
      <ul class="nobullet">
      <li><code>::</code><br/>
      <em>type-id</em><br/>
      <em>nested-name-specifier</em><sub>opt</sub> <em>identifier</em><br/>
      <em>nested-name-specifier</em><sub>opt</sub> <em>simple-template-id</em><br/>
      <ins>( <em>expression</em> )</ins><br/>
      <ins><em>function-call-expression</em></ins><br/>
      <ins><em>functional-type-conv-expression</em></ins>
         </li>
      </ul></li>
      </ul>
</div>

<h4>10.1.7.6 Reflection type specifier <span class="section_name">[dcl.type.reflexpr]</span></h4>
<p>Apply the following modification to the enumeration:</p>
<div class="std">
<ul>
<li>...</li>
<li><code>A</code> is not the global namespace and <code>B</code> is an enclosing namespace of <code>A</code>,<del> or</del></li>
<li><ins><code>B</code> is the parenthesized expression <code>( A )</code>,</ins></li>
<li><ins><code>A</code> is a lambda capture of the closure type <code>B</code>,</ins></li>
<li><ins><code>A</code> is the closure type of the lambda capture <code>B</code>,</ins></li>
<li><ins><code>A</code> is the type specified by the <em>functional-type-conv-expression</em> <code>B</code>,</ins></li>
<li><ins><code>A</code> is the function selected by overload resolution for a <em>function-call-expression</em> <code>B</code>,</ins></li>
<li><ins><code>A</code> is the return type, parameter type, or function type of the function <code>B</code>, or</ins></li>
<li><code>A</code> is reflection-related to an entity or alias <code>X</code> and <code>X</code> is reflection-related to <code>B</code>.</li>
</ul>
</div>

<div class="std">
<p>For the operand <code>::</code>, the type specified by the <code>reflexpr-specifier</code> satisfies <code>reflect::GlobalScope</code>.</p>
<p><ins>For an operand that is a parenthesized expression [expr.prim.paren], the type satisfies <code>reflect::ParenthesizedExpression</code>.
For a parenthesized expression <code>(E)</code>, whether or not itself nested inside a parenthesized expression, the expression <code>E</code> shall be either a parenthesized expression, a <em>function-call-expression</em> or a <em>functional-type-conv-expression</em>; otherwise the program is ill-formed.</ins></p>
<p><ins>For an operand of the form <em>function-call-expression</em>, the type satisfies <code>reflect::FunctionCallExpression</code>.
If the <em>postfix-expression</em> of the <em>function-call-expression</em> is of class type, the function call shall not resolve to a surrogate call function ([over.call.object]). Otherwise, the <em>postfix-expression</em> shall name a function that is the unique result of overload resolution.</ins></p>
<p><ins>For an operand of the form <em>functional-type-conv-expression</em> [expr.type.conv], the type satisfies <code>reflect::FunctionalTypeConversion</code>.
[<em>Note:</em> The usual disambiguation between function-style cast and a <em>type-id</em> [dcl.ambig.res] applies. [<em>Example:</em> The default constructor of <code>class X</code> can be reflected on as <code>reflexpr((X()))</code>, while <code>reflexpr(X())</code> reflects the type of a function returning <code>X</code>. <em>&mdash; end example</em>] <em>&mdash; end note</em>]
</ins><br/>
For an operand of the form <em>identifier</em> where <em>identifier</em> is a template <em>type-parameter</em>, the type satisfies both <code>reflect::Type</code> and <code>reflect::Alias</code>.</p>
</div>

<p>Modify Table 12 as follows:</p>
<table class="withBorder">
<thead><tr><th>Category</th><th><em>identifier</em> or <em>simple-template-id</em> kind</th><th><code>reflect</code> Concept</th></tr></thead>
<tbody>
<tr><td rowspan="6">type</td><td><em>class-name</em> designating a union</td><td><code>reflect::Record</code></td></tr>
<tr class="ins"><td><em>class-name</em> designating a closure type</td><td><code>reflect::Lambda</code></td></tr>
<tr><td><em>class-name</em> designating a non-union class</td><td><code>reflect::Class</code></td></tr>
<tr><td><em>enum-name</em></td><td><code>reflect::Enum</code></td></tr>
<tr><td><em>type-name</em> introduced by a <em>using-declaration</em></td><td>both <code>reflect::Type</code> and <code>reflect::Alias</code></td></tr>
<tr><td>any other <em>typedef-name</em></td><td>both <code>reflect::Type</code> and <code>reflect::Alias</code></td></tr>
<tr><td rowspan="2">namespace</td><td><em>namespace-alias</em></td><td>both <code>reflect::Namespace</code> and <code>reflect::Alias</code></td></tr>
<tr><td>any other <em>namespace-name</em></td><td>both <code>reflect::Namespace</code> and <code>reflect::ScopeMember</code></td></tr>
<tr><td>data member</td><td>the name of a data member</td><td><code>reflect::Variable</code></td></tr>
<tr><td rowspan="4">value</td><td>the name of a variable or structured binding that is not a local entity</td><td><code>reflect::Variable</code></td></tr>
<tr><td>the name of an enumerator</td><td>both <code>reflect::Enumerator</code> and <code>reflect::Constant</code></td></tr>
<tr class="ins"><td>the name of a function parameter</td><td><code>reflect::FunctionParameter</code></td></tr>
<tr class="ins"><td>the name of a captured entity [expr.prim.lambda.capture]</td><td><code>reflect::LambdaCapture</code></td></tr>
</tbody>
</table>

<p>Modify the following paragraph as follows:</p>
<div class="std">
   <p>If the <em>reflexpr-operand</em> designates an entity or alias at block scope (6.3.3) or function prototype scope (6.3.4)<ins> and the entity is neither captured nor a function parameter</ins>, the program is ill-formed.
   If the <em>reflexpr-operand</em> designates a class member, the type represented by the <em>reflexpr-specifier</em> also satisfies <code>reflect::RecordMember</code>.
   If the <em>reflexpr-operand</em> designates an <del>variable or a data member</del> <ins>expression</ins>, it is an unevaluated operand (expr.context).
   If the <em>reflexpr-operand</em> designates both an alias and a class name, the type represented by the <em>reflexpr-specifier</em> reflects the alias and satisfies <code>Alias</code>.
</p>
</div>

<h3>11 Declarators <span class="section_name">[dcl.decl]</span></h3>
<p>No changes are made to Clause 11 of the Reflection TS.</p>

<h3>12 Classes<span class="section_name">[class]</span></h3>
<p>No changes are made to Clause 12 of the Reflection TS.</p>

<h3>13 Derived classes<span class="section_name">[class.derived]</span></h3>
<p>No changes are made to Clause 13 of the Reflection TS.</p>

<h3>14 Member access control<span class="section_name">[class.access]</span></h3>
<p>No changes are made to Clause 14 of the Reflection TS.</p>

<h3>15 Special member functions<span class="section_name">[special]</span></h3>
<p>No changes are made to Clause 15 of the Reflection TS.</p>

<h3>16 Overloading<span class="section_name">[over]</span></h3>
<p>No changes are made to Clause 16 of the Reflection TS.</p>

<h3>17 Templates <span class="section_name">[temp]</span></h3>
<p>No changes are made to Clause 17 of the Reflection TS.</p>

<h3>18 Exception handling<span class="section_name">[except]</span></h3>
<p>No changes are made to Clause 18 of the Reflection TS.</p>

<h3>19 Preprocessing directives<span class="section_name">[cpp]</span></h3>
<p>No changes are made to Clause 19 of the Reflection TS.</p>

<h3>20 Library introduction<span class="section_name">[library]</span></h3>
<p>No changes are made to Clause 20 of the Reflection TS.</p>

<h3>21 Language support library <span class="section_name">[language.support]</span></h3>
<h4>21.11 Static reflection <span class="section_name">[reflect]</span></h4>
<h4>21.11.1 In general<span class="section_name">[reflect.general]</span></h4>
<h4>21.11.2 Header <code>&lt;experimental/reflect&gt;</code> synopsis <span class="section_name">[reflect.synopsis]</span></h4>
Modify this section as follows:
<div class="std">
<pre>
<code>
namespace std::experimental::reflect {
inline namespace v1 {

// 21.11.3 Concepts for meta-object types
template &lt;class T&gt; concept Object;
template &lt;class T&gt; concept ObjectSequence;            <ins>// refines Object</ins>
template &lt;class T&gt; concept Named;                     <ins>// refines Object</ins>
template &lt;class T&gt; concept Alias;                     <ins>// refines Named and ScopeMember</ins>
template &lt;class T&gt; concept RecordMember;              <ins>// refines ScopeMember</ins>
template &lt;class T&gt; concept Enumerator;                <ins>// refines Constant</ins>
template &lt;class T&gt; concept Variable;                  <ins>// refines Typed and ScopeMember</ins>
template &lt;class T&gt; concept ScopeMember;               <ins>// refines Named</ins>
template &lt;class T&gt; concept Typed;                     <ins>// refines Object</ins>
template &lt;class T&gt; concept Namespace;                 <ins>// refines Named and Scope</ins>
template &lt;class T&gt; concept GlobalScope;               <ins>// refines Namespace</ins>
template &lt;class T&gt; concept Class;                     <ins>// refines Record</ins>
template &lt;class T&gt; concept Enum;                      <ins>// refines Type and Scope</ins>
template &lt;class T&gt; concept Record;                    <ins>// refines Type and Scope</ins>
template &lt;class T&gt; concept Scope;                     <ins>// refines Object</ins>
template &lt;class T&gt; concept Type;                      <ins>// refines Named and ScopeMember</ins>
template &lt;class T&gt; concept Constant;                  <ins>// refines Typed and ScopeMember</ins>
template &lt;class T&gt; concept Base;                      <ins>// refines Object</ins>
<ins>template &lt;class T&gt; concept FunctionParameter;         // refines Typed and ScopeMember
template &lt;class T&gt; concept Callable;                  // refines Scope and ScopeMember
template &lt;class T&gt; concept Expression;                // refines Object
template &lt;class T&gt; concept ParenthesizedExpression;   // refines Expression
template &lt;class T&gt; concept FunctionCallExpression;    // refines Expression
template &lt;class T&gt; concept FunctionalTypeConversion;  // refines Expression
template &lt;class T&gt; concept Function;                  // refines Typed and Callable
template &lt;class T&gt; concept MemberFunction;            // refines RecordMember and Function
template &lt;class T&gt; concept SpecialMemberFunction;     // refines RecordMember
template &lt;class T&gt; concept Constructor;               // refines Callable and RecordMember
template &lt;class T&gt; concept Destructor;                // refines Callable and SpecialMemberFunction
template &lt;class T&gt; concept Operator;                  // refines Function
template &lt;class T&gt; concept ConversionOperator;        // refines MemberFunction and Operator
template &lt;class T&gt; concept Lambda;                    // refines Type and Scope
template &lt;class T&gt; concept LambdaCapture;             // refines Variable</ins>
</code></pre></div>
...
<div class="std">
<pre><code>
// 21.11.4 Meta-object operations
// 21.11.4.1 Multi-concept operations
template &lt;<del>class</del><ins>Object</ins> T&gt; struct is_public;
template &lt;<del>class</del><ins>Object</ins> T&gt; struct is_protected;
template &lt;<del>class</del><ins>Object</ins> T&gt; struct is_private;
<ins>template &lt;Object T&gt; struct is_constexpr;
template &lt;Object T&gt; struct is_static;
template &lt;Object T&gt; struct is_final;
template &lt;Object T&gt; struct is_explicit;
template &lt;Object T&gt; struct is_inline;
template &lt;Object T&gt; struct is_virtual;
template &lt;Object T&gt; struct is_pure_virtual;
template &lt;Object T&gt; struct get_pointer;</ins>

template &lt;class T&gt;
   constexpr auto is_public_v = is_public&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_protected_v = is_protected&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_private_v = is_private&lt;T&gt;::value;
<ins>template &lt;class T&gt;
   constexpr auto is_constexpr_v = is_constexpr&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_static_v = is_static&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_final_v = is_final&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_explicit_v = is_explicit&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_inline_v = is_inline&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_virtual_v = is_virtual&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto is_pure_virtual_v = is_pure_virtual&lt;T&gt;::value;
template &lt;class T&gt;
   constexpr auto get_pointer_v = get_pointer&lt;T&gt;::value;</ins>
</code></pre></div>
...
<div class="std">
<pre><code>
// 21.11.4.8 Record operations
template &lt;Record T&gt; struct get_public_data_members;
template &lt;Record T&gt; struct get_accessible_data_members;
template &lt;Record T&gt; struct get_data_members;
<ins>template &lt;Record T&gt; struct get_public_member_functions;
template &lt;Record T&gt; struct get_accessible_member_functions;
template &lt;Record T&gt; struct get_member_functions;</ins>
template &lt;Record T&gt; struct get_public_member_types;
template &lt;Record T&gt; struct get_accessible_member_types;
template &lt;Record T&gt; struct get_member_types;
<ins>template &lt;Record T&gt; struct get_constructors;
template &lt;Record T&gt; struct get_destructor;
template &lt;Record T&gt; struct get_operators;</ins>
template &lt;Class T&gt; struct get_public_base_classes;
template &lt;Class T&gt; struct get_accessible_base_classes;
template &lt;Class T&gt; struct get_base_classes;
template &lt;Class T&gt; struct is_final<ins>&lt;T&gt;</ins>;

template &lt;Record T&gt;
  using get_public_data_members_t = typename get_public_data_members&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_accessible_data_members_t = typename get_accessible_data_members&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_data_members_t = typename get_data_members&lt;T&gt;::type;
<ins>template &lt;Record T&gt;
  using get_public_member_functions_t = typename get_public_member_functions&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_accessible_member_functions_t = typename get_accessible_member_functions&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_member_functions_t = typename get_member_functions&lt;T&gt;::type;</ins>
template &lt;Record T&gt;
  using get_public_member_types_t = typename get_public_member_types&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_accessible_member_types_t = typename get_accessible_member_types&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_member_types_t = typename get_member_types&lt;T&gt;::type;
<ins>template &lt;Record T&gt;
  using get_constructors_t = typename get_constructors&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_destructor_t = typename get_destructor&lt;T&gt;::type;
template &lt;Record T&gt;
  using get_operators_t = typename get_operators&lt;T&gt;::type;</ins>
template &lt;Class T&gt;
  using get_public_base_classes_t = typename get_public_base_classes&lt;T&gt;::type;
template &lt;Class T&gt;
  using get_accessible_base_classes_t = typename get_accessible_base_classes&lt;T&gt;::type;
template &lt;Class T&gt;
  using get_base_classes_t = typename get_base_classes&lt;T&gt;::type;
<del>template &lt;Class T&gt;
  constexpr auto is_final_v = is_final&lt;T&gt;::value;</del>
</code>
</pre>
</div>
...
<div class="std">
<pre><code>
// 21.11.4.10 Value operations
template &lt;Constant T&gt; struct get_constant;
template &lt;Variable T&gt; struct is_constexpr<ins>&lt;T&gt;</ins>;
template &lt;Variable T&gt; struct is_static<ins>&lt;T&gt;</ins>;
template &lt;Variable T&gt; struct get_pointer<ins>&lt;T&gt;</ins>;

template &lt;Constant T&gt;
  constexpr auto get_constant_v = get_constant&lt;T&gt;::value;
<del>template &lt;Variable T&gt;
  constexpr auto is_constexpr_v = is_constexpr&lt;T&gt;::value;
template &lt;Variable T&gt;
  constexpr auto is_static_v = is_static&lt;T&gt;::value;
template &lt;Variable T&gt;
  const auto get_pointer_v = get_pointer&lt;T&gt;::value;</del>

// 21.11.4.11 Base operations
template &lt;Base T&gt; struct get_class;
template &lt;Base T&gt; struct is_virtual<ins>&lt;T&gt;</ins>;
template &lt;Base T&gt; struct is_public&lt;T&gt;;
template &lt;Base T&gt; struct is_protected&lt;T&gt;;
template &lt;Base T&gt; struct is_private&lt;T&gt;;

template &lt;Base T&gt;
  using get_class_t = typename get_class&lt;T&gt;::type;
<del>template &lt;Base T&gt;
  constexpr auto is_virtual_v = is_virtual&lt;T&gt;::value;</del>

// 21.11.4.12 Namespace operations
template &lt;Namespace T&gt; struct is_inline<ins>&lt;T&gt;</ins>;

<del>template &lt;Namespace T&gt;
  constexpr auto is_inline_v = is_inline&lt;T&gt;::value;</del>
</code>
</pre>
</div>
...
<div class="std ins">
<pre><code>
// 21.11.4.13 FunctionParameter operations
template &lt;FunctionParameter T&gt; struct has_default_argument;

template &lt;FunctionParameter T&gt;
  constexpr auto has_default_argument_v = has_default_argument&lt;T&gt;::value;

// 21.11.4.14 Callable operations
template &lt;Callable T&gt; struct get_parameters;
template &lt;Callable T&gt; struct is_vararg;
template &lt;Callable T&gt; struct is_constexpr&lt;T&gt;;
template &lt;Callable T&gt; struct is_noexcept&lt;T&gt;;
template &lt;Callable T&gt; struct is_inline&lt;T&gt;;
template &lt;Callable T&gt; struct is_deleted;

template &lt;Callable T&gt;
  using get_parameters_t = typename get_parameters&lt;T&gt;::type;
template &lt;Callable T&gt;
  constexpr auto is_vararg_v = is_vararg&lt;T&gt;::value;
template &lt;Callable T&gt;
  constexpr auto is_deleted_v = is_deleted&lt;T&gt;::value;

// 21.11.4.15 ParenthesizedExpression operations
template &lt;ParenthesizedExpression T&gt; struct get_subexpression;

template &lt;ParenthesizedExpression T&gt;
   using get_subexpression_t = typename get_subexpression&lt;T&gt;::type;

// 21.11.4.16 FunctionCallExpression operations
template &lt;FunctionCallExpression T&gt; struct get_callable;

template &lt;FunctionCallExpression T&gt;
  using get_callable_t = typename get_callable&lt;T&gt;::type;

// 21.11.4.17 FunctionalTypeConversion operations
template &lt;FunctionalTypeConversion T&gt; struct get_constructor;

template &lt;FunctionalTypeConversion T&gt;
  using get_constructor_t = typename get_constructor&lt;T&gt;::type;

// 21.11.4.18 Function operations
template &lt;Function T&gt; struct get_pointer&lt;T&gt;;

// 21.11.4.19 MemberFunction operations
template &lt;MemberFunction T&gt; struct is_static&lt;T&gt;;
template &lt;MemberFunction T&gt; struct is_const;
template &lt;MemberFunction T&gt; struct is_volatile;
template &lt;MemberFunction T&gt; struct has_lvalueref_qualifier;
template &lt;MemberFunction T&gt; struct has_rvalueref_qualifier;
template &lt;MemberFunction T&gt; struct is_virtual&lt;T&gt;;
template &lt;MemberFunction T&gt; struct is_pure_virtual&lt;T&gt;;
template &lt;MemberFunction T&gt; struct is_override;
template &lt;MemberFunction T&gt; struct is_final&lt;T&gt;;

template &lt;MemberFunction T&gt;
  constexpr auto is_const_v = is_const&lt;T&gt;::value;
template &lt;MemberFunction T&gt;
  constexpr auto is_volatile_v = is_volatile&lt;T&gt;::value;
template &lt;MemberFunction T&gt;
  constexpr auto has_lvalueref_qualifier_v = has_lvalueref_qualifier&lt;T&gt;::value;
template &lt;MemberFunction T&gt;
  constexpr auto has_rvalueref_qualifier_v = has_rvalueref_qualifier&lt;T&gt;::value;
template &lt;MemberFunction T&gt;
  constexpr auto is_override_v = is_override&lt;T&gt;::value;

// 21.11.4.20 SpecialMemberFunction operations
template &lt;SpecialMemberFunction T&gt; struct is_implicitly_declared;
template &lt;SpecialMemberFunction T&gt; struct is_defaulted;

template &lt;SpecialMemberFunction T&gt;
  constexpr auto is_implicitly_declared_v = is_implicitly_declared&lt;T&gt;::value;
template &lt;SpecialMemberFunction T&gt;
  constexpr auto is_defaulted_v = is_defaulted&lt;T&gt;::value;

// 21.11.4.21 Constructor operations
template &lt;Constructor T&gt; struct is_explicit&lt;T&gt;;

// 21.11.4.22 Destructor operations
template &lt;Destructor T&gt; struct is_virtual&lt;T&gt;;
template &lt;Destructor T&gt; struct is_pure_virtual&lt;T&gt;;

// 21.11.4.23 ConversionOperator operations
template &lt;ConversionOperator T&gt; struct is_explicit&lt;T&gt;;

// 21.11.4.24 Lambda operations
template &lt;Lambda T&gt; struct get_captures;
template &lt;Lambda T&gt; struct uses_default_copy_capture;
template &lt;Lambda T&gt; struct uses_default_reference_capture;
template &lt;Lambda T&gt; struct is_call_operator_const;

template &lt;Lambda T&gt;
  using get_captures_t = typename get_captures&lt;T&gt;::type;
template &lt;Lambda T&gt;
  constexpr auto uses_default_copy_capture_v = uses_default_copy_capture&lt;T&gt;::value;
template &lt;Lambda T&gt;
  constexpr auto uses_default_reference_capture_v = uses_default_reference_capture&lt;T&gt;::value;
template &lt;Lambda T&gt;
  constexpr auto is_call_operator_const_v = is_call_operator_const&lt;T&gt;::value;

// 21.11.4.25 LambdaCapture operations
template &lt;LambdaCapture T&gt; struct is_explicitly_captured;
template &lt;LambdaCapture T&gt; struct is_init_capture;

template &lt;LambdaCapture T&gt;
  constexpr auto is_explicitly_captured_v = is_explicitly_captured&lt;T&gt;::value;
template &lt;LambdaCapture T&gt;
  constexpr auto is_init_capture_v = is_init_capture&lt;T&gt;::value;
</code>
</pre>
</div>


<h4>21.11.3 Concepts for meta-object types <span class="section_name">[reflect.concepts]</span></h4>
Modify this section as follows:
<div class="std">

<h4>21.11.3.1 Concept <code>Object</code><span class="section_name">[reflect.concepts.object]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Object = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Object&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> is a meta-object type, as generated by the <code>reflexpr</code> operator or any of the meta-object operations that in turn generate meta-object types.</dd>
</dl>


<h4>21.11.3.2 Concept <code>ObjectSequence</code><span class="section_name">[reflect.concepts.objseq]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept ObjectSequence = <ins>Object&lt;T&gt; &amp;&amp;</ins> <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>ObjectSequence&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> is a sequence of <code>Object</code>s, generated by a meta-object operation.</dd>
</dl>

<h4>21.11.3.3 Concept <code>Named</code><span class="section_name">[reflect.concepts.named]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Named = <ins>Object&lt;T&gt; &amp;&amp;</ins> <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Named&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> <del>is an <code>Object</code> with</del><ins>has</ins> an associated (possibly empty) name.</dd>
</dl>

<h4>21.11.3.4 Concept <code>Alias</code><span class="section_name">[reflect.concepts.alias]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Alias = Named&lt;T&gt; &amp;&amp; <ins>ScopeMember&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Alias&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> <del>is a <code>Named</code> that</del> reflects a <code>typedef</code> declaration, an <em>alias-declaration</em>, a <em>namespace-alias</em>, a template <em>type-parameter</em>, a <em>decltype-specifier</em>, or a declaration introduced by a <em>using-declaration</em>.
   <ins>[<em>Note:</em></ins> <del>Any such <code>T</code> also satisfies <code>ScopeMember</code>; its scope</del> <ins>The <code>Scope</code> of an <code>Alias</code></ins> is the scope that the alias was injected into. <ins><em>&mdash; end note</em>]</ins><br/>
   [<em>Example:</em>
<pre><code>
namespace N {
   struct A;
}
namespace M {
   using X = N::A;
}
using M_X_t = reflexpr(M::X);
using M_X_scope_t = get_scope_t&lt;M_X_t&gt;;
</code></pre> The scope reflected by <code>M_X_scope_t</code> is <code>M</code>, not <code>N</code>. <em>&mdash; end example</em>]<br/>
Except for the type represented by the <code>reflexpr</code> operator, <code>Alias</code> properties resulting from type transformations (21.11.4) are not retained.</dd>
</dl>

<h4>21.11.3.5 Concept <code>RecordMember</code><span class="section_name">[reflect.concepts.recordmember]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept RecordMember = <ins>ScopeMember&lt;T&gt; &amp;&amp;</ins> <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>RecordMember&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a <em>member-declaration</em>. <del>Any such <code>T</code> also satisfies <code>ScopeMember</code>. </del><!-- covers members of class, struct, union --></dd>
</dl>

<h4>21.11.3.6 Concept <code>Enumerator</code><span class="section_name">[reflect.concepts.enumerator]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Enumerator = <ins>Typed&lt;T&gt; &amp;&amp; ScopeMember&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Enumerator&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects an enumerator. <del>Any such <code>T</code> also satisfies <code>Typed</code> and <code>ScopeMember</code>; the </del><ins>[<em>Note:</em> The </ins> <code>Scope</code> of an <code>Enumerator</code> is its type also for enumerations that are unscoped enumeration types. <ins><em>&mdash; end note</em>]</ins></dd>
</dl>

<h4>21.11.3.7 Concept <code>Variable</code><span class="section_name">[reflect.concepts.variable]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Variable = <ins>Typed&lt;T&gt; &amp;&amp;</ins> <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Variable&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a variable or non-static data member. <del>Any such <code>T</code> also satisfies <code>Typed</code></del>.</dd>
</dl>

<h4>21.11.3.8 Concept <code>ScopeMember</code><span class="section_name">[reflect.concepts.scopemember]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept ScopeMember = <ins>Named&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>ScopeMember&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> satisfies <code>RecordMember</code>, <code>Enumerator</code>, or <code>Variable</code>, or if <code>T</code> reflects a namespace that is not the global namespace. <del>Any such <code>T</code> also satisfies <code>Named</code>.</del> <ins>[<em>Note:</em></ins> The scope of members of an unnamed union is the unnamed union; the scope of enumerators is their type. <ins><em>&mdash; end note</em>]</ins></dd>
</dl>

<h4>21.11.3.9 Concept <code>Typed</code><span class="section_name">[reflect.concepts.typed]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Typed = <ins>Named&lt;T&gt; &amp;&amp; <em>see below</em></ins>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Typed&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects an entity with a type. <del>Any such <code>T</code> also satisfies <code>Named</code>.</del></dd>
</dl>

<h4>21.11.3.10 Concept <code>Namespace</code><span class="section_name">[reflect.concepts.namespace]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Namespace = <ins>Scope&lt;T&gt; &amp;&amp;</ins> <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Namespace&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a namespace (including the global namespace). <del>Any such <code>T</code> also satisfies <code>Scope</code>.</del> <ins>[<em>Note:</em> </ins>Any such <code>T</code> that does not reflect the global namespace also satisfies <code>ScopeMember</code>. <ins><em>&mdash; end note</em>]</ins></dd>
</dl>

<h4>21.11.3.11 Concept <code>GlobalScope</code><span class="section_name">[reflect.concepts.globalscope]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept GlobalScope = <ins>Namespace&lt;T&gt; &amp;&amp;</ins> <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>GlobalScope&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects the global namespace. <ins>[<em>Note:</em> </ins>Any such <code>T</code> <del>also satisfies <code>Namespace</code>; it</del> does not satisfy <code>ScopeMember</code>. <ins><em>&mdash; end note</em>]</ins></dd>
</dl>

<h4>21.11.3.12 Concept <code>Class</code><span class="section_name">[reflect.concepts.class]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Class = <ins>Record&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Class&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a non-union class type. <del>Any such <code>T</code> also satisfies <code>Record</code>.</del></dd>
</dl>

<h4>21.11.3.13 Concept <code>Enum</code><span class="section_name">[reflect.concepts.enum]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Enum = <ins>Type&lt;T&gt; &amp;&amp; Scope&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Enum&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects an enumeration type. <del>Any such <code>T</code> also satisfies <code>Type</code> and <code>Scope</code>.</del></dd>
</dl>

<h4>21.11.3.14 Concept <code>Record</code><span class="section_name">[reflect.concepts.record]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Record = <ins>Type&lt;T&gt; &amp;&amp; Scope&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Record&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a class type. <del>Any such <code>T</code> also satisfies <code>Type</code> and <code>Scope</code>.</del></dd>
</dl>


<h4>21.11.3.15 Concept <code>Scope</code><span class="section_name">[reflect.concepts.scope]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Scope = <ins>Object&lt;T&gt; &amp;&amp; <em>see below</em> </ins><del>Namespace&lt;T&gt; || Record&lt;T&gt; || Enum&lt;T&gt;</del>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Scope&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a namespace (including the global namespace), class, <del>or</del> enumeration<ins>, function or closure type</ins>. [<em>Note:</em> Any such <code>T</code> that does not reflect the global namespace also satisfies <code>ScopeMember</code>. <em>&mdash; end note</em>]</dd>
</dl>

<h4>21.11.3.16 Concept <code>Type</code><span class="section_name">[reflect.concepts.type]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Type = <ins>Named&lt;T&gt; &amp;&amp; ScopeMember&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Type&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a type. <del>Any such <code>T</code> also satisfies <code>Named</code> and <code>ScopeMember</code>.</del></dd>
</dl>

<h4>21.11.3.17 Concept <code>Constant</code><span class="section_name">[reflect.concepts.const]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Constant = <ins>ScopeMember&lt;T&gt; &amp;&amp; Typed&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Constant&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a constant expression ([expr.const]). <del>Any such <code>T</code> also satisfies <code>ScopeMember</code> and <code>Typed</code></del>.</dd>
</dl>

<h4>21.11.3.18 Concept <code>Base</code><span class="section_name">[reflect.concepts.base]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Base = <ins>Object&lt;T&gt; &amp;&amp; </ins><em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Base&lt;T&gt;</code> is <del>satisfied</del><ins><code>true</code></ins> if and only if <code>T</code> reflects a direct base class, as returned by the template <code>get_base_classes</code>.</dd>
</dl>
</div>

<p>Add the following paragraphs at the end of [reflect.concepts]:</p>

<div class="std ins">
<h4>21.11.3.19 Concept <code>FunctionParameter</code><span class="section_name">[reflect.concepts.fctparam]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept FunctionParameter = Typed&lt;T&gt; &amp;&amp; ScopeMember&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>FunctionParameter&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a function parameter.
[<em>Note:</em> The <code>Scope</code> of a <code>FunctionParameter</code> is the <code>Callable</code> to which this parameter appertains. <em>&mdash; end note</em>]<br/>
[<em>Note:</em> A <code>FunctionParameter</code> does not satisfy <code>Variable</code>, and thus does not offer an interface for getting the pointer to a parameter. <em>&mdash; end note</em>]</dd>
</dl>

<h4>21.11.3.20 Concept <code>Callable</code><span class="section_name">[reflect.concepts.callable]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Callable = ScopeMember&lt;T&gt; &amp;&amp; Scope&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Callable&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a function, including constructors and destructors.</dd>
</dl>

<h4>21.11.3.21 Concept <code>Expression</code><span class="section_name">[reflect.concepts.expr]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Expression = Object&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Expression&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects an expression [expr].</dd>
</dl>

<h4>21.11.3.22 Concept <code>ParenthesizedExpression</code><span class="section_name">[reflect.concepts.expr.paren]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept ParenthesizedExpression = Expression&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>ParenthesizedExpression&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a parenthesized expression [expr.prim.paren].</dd>
</dl>

<h4>21.11.3.23 Concept <code>FunctionCallExpression</code><span class="section_name">[reflect.concepts.expr.fctcall]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept FunctionCallExpression = Expression&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>FunctionCallExpression&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a <em>function-call-expression</em> [expr.call].</dd>
</dl>

<h4>21.11.3.24 Concept <code>FunctionalTypeConversion</code><span class="section_name">[reflect.concepts.expr.type.fctconv]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept FunctionalTypeConversion = Expression&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>FunctionalTypeConversion&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a <em>functional-type-conv-expression</em> [expr.type.conv].</dd>
</dl>

<h4>21.11.3.25 Concept <code>Function</code><span class="section_name">[reflect.concepts.fct]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Function = Callable&lt;T&gt; &amp;&amp; Typed&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Function&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a function, excluding constructors and destructors.</dd>
</dl>

<h4>21.11.3.26 Concept <code>MemberFunction</code><span class="section_name">[reflect.concepts.memfct]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept MemberFunction = RecordMember&lt;T&gt; &amp;&amp; Function&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>MemberFunction&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a member function, excluding constructors and destructors.</dd>
</dl>

<h4>21.11.3.27 Concept <code>SpecialMemberFunction</code><span class="section_name">[reflect.concepts.specialfct]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept SpecialMemberFunction = RecordMember&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>SpecialMemberFunction&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a special member function [special].</dd>
</dl>

<h4>21.11.3.28 Concept <code>Constructor</code><span class="section_name">[reflect.concepts.ctor]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Constructor = Callable&lt;T&gt; &amp;&amp; RecordMember&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Constructor&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a constructor. [<em>Note:</em> Some types that satisfy <code>Constructor</code> also satisfy <code>SpecialMemberFunction</code>. <em>&mdash; end note</em>]</dd>
</dl>

<h4>21.11.3.29 Concept <code>Destructor</code><span class="section_name">[reflect.concepts.dtor]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Destructor = Callable&lt;T&gt; &amp;&amp; SpecialMemberFunction&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Destructor&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a destructor.</dd>
</dl>

<h4>21.11.3.30 Concept <code>Operator</code><span class="section_name">[reflect.concepts.oper]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Operator = Function&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Operator&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects an operator function [over.oper] or a conversion function [class.conv.fct]. [<em>Note:</em> Some types that satisfy <code>Operator</code> also satisfy <code>MemberFunction</code> or <code>SpecialMemberFunction</code>. <em>&mdash; end note</em>]</dd>
</dl>

<h4>21.11.3.31 Concept <code>ConversionOperator</code><span class="section_name">[reflect.concepts.convfct]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept ConversionOperator = Operator&lt;T&gt; &amp;&amp; MemberFunction&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>ConversionOperator&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a conversion function [class.conv.fct].</dd>
</dl>

<h4>21.11.3.32 Concept <code>Lambda</code><span class="section_name">[reflect.concepts.lambda]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Lambda = Type&lt;T&gt; &amp;&amp; Scope&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Lambda&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a closure object (excluding generic lambdas).</dd>
</dl>

<h4>21.11.3.33 Concept <code>LambdaCapture</code><span class="section_name">[reflect.concepts.lambdacapture]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept LambdaCapture = Variable&lt;T&gt; &amp;&amp; <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>LambdaCapture&lt;T&gt;</code> is <code>true</code> if and only if <code>T</code> reflects a lambda capture as introduced by the capture list or by capture defaults. [<em>Note:</em> The <code>Scope</code> of a <code>LambdaCapture</code> is its immediately enclosing <code>Lambda</code>. <em>&mdash; end note</em>]</dd>
</dl>
</div>


<h4>21.11.4 Meta-object Operations <span class="section_name">[reflect.ops]</span></h4>
<p>Add two new final paragraphs to [reflect.ops]:</p>
<div class="std ins">
<p>Some operations specify result types with a nested type called <code>type</code> that satisfies one of the concepts in <code>reflect</code>.
These nested types will possibly satisfy other concepts, for instance more specific ones, or independent ones, as applicable for the entity reflected by the nested type.
[<em>Example:</em><pre><code>struct X {};
X x;
using x_t = get_type_t&lt;reflexpr(x)&gt;;</code></pre>
While <code>get_type_t</code> is specified to be a <code>Type</code>, <code>x_t</code> will even satisfy <code>Class</code>. <em>&mdash; end example</em>]
</p>
<p>If subsequent specializations of operations on the same reflected entity could give different constant expression results (for instance for <code>get_name_v</code> because the parameter's function is redeclared with a different parameter name between the two points of instantiation), the program is ill-formed, no diagnostic required.
   [<em>Example:</em><pre><code>void func(int a);
auto x1 = get_name_v&lt;get_element_t&lt;0, get_parameters_t&lt;reflexpr(func(42))&gt;&gt;&gt;;
void func(int b);
auto x2 = get_name_v&lt;get_element_t&lt;0, get_parameters_t&lt;reflexpr(func(42))&gt;&gt;&gt;; // ill-formed, no diagnostic required</code></pre>
<em>&mdash; end example</em>]
</p>
</div>

<h4>21.11.4.1 Multi-concept operations <span class="section_name">[reflect.ops.over]</span></h4>
<p>Remove the section 21.11.4.1.</p>

<h4>21.11.4.4 Named operations<span class="section_name">[reflect.ops.named]</span></h4>
<p>Modify the relevant part of [reflect.ops.over] as follows:</p>
<div class="std">
<ul>
<li><ul>
<li>...</li>
<li>for <code>T</code> reflecting a class data member, its unqualified name<del>.</del><ins>;</ins></li>
<li><ins>for <code>T</code> reflecting a function, its unqualified name;</ins></li>
<li><ins>for <code>T</code> reflecting a specialization of a template function, its <em>template-name</em>;</ins></li>
<li><ins>for <code>T</code> reflecting a function parameter, its unqualified name;</ins></li>
<li><ins>for <code>T</code> reflecting a constructor, the <em>injected-class-name</em> of its class;</ins></li>
<li><ins>for <code>T</code> reflecting a destructor, the <em>injected-class-name</em> of its class, prefixed by the character '~';</ins></li>
<li><ins>for <code>T</code> reflecting an operator function, the <em>operator</em> element of the relevant <em>operator-function-id</em>;</ins></li>
<li><ins>for <code>T</code> reflecting an conversion function, the same characters as <code>get_name_ve&lt;R&gt;</code>, with <code>R</code> reflecting the type represented by the <em>conversion-type-id</em>.</ins></li>
</ul></li>
<li>In all other cases<ins> (for instance for <code>T</code> reflecting a lambda object)</ins>, the string's value is the empty string for get_name<ins>&lt;T&gt;</ins> and implementation-defined for get_display_name<ins>&lt;T&gt;</ins>.</li>
</ul>
</div>
Insert a new final paragraph:
<div class="std">
<dl class="attribute">
      <dt><ins>Remarks:</ins></dt>
      <dd><ins>Subsequent specializations of <code>get_name&lt;T&gt;</code> on the same reflected function parameter can render the program ill-formed, no diagnostic required (21.11.4).</ins></dd>
   </dl>
</div>

<h4>21.11.4.7 Member operations<span class="section_name">[reflect.ops.member]</span></h4>
<p>Modify the relevant part of [reflect.ops.over] as follows:</p>
<div class="std">
With <em>ST</em> being the scope of the declaration of the entity<del> or</del><ins>,</ins> typedef <ins>or value</ins> reflected by <code>T</code>, <em>S</em> is found as the innermost scope enclosing <em>ST</em> that is either a namespace scope (including global scope), class scope, <del>or </del>enumeration scope<ins>, function scope (for the function's parameters), or immediately enclosing closure type (for lambda captures). For members of an unnamed union, this innermost scope is the unnamed union. For enumerators of unscoped enumeration types, this innermost scope is their enumeration type</ins>.
</div>

<h4>21.11.4.8 Record operations<span class="section_name">[reflect.ops.record]</span></h4>
<p>Modify the relevant part of [reflect.ops.record] as follows:</p>
<div class="std">
<p class="function">
<code>
template &lt;Record T&gt; struct get_public_data_members;<br/>
template &lt;Record T&gt; struct get_accessible_data_members;<br/>
template &lt;Record T&gt; struct get_data_members;<br/>
<ins>template &lt;Record T&gt; struct get_public_member_functions;<br/>
template &lt;Record T&gt; struct get_accessible_member_functions;<br/>
template &lt;Record T&gt; struct get_member_functions;</ins>
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>RecordMember</code> types that reflect the following subset of <ins>non-template</ins> <del>data </del>members of the class reflected by <code>T</code>:
<ul>
   <li>for <code>get_data_members</code><ins> (<code>get_member_functions</code>)</ins>, all data <ins>(function, including constructor and destructor) </ins>members.</li>
   <li>for <code>get_public_data_members</code><ins> (<code>get_public_member_functions</code>)</ins>, all public data <ins>(function, including constructor and destructor) </ins>members;</li>
  <li>for <code>get_accessible_data_members</code><ins> (<code>get_accessible_member_functions</code>)</ins>, all data <ins>(function, including constructor and destructor) </ins>members that are accessible from the context where the <em>reflexpr-specifier</em> appeared which (directly or indirectly) generated <code>T</code>.<br/>
<ins>[<em>Example:</em></ins><pre><code><ins>class X {
   int a;

   friend struct Y;
};

struct Y {
  using X_t = reflexpr(X);
};

using X_mem_t = get_accessible_data_members_t&lt;Y::X_t&gt;;
static_assert(get_size_v&lt;X_mem_t&gt; == 1); // passes.</ins>
</code></pre>
<ins><em>&mdash; end example</em>]</ins></li>
</ul>
The order of the elements in the <code>ObjectSequence</code> is the order of the declaration of the <del>data</del> members in the class reflected by <code>T</code>.</dd>
<dt>Remarks:</dt>
<dd>
  The program is ill-formed if <code>T</code> reflects a closure type.
</dd>
</dl>
</div>
<div class="std ins">
<p class="function">
<code>
template &lt;Record T&gt; struct get_constructors;<br/>
template &lt;Record T&gt; struct get_destructor;<br/>
template &lt;Record T&gt; struct get_operators;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>RecordMember</code> types that reflect the following subset of function members of the class reflected by <code>T</code>:
<ul>
   <li>for <code>get_constructors</code>, all constructors.</li>
   <li>for <code>get_destructor</code>, the destructor;</li>
  <li>for <code>get_operators</code>, all conversion functions [class.conv.fct] and operator functions [over.oper].</li>
</ul>
The order of the elements in the <code>ObjectSequence</code> is the order of the declaration of the members in the class reflected by <code>T</code>.</dd>
<dt>Remarks:</dt>
<dd>
  The program is ill-formed if <code>T</code> reflects a closure type.
</dd>
</dl>
</div>

<p>Modify the relevant part of [reflect.ops.record] as follows:</p>
<div class="std">
<p class="function">
<code>
template &lt;Class T&gt; struct is_final<ins>&lt;T&gt;</ins>;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_final&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If <code>T</code> reflects a class that is marked with the <em>class-virt-specifier</em> <code>final</code>, the base characteristic of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>
</div>

<h4>21.11.4.10 Value operations<span class="section_name">[reflect.ops.value]</span></h4>
<p>Modify the relevant part of [reflect.ops.value] as follows:</p>
<div class="std">
<p class="function">
<code>
template &lt;Variable T&gt; struct is_constexpr<ins>&lt;T&gt;</ins>;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_constexpr&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If <code>T</code> reflects a variable declared with the <em>decl-specifier</em> <code>constexpr</code>, the base characteristic of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>

<p class="function">
<code>
template &lt;Variable T&gt; struct is_static<ins>&lt;T&gt;</ins>;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_static&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If <code>T</code> reflects a variable with static storage duration, the base characteristic of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>

<p class="function">
<code>
template &lt;Variable T&gt; struct get_pointer<ins>&lt;T&gt;</ins>;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_pointer&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]), with a static data member named <code>value</code> of type <code>X</code> and value <code>x</code>, where
<ul>
  <li>for variables with static storage duration: <code>X</code> is <code>add_pointer&lt;Y&gt;</code>, where <code>Y</code> is the type of the variable reflected by <code>T</code> and <code>x</code> is the address of that variable; otherwise, </li>
  <li><code>X</code> is the pointer-to-member type of the member variable reflected by <code>T</code> and <code>x</code> a pointer to the member.</li>
</ul>
[<em>Note:</em> A <code>FunctionParameter</code> does not satisfy <code>Variable</code>, and thus does not offer an interface for getting the pointer to a parameter. <em>&mdash; end note</em>]
</dd></dl>
</div>


<h4>21.11.4.11 Base operations<span class="section_name">[reflect.ops.derived]</span></h4>
<p>Modify the relevant part of [reflect.ops.derived] as follows:</p>
<div class="std">
<p class="function">
<code>
template &lt;Base T&gt; struct get_class;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_class&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is an alias to <code>reflexpr(<em>X</em>)</code>, where <code><em>X</em></code> is the base class reflected by <code>T</code>.</dd></dl>

<p class="function">
<code>
template &lt;Base T&gt; struct is_virtual<ins>&lt;T&gt;</ins>;<br/>
template &lt;Base T&gt; struct is_public&lt;T&gt;;<br/>
template &lt;Base T&gt; struct is_protected&lt;T&gt;;<br/>
template &lt;Base T&gt; struct is_private&lt;T&gt;;
</code>
</p>
</div>


<h4>21.11.4.12 Namespace operations<span class="section_name">[reflect.ops.namespace]</span></h4>
<p>Modify the relevant part of [reflect.ops.derived] as follows:</p>
<div class="std">
<p class="function">
<code>
template &lt;Namespace T&gt; struct is_inline<ins>&lt;T&gt;</ins>;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_inline&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If <code>T</code> reflects an inline namespace, the base characteristic of the template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>

</div>


<p>Add the following paragraphs at the end of [reflect.ops]:</p>
<div class="std ins">

   <h4>21.11.4.13 FunctionParameter operations
      <span class="section_name">[reflect.ops.fctparam]</span>
   </h4>
   <p class="function">
      <code>
template &lt;FunctionParameter T&gt; struct has_default_argument;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If
         <code>T</code> reflects a parameter with a default argument, the base characteristic of
         <code>has_default_argument&lt;T&gt;</code> is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
      <dt>Remarks:</dt>
      <dd>Subsequent specializations of <code>has_default_argument&lt;T&gt;</code> on the same reflected function parameter can render the program ill-formed, no diagnostic required (21.11.4).</dd>
   </dl>


   <h4>21.11.4.14 Callable operations<span class="section_name">[reflect.ops.callable]</span></h4>
   <p class="function">
      <code>
template &lt;Callable T&gt; struct get_parameters;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>FunctionParameter</code> types that reflect the parameters of the function reflected by <code>T</code>.
      If that function's <em>parameter-declaration-clause</em> [dcl.fct] terminates with an ellipsis, the <code>ObjectSequence</code> does not contain any additional elements reflecting that. The <code>is_vararg_v&lt;Callable&gt;</code> trait can be used to determine if the terminating ellipsis is in its parameter list.
      </dd>
   </dl>

   <p class="function">
      <code>
template &lt;Callable T&gt; struct is_vararg;<br/>
template &lt;Callable T&gt; struct is_constexpr&lt;T&gt;;<br/>
template &lt;Callable T&gt; struct is_noexcept&lt;T&gt;;<br/>
template &lt;Callable T&gt; struct is_inline&lt;T&gt;;<br/>
template &lt;Callable T&gt; struct is_deleted;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of these templates shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]).
			If their template parameter reflects an entity with an ellipsis terminating the <em>parameter-declaration-clause</em> [dcl.fct] (for <code>is_vararg</code>),
			or an entity that is (where applicable implicitly or explicitly) declared as <code>constexpr</code> (for <code>is_constexpr</code>),
			<code>noexcept</code> (for <code>is_noexcept</code>), as an inline function [dcl.inline] (for <code>is_inline</code>),
			or as deleted (for <code>is_deleted</code>), the base characteristic of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.
      </dd>
      <dt>Remarks:</dt>
      <dd>Subsequent specializations of <code>is_inline&lt;T&gt;</code> on the same reflected function can render the program ill-formed, no diagnostic required (21.11.4).</dd>
   </dl>

   <h4>21.11.4.15 ParenthesizedExpression operations<span class="section_name">[reflect.ops.expr.paren]</span></h4>
   <p class="function">
      <code>
template &lt;ParenthesizedExpression T&gt; struct get_subexpression;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of <code>get_subexpression&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is the <code>Expression</code> type reflecting the expression <code>E</code> of the parenthesized expression <code>(E)</code> reflected by <code>T</code>. 
      </dd>
   </dl>


   <h4>21.11.4.16 FunctionCallExpression operations<span class="section_name">[reflect.ops.expr.fctcall]</span></h4>
   <p class="function">
      <code>
template &lt;FunctionCallExpression T&gt; struct get_callable;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of <code>get_callable&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is the <code>Callable</code> type reflecting the function invoked by the <em>function-call-expression</em> which is reflected by <code>T</code>.
      </dd>
   </dl>


   <h4>21.11.4.17 FunctionalTypeConversion operations<span class="section_name">[reflect.ops.expr.fcttypeconv]</span></h4>
   <p class="function">
      <code>
template &lt;FunctionalTypeConversion T&gt; struct get_constructor;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
			<dd>All specializations of <code>get_converting_callable&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). For a type conversion reflected by <code>T</code>, the nested type named <code>type</code> is the <code>Constructor</code> reflecting the constructor of the type specified by the type conversion, as selected by overload resolution.
      The program is ill-formed if no such constructor exists.
      [<em>Note:</em> For instance fundamental types (6.7) do not have constructors. <em>&mdash; end note</em>]
      </dd>
   </dl>

   <h4>21.11.4.18 Function operations<span class="section_name">[reflect.ops.fct]</span></h4>
   <p class="function">
      <code>
template &lt;Function T&gt; struct get_pointer&lt;T&gt;;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of <code>get_pointer&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements ([meta.rqmts]), with a static data member named <code>value</code> of type <code>X</code> and value <code>x</code>, where
         <ul>
           <li>for non-static member functions, <code>X</code> is the pointer-to-member-function type of the member function reflected by <code>T</code> and <code>x</code> a pointer to the member function; otherwise,</li>
           <li><code>X</code> is <code>add_pointer&lt;Y&gt;</code>, where <code>Y</code> is the type of the function reflected by <code>T</code> and <code>x</code> is the address of that function. </li>
         </ul>
      </dd>
   </dl>


   <h4>21.11.4.19 MemberFunction operations<span class="section_name">[reflect.ops.memfct]</span></h4>
   <p class="function">
      <code>
template &lt;MemberFunction T&gt; struct is_static&lt;T&gt;;<br/>
template &lt;MemberFunction T&gt; struct is_const;<br/>
template &lt;MemberFunction T&gt; struct is_volatile;<br/>
template &lt;MemberFunction T&gt; struct has_lvalueref_qualifier;<br/>
template &lt;MemberFunction T&gt; struct has_rvalueref_qualifier;<br/>
template &lt;MemberFunction T&gt; struct is_virtual&lt;T&gt;;<br/>
template &lt;MemberFunction T&gt; struct is_pure_virtual&lt;T&gt;;<br/>
template &lt;MemberFunction T&gt; struct is_override;<br/>
template &lt;MemberFunction T&gt; struct is_final&lt;T&gt;;<br/>
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of these templates shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If their template parameter reflects a member function that is <code>static</code> (for <code>is_static</code>), <code>const</code> (for <code>is_const</code>), <code>volatile</code> (for <code>is_volatile</code>), declared with a <em>ref-qualifier</em> <code>&amp;</code> (for <code>has_lvalueref_qualifier</code>) or <code>&amp;&amp;</code> (for <code>has_rvalueref_qualifier</code>), implicitly or expicitly <code>virtual</code> (for <code>is_virtual</code>), pure virtual (for <code>is_pure_virtual</code>), or marked with <code>override</code> (for <code>is_override</code>) or <code>final</code> (for <code>is_final</code>), the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>


   <h4>21.11.4.20 SpecialMemberFunction operations<span class="section_name">[reflect.ops.specialfct]</span></h4>
   <p class="function">
      <code>
template &lt;SpecialMemberFunction T&gt; struct is_implicitly_declared;<br/>
template &lt;SpecialMemberFunction T&gt; struct is_defaulted;<br/>
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of these templates shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If their template parameter reflects a special member function that is implicitly declared (for <code>is_implicitly_declared</code>) or that is defaulted in its first declaration (for <code>is_defaulted</code>), the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
      </dl>


   <h4>21.11.4.21 Constructor operations<span class="section_name">[reflect.ops.ctor]</span></h4>
   <p class="function">
      <code>
template &lt;Constructor T&gt; struct is_explicit&lt;T&gt;;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects an explicit constructor, the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>


   <h4>21.11.4.22 Destructor operations<span class="section_name">[reflect.ops.dtor]</span></h4>
   <p class="function">
      <code>
template &lt;Destructor T&gt; struct is_virtual&lt;T&gt;;<br/>
template &lt;Destructor T&gt; struct is_pure_virtual&lt;T&gt;;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of these templates shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects a virtual (for <code>is_virtual</code>) or pure virtual (for <code>is_pure_virtual</code>) destructor, the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>


   <h4>21.11.4.23 ConversionOperator operations<span class="section_name">[reflect.ops.convfct]</span></h4>
   <p class="function">
      <code>
         template &lt;ConversionOperator T&gt; struct is_explicit&lt;T&gt;;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects an explicit conversion function, the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>


   <h4>21.11.4.24 Lambda operations<span class="section_name">[reflect.ops.lambda]</span></h4>
   <p class="function">
      <code>
template &lt;Lambda T&gt; struct get_captures;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the <code>TransformationTrait</code> requirements ([meta.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>LambdaCapture</code> types that reflect the captures of the closure object reflected by <code>T</code>.
      The elements are in order of appearance in the <em>lambda-capture</em>; captures captured because of a <em>capture-default</em> have no defined order among the default captures.
      </dd>
   </dl>

   <p class="function">
      <code>
template &lt;Lambda T&gt; struct uses_default_copy_capture;<br/>
template &lt;Lambda T&gt; struct uses_default_reference_capture;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of these templates shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects a closure object with a <em>capture-default</em> that is <code>=</code> (for <code>uses_default_copy_capture</code>) or <code>&amp;</code> (for <code>uses_default_reference_capture</code>), the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>

   <p class="function">
      <code>
template &lt;Lambda T&gt; struct is_call_operator_const;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects a closure object with a <code>const</code> function call operator, the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>


   <h4>21.11.4.25 LambdaCapture operations<span class="section_name">[reflect.ops.lambdacapture]</span></h4>
   <p class="function">
      <code>
template &lt;LambdaCapture T&gt; struct is_explicitly_captured;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects an explicitly captured entity, the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>

   <p class="function">
      <code>
template &lt;LambdaCapture T&gt; struct is_init_capture;
      </code>
   </p>
   <dl class="attribute">
      <dt></dt>
      <dd>All specializations of this template shall meet the
         <code>UnaryTypeTrait</code> requirements ([meta.rqmts]). If the template parameter reflects an <em>init-capture</em>, the base characteristic of the respective template specialization is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>
</div>



<h2 id="history">Revision history</h2>

<h4>Revision 3 (<a href="http://wg21.link/p0670r3">P0670R3</a>)</h4>

<p>First revision with formal wording.</p>

<h4>Changes first appearing in <a href="http://wg21.link/p0670r4">P0670R4</a></h4>

<p><ul>
   <li>Identified "constructor calls" as <code>FunctionalTypeConversion</code>.</li>
   <li>Introduced <code>ParenthesizedExpression</code> as disambiguation mechanism (type-id vs cast expression).</li>
   <li>Introduced <em>functional-type-conv-expression</em>.</li>
   <li>Objects with function call operator are not <code>Function</code>s anymore.</li>
   <li>Better definition of concepts, enabling subsummation and clarifying that all concepts have only syntactic (i.e. checkable) requirements.</li>
   <li>Specify the odr-rule behavior.</li>
   <li>Specify that lambda captures used as <em>reflexpr-operand</em> are captured.</li>
   <li>Repeated specializations of operations yielding different constant expression results are now ill-formed ndr.</li>
   <li>Specify that <code>get_pointer</code> creates an odr-use.</li>
   <li>Replaced ellipsis <code>FunctionParameter</code> by <code>is_vararg</code> <code>Callable</code> operation.</li>
   <li>Rename <code>has_default_value</code> to <code>has_default_argument</code>.</li>
</ul></p>



<h2 id="references" class="references unnumbered">References</h2>
<div id="ref-p0385">
<p>1. <em>Static reflection. Rationale, design and evolution.</em> <a href="http://wg21.link/p0385">p0385</a></p>
</div>
<div id="ref-p0578">
<p>2. <em>Static reflection in a nutshell.</em> <a href="http://wg21.link/p0578">p0578</a></p>
</div>
</body>
</html>
