<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0670R3, 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>P0670R3</b>, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>CWG, LWG</td></tr>
   <tr><td>Date:</td><td>2018-05-07</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>
<p>No changes are made to Clause 6 of the Reflection TS.</p>

<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>
<p>No changes are made to Clause 8 of the Reflection TS.</p>

<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>function call expression</ins><br/>
      </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><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>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 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>.
<ins>
For an operand that can be parsed as a function call expression [expr.call], the type satisfies <code>reflect::FunctionCallExpression</code>.
</ins>
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 not captured or 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 variable <del>or </del>a data member, <ins>a function parameter, or a captured entity,</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>.
   <ins>If the overload resolution of the function call expression is ambiguous, the programm is ill-formed.</ins>
</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>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;
template &lt;class T&gt; concept Named;
template &lt;class T&gt; concept Alias;
template &lt;class T&gt; concept RecordMember;
template &lt;class T&gt; concept Enumerator;
template &lt;class T&gt; concept Variable;
template &lt;class T&gt; concept ScopeMember;
template &lt;class T&gt; concept Typed;
template &lt;class T&gt; concept Namespace;
template &lt;class T&gt; concept GlobalScope;
template &lt;class T&gt; concept Class;
template &lt;class T&gt; concept Enum;
template &lt;class T&gt; concept Record;
template &lt;class T&gt; concept Scope;
template &lt;class T&gt; concept Type;
template &lt;class T&gt; concept Constant;
template &lt;class T&gt; concept Base;
<ins>template &lt;class T&gt; concept FunctionParameter;
template &lt;class T&gt; concept Callable;
template &lt;class T&gt; concept FunctionCallExpression;
template &lt;class T&gt; concept Function;
template &lt;class T&gt; concept RecordMemberFunction;
template &lt;class T&gt; concept SpecialMemberFunction;
template &lt;class T&gt; concept Constructor;
template &lt;class T&gt; concept Destructor;
template &lt;class T&gt; concept ConversionOperator;
template &lt;class T&gt; concept Lambda;
template &lt;class T&gt; concept LambdaCapture;</ins>
</code></pre></div>
...
<div class="std">
<pre><code>
// 21.11.4 Meta-object operations
// 21.11.4.1 Multi-concept operations
template &lt;class T&gt; struct is_public;
template &lt;class T&gt; struct is_protected;
template &lt;class T&gt; struct is_private;
<ins>template &lt;class T&gt; struct is_constexpr;
template &lt;class T&gt; struct is_static;
template &lt;class T&gt; struct is_final;
template &lt;class T&gt; struct get_pointer;
template &lt;class T&gt; struct is_explicit;
template &lt;class T&gt; struct is_inline;
template &lt;class T&gt; struct is_virtual;
template &lt;class T&gt; struct is_pure_virtual;</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 get_pointer_v = get_pointer&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;</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_destructors;
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_destructors_t = typename get_destructors&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 is_ellipsis;
template &lt;FunctionParameter T&gt; struct has_default_value;

template &lt;FunctionParameter T&gt;
  constexpr auto is_ellipsis_v = is_ellipsis&lt;T&gt;::value;
template &lt;FunctionParameter T&gt;
  constexpr auto has_default_value_v = has_default_value&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_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_deleted_v = is_deleted&lt;T&gt;::value;

// 21.11.4.15 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.16 Function operations
template &lt;Function T&gt; struct get_pointer&lt;T&gt;;

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

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

// 21.11.4.18 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.19 Constructor operations
template &lt;Constructor T&gt; struct is_explicit&lt;T&gt;;

// 21.11.4.20 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.21 ConversionOperator operations
template &lt;ConversionOperator T&gt; struct is_explicit&lt;T&gt;;

// 21.11.4.22 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.23 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>
<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 = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>FunctionParameter&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a function patameter. Any such <code>T</code> also satisfies <code>Named</code> and <code>ScopeMember</code>. The <code>Scope</code> of a <code>FunctionParameter</code> is the <code>Callable</code> this parameter appertains to.</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 = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Callable&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a function including operators, constructors and destructors, or an object with a call operator, for instance a closure type. Any such <code>T</code> also satisfies <code>Named</code>, <code>ScopeMember</code> and <code>Scope</code>.</dd>
</dl>

<h4>21.11.3.21 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 = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>FunctionCallExpression&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a function call expression [expr.call]. Any such <code>T</code> also satisfies <code>Object</code>.</dd>
</dl>

<h4>21.11.3.22 Concept <code>Function</code><span class="section_name">[reflect.concepts.fct]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Function = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Function&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects an object with a call operator (for instance a closure object) or a function, excluding constructors and destructors. Any such <code>T</code> also satisfies <code>Callable</code> and <code>Typed</code>.</dd>
</dl>

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

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

<h4>21.11.3.25 Concept <code>Constructor</code><span class="section_name">[reflect.concepts.ctor]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Constructor = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Constructor&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a constructor. Any such <code>T</code> also satisfies <code>Callable</code> and <code>RecordMember</code>. Some specializations of <code>Constructor</code> satisfy <code>SpecialMemberFunction</code>.</dd>
</dl>

<h4>21.11.3.26 Concept <code>Destructor</code><span class="section_name">[reflect.concepts.dtor]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Destructor = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Destructor&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a destructor. Any such <code>T</code> also satisfies <code>Callable</code>, <code>SpecialMemberFunction</code> and <code>RecordMember</code>.</dd>
</dl>

<h4>21.11.3.27 Concept <code>Operator</code><span class="section_name">[reflect.concepts.oper]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Operator = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Operator&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects an operator function [over.oper] or a conversion function [class.conv.fct]. Any such <code>T</code> also satisfies <code>Function</code>. Some specializations of <code>Operator</code> satisfy <code>RecordMemberFunction</code> or <code>SpecialMemberFunction</code>.</dd>
</dl>

<h4>21.11.3.28 Concept <code>ConversionOperator</code><span class="section_name">[reflect.concepts.convfct]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept ConversionOperator = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>ConversionOperator&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a conversion function [class.conv.fct]. Any such <code>T</code> also satisfies <code>Function</code>. Some specializations of <code>Operator</code> satisfy <code>RecordMemberFunction</code>.</dd>
</dl>

<h4>21.11.3.29 Concept <code>Lambda</code><span class="section_name">[reflect.concepts.lambda]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept Lambda = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>Lambda&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects an closure object (excluding generic lambdas). Any such <code>T</code> also satisfies <code>Function</code>.</dd>
</dl>

<h4>21.11.3.30 Concept <code>LambdaCapture</code><span class="section_name">[reflect.concepts.lambdacapture]</span></h4>
<p class="function">
<code>
template &lt;class T&gt; concept LambdaCapture = <em>see below</em>;
</code></p>
<dl class="attribute">
<dt></dt>
<dd><code>LambdaCapture&lt;T&gt;</code> is satisfied if and only if <code>T</code> reflects a lambda capture as introduced by the capture list or by capture defaults. Any such <code>T</code> also satisfies <code>Variable</code>. The <code>Scope</code> of a <code>LambdaCapture</code> is its <code>Lambda</code>.</dd>
</dl>
</div>


<h4>21.11.4 Meta-object Operations <span class="section_name">[reflect.ops]</span></h4>
<h4>21.11.4.1 Multi-concept operations <span class="section_name">[reflect.ops.over]</span></h4>
<p>Modify [reflect.ops.over] as follows:</p>
<div class="std">
<p class="function">
<code>
template &lt;class T&gt; struct is_public;<br/>
template &lt;class T&gt; struct is_protected;<br/>
template &lt;class T&gt; struct is_private;<br/>
<ins>template &lt;class T&gt; struct is_constexpr;<br/>
template &lt;class T&gt; struct is_static;<br/>
template &lt;class T&gt; struct is_final;<br/>
template &lt;class T&gt; struct get_pointer;<br/>
template &lt;class T&gt; struct is_explicit;<br/>
template &lt;class T&gt; struct is_inline;<br/>
template &lt;class T&gt; struct is_virtual;<br/>
template &lt;class T&gt; struct is_pure_virtual;</ins>
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>These meta-object operations are applicable to <del>to both <code>RecordMember</code> and <code>Base</code></del><ins>more than one of the concepts defined in the <code>reflect</code> namespace.</ins>
</dd></dl>
</div>

<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>

<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, or closure 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 <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) </ins>members.</li>
   <li>for <code>get_public_data_members</code><ins> (<code>get_public_member_functions</code>)</ins>, all public data <ins>(function) </ins>members;</li>
  <li>for <code>get_accessible_data_members</code><ins> (<code>get_accessible_member_functions</code>)</ins>, all data <ins>(function) </ins>members that are accessible from the scope of the invocation of <code>reflexpr</code> which (directly or indirectly) generated <code>T</code>.</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_destructors;<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_destructors</code>, all destructors;</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>
</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 is_ellipsis;<br/>
      </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 terminating ellipsis of a function's
         <em>parameter-declaration-clause</em> [dcl.fct], the base characteristic of
         <code>is_ellipsis&lt;T&gt;</code> is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </dd>
   </dl>

   <p class="function">
      <code>
template &lt;FunctionParameter T&gt; struct has_default_value;
      </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>is_enum&lt;T&gt;</code> (
         <code>is_union&lt;T&gt;</code>) is
         <code>true_type</code>, otherwise it is
         <code>false_type</code>.
      </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> contains an additional, final element of type <code>ELL</code> for which <code>is_ellipsis_v&lt;ELL&gt;</code> is <code>true</code>. 
      </dd>
   </dl>

   <p class="function">
      <code>
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 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>
   </dl>


   <h4>21.11.4.15 FunctionCallExpression operations<span class="section_name">[reflect.ops.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 or callable object invoked by the function call expression which is reflected by <code>T</code>. 
      </dd>
   </dl>


   <h4>21.11.4.16 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; otheriwse,</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.17 RecordMemberFunction operations<span class="section_name">[reflect.ops.memfct]</span></h4>
   <p class="function">
      <code>
template &lt;RecordMemberFunction T&gt; struct is_static&lt;T&gt;;<br/>
template &lt;RecordMemberFunction T&gt; struct is_const;<br/>
template &lt;RecordMemberFunction T&gt; struct is_volatile;<br/>
template &lt;RecordMemberFunction T&gt; struct has_lvalueref_qualifier;<br/>
template &lt;RecordMemberFunction T&gt; struct has_rvalueref_qualifier;<br/>
template &lt;RecordMemberFunction T&gt; struct is_virtual&lt;T&gt;;<br/>
template &lt;RecordMemberFunction T&gt; struct is_pure_virtual&lt;T&gt;;<br/>
template &lt;RecordMemberFunction T&gt; struct is_override;<br/>
template &lt;RecordMemberFunction 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.18 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 (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.19 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.20 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.21 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.22 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>.
      </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> 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.23 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="design">Concepts and Operations</h2>

<p>Following P0194's lead, function reflection requires a couple new concepts to restrict operations on the meta level. It builds upon the concepts introduced by P0194 and, like P0194, all declarations are inside the <code>reflect</code> namespace.

Some of the concepts below extend P0194's concepts. Whenever a concept A requires another concept B, the operations defined for concept B are also available for concept A, building a graph similar to an inheritance graph.</p>
<p>Proper wording will be provided when needed (and when P0194 has progressed through LWG, increasing to the authors' experience on wording of reflection papers); we believe that missing wording should not hinder SG7's design discussion. The wording is planned to be similar to that of P0194; specifically, it uses nested <code>type</code> and <code>value</code> entities, with the usual using declarations <code>..._t</code> and <code>..._v</code>.</p>

<h3>Extending operands of <code>reflexpr</code></h3>
<p>P0194 allows certain types and variables as operands of <code>reflexpr</code>. This paper extends this set:</p>
<ul>
  <li>invoking <code>reflexpr</code> on a function call expression generates a <code>FunctionCallExpression</code>;</li>
  <li>invoking <code>reflexpr</code> on a closure object generates a <code>Lambda</code>;</li>
  <li>invoking <code>reflexpr</code> on a parameter name generates a <code>FunctionParameter</code>;</li>
  <li>invoking <code>reflexpr</code> on a lambda capture generates a <code>LambdaCapture</code>;</li>
</ul>
<p>

The way to obtain a <code>Callable</code> might seem complicated. But instead of inventing a new syntax, for instance <code>reflexpr(foo(int,int))</code>, re-using the mechanism of matching the address of an overloaded function name <code>reflexpr((void(&amp;)(int, int))foo)</code>, or syntax similar to function definition <code>reflexpr(void foo(int,int))</code>, we rely on the existing, familiar rules for function overload resolution and generate the <code>Callable</code> only when a concrete overload is selected. This approach also works for constructors and operators, for instance <code>reflexpr(std::string())</code> reflects the call of the default constructor of <code>string</code>; <code>reflexpr(1+1)</code> reflects the call of the built-in addition operator for type <code>int</code>.
</p>


<!--
	 - FunctionParameter
  -->
<h3><code>FunctionParameter</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept FunctionParameter = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Named</code> and <code>ScopeMember</code>. Represents a function parameter. Unlike <code>Variable</code>, it does not offer a <code>get_pointer</code> interface. The name of a parameter is one of the names used in an unspecified declaration. If at least one of the declarations does not specify the parameter name, then <code>get_name</code> is allowed to return an empty string. Its scope is the <code>Callable</code> declaring this <code>FunctionParameter</code>.</dd>
<dt></dt>
<dd>Given the lack of relevance that C++ attributes to parameter names in function declarations one might ask: "o really?!" We believe that the answer is "yes": parameter names often carry significant meaning. Examples:
  <pre>
  <code>
    double Gauss(double x, double mean, double width, double height);

    void f() {
      // Don't confuse those!
      func(true /*willLeave*/,
           false /*knewWhatTheyVotedOn*/,
           false /*willBeHappyEverAfter*/);
    }
  </code>
  </pre>
  The bare combination of type and index is almost meaningless in these cases. There are many reflection applications that can benefit from this, for instance:
  <ul>
    <li>remote procedure calls identifying parameters by name;</li>
    <li>code exposing C++ functions to scripting frameworks;</li>
    <li>GUI generation, converting parameter names to text box labels;</li>
    <li>documentation generation, referencing function parameters in a meaningful way.</li>
  </ul>
  To put it differently: functions without parameter names are like classes without member names. And <code>tuple</code> is not a replacement for classes.</dd>
<dt></dt>
<dd>Another common objection is that multiple declarations could potentially
     have different parameter names ascribed. This concern is mitigated in two
     ways:

     <ol><li>Modern coding conventions have the declarations for a particular
        function showing up in exactly one header file.</li>
     <li>Modern coding conventions discourage the use of different argument
        names between function declarations (in a header) and function
        definitions (in a '.cpp' file). Dedicated compiler warnings exist to
        protecte against this case.</li>
     </ol>
</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires FunctionParameter&lt;T&gt;<br>
struct is_ellipsis;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Indicates that a <code>FunctionParameter</code> reflects an ellipsis.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires FunctionParameter&lt;T&gt;<br>
struct has_default_value;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Indicates that a <code>FunctionParameter</code> has a default value.</dd>
</dl>

<!--
	 - Callable
  -->
<h3><code>Callable</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Callable = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Named</code>, <code>ScopeMember</code> and <code>Scope</code>. Represents a function or lambda, including operators, constructors and destructors - i.e. anything this paper is dealing with.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct get_parameters;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of <code>FunctionParameter</code>s of the reflected <code>Callable</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_constexpr;<br>
<br>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_noexcept;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function was declared as <code>constexpr</code> or <code>noexcept</code>, respectively.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_inline;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is an inline function. With <code>struct X{ inline void f(); void g() {} }</code>, <code>is_inline</code> is <code>true</code> for both <code>f</code> and <code>g</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Callable&lt;T&gt;<br>
struct is_deleted;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function was defined as <code>= delete</code> before the invocation of <code>reflexpr</code>.</dd>
</dl>


<h3><code>FunctionCallExpression</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept FunctionCallExpression = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Object</code>. Reflects a call of a concrete function or other callable.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires FunctionCallExpression&lt;T&gt;<br>
struct get_callable;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns the <code>Callable</code> that was invoked in a <code>FunctionCallExpression</code>.</dd>
</dl>


<!--
	 - Function
  -->
<h3><code>Function</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Function = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Callable</code> and <code>Typed</code>. Represents a function or lambda, excluding constructors and destructors.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Function&lt;T&gt;<br>
struct get_pointer;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns a pointer to the function. This is a pointer-to-member for non-static member functions (including lambda calls), and a function pointer otherwise. It is ill-formed to invoke this for deleted functions. Example: <code>auto p_sin = get_pointer_v&lt;get_callable_t&lt;reflexpr(sin(1.0))&gt;&gt;</code> holds the address of <code>sin(double)</code>.</dd>
</dl>


<!--
	 - RecordMemberFunction
  -->
<h3><code>RecordMemberFunction</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept RecordMemberFunction = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>RecordMember</code> and <code>Function</code>. Represents a member function, excluding constructors and destructors.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_static;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether this is a static member function.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_const;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_volatile;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as <code>const</code> or <code>volatile</code>, respectively.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct has_lvalueref_qualifier;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct has_rvalueref_qualifier;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as with a <em>ref-qualifier</em> being <code>&amp;</code> or <code>&amp;&amp;</code>, respectively.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_virtual;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_pure_virtual;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is a virtual or pure virtual function, respectively. For
<pre>
  <code>
    struct A { virtual void X(); };
    struct B: A { void X(); };
  </code>
</pre>
the value of <code>is_virtual_v&lt;get_callable_t&lt;reflexpr(std::declval&lt;B&gt;().X())&gt;&gt;</code> is <code>true</code>, irrespectively of whether <code>virtual</code> is implicit of explicit.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_override;<br><br>

template &lt;typename T&gt;<br>
requires RecordMemberFunction&lt;T&gt;<br>
struct is_final;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as <code>override</code> or <code>final</code>, respectively.</dd>
</dl>


<!--
	 - SpecialMemberFunction
  -->
<h3><code>SpecialMemberFunction</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept SpecialMemberFunction = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>RecordMember</code>. Represents a special member function.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires SpecialMemberFunction&lt;T&gt;<br>
struct is_implicitly_declared;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the special member function is known to be implicitly declared at the point of invocation of <code>reflexpr</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires SpecialMemberFunction&lt;T&gt;<br>
struct is_defaulted;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is defined as <code>= default</code> before the invocation of <code>reflexpr</code>, independently of whether the special member function is implicitly or explicitly declared.</dd>
</dl>



<h3><code>Constructor</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Constructor = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Callable</code> and <code>RecordMember</code>. Represents a constructor. The base name of the constructor is the base name of the constructor's class. Even though the standard explicitly says that constructors do not have a name, for usability purposes (e.g. generating messages), having them state the class name is a usability improvement.</dd>
<dt></dt>
<dd>Some instances of <code>Constructor</code> might also satisfy <code>SpecialMemberFunction</code>.</dd>
</dl>

<h4>Operations</h4>


<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Constructor&lt;T&gt;<br>
struct is_explicit;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the constructor is known to be declared as <code>explicit</code>.</dd>
</dl>




<h3><code>Destructor</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Destructor = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Callable</code>, <code>SpecialMemberFunction</code> and <code>RecordMember</code>. Represents a destructor. The base name is the base name if the destructor's class, prefixed with <code>'~'</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Destructor&lt;T&gt;<br>
struct is_virtual;<br><br>

template &lt;typename T&gt;<br>
requires Destructor&lt;T&gt;<br>
struct is_pure_virtual;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the destructor is a virtual or pure virtual function, respectively. For
<pre>
  <code>
    struct A { virtual ~A(); };
    struct B: A { B(); };
  </code>
</pre>
the value of <code>is_virtual_v&lt;get_callable_t&lt;reflexpr(std::declval&lt;B&gt;.~B())&gt;&gt;</code> is <code>true</code>, irrespectively of whether <code>virtual</code> is implicit of explicit.</dd>
</dl>





<h3><code>Operator</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Operator = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Function</code>. Some instances might implement <code>RecordMemberFunction</code> or <code>SpecialMemberFunction</code>. Represents an operator. The base name is the operator "symbol", for instance <code>"+"</code>.</dd>
</dl>






<h3><code>ConversionOperator</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept ConversionOperator = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Operator</code>. Represents a conversion operator. The base name is the base name of the operator's target type, for instance <code>"int"</code>.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires ConversionOperator&lt;T&gt;<br>
struct is_explicit;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the function is declared as <code>explicit</code>.</dd>
</dl>







<h3><code>Lambda</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept Lambda = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Function</code>. Represents a closure type, excluding those for generic lambdas. Its base name is the empty string.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct get_captures;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of <code>LambdaCapture</code>s.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct uses_default_copy_capture;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the <em>capture-default</em> is <code>=</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct uses_default_reference_capture;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the <em>capture-default</em> is <code>&amp;</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Lambda&lt;T&gt;<br>
struct is_call_operator_const;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns <code>false</code> if the lambda was declared as <code>mutable</code>, <code>true otherwise</code>.</dd>
</dl>



<h3><code>LambdaCapture</code></h3>
<p class="function">
<code>
template &lt;class Object&gt; concept LambdaCapture = /* implementation defined */;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Requires <code>Variable</code>. Represents a lambda capture as introduced by the capture list or by capture defaults. The <code>LambdaCapture</code>'s scope is its <code>Lambda</code>.</dd>
</dl>

<h4>Operations</h4>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires LambdaCapture&lt;T&gt;<br>
struct is_explicitly_captured;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the entity was captured explicitly.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires LambdaCapture&lt;T&gt;<br>
struct is_init_capture;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns whether the entity is an <em>init-capture</em>.</dd>
</dl>




<h3>Extending <code>Record</code></h3>
<p>This proposal adds the following interfaces to the <code>Record</code> concept of P0194:</p>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_public_member_functions;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_accessible_member_functions;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_member_functions;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of <code>RecordMemberFunctions</code>s representing a class's public member functions (for <code>get_public_member_functions</code>), member functions accessible from the point of invocation of <code>reflexpr</code> (for <code>get_accessible_member_functions</code>) and all member functions, irrespective of their accessibility (for <code>get_member_functions</code>). This includes <em>static</em> member functions, but not <em>friend</em> functions.</dd>
</dl>

<p class="function">
<code>
template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_constructors;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_destructors;<br><br>

template &lt;typename T&gt;<br>
requires Record&lt;T&gt;<br>
struct get_operators;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>Returns an <code>ObjectSequence</code> of a class's <code>Constructor</code>s, <code>Destructor</code>s and <code>Operator</code>s, respectively.</dd>
</dl>



<!--h2 id="proposed-wording">Proposed wording</h2-->

<h2 id="acknowledgments">Acknowledgments</h2>
<p>Thanks to Jackie Kay who provided valuable feedback, criticism and suggestions!</p>



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

<h4>Revision 1 (<a href="http://wg21.link/N3996">N3996</a>)</h4>

<p>Describes the method of static reflection
by means of compiler-generated anonymous types. Introduces the first version
of the metaobject concepts and some possibilities of their implementation.
Also includes discussion about the motivation and the design rationale for the proposal.
</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>
