<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="author" content="P0088R3, 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; }
ins { text-decoration: none;
    border-bottom: 1px solid #005100;
    color: #005100;
    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; }

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: #C8FFC8;
  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;  }
</style>

<title>Static reflection</title>
</head>

<body>
<table class="header">
    <tr><td>Document Number:</td> <td><b>P0194R3</b>, ISO/IEC JTC1 SC22 WG21</td></tr>
  <tr><td>Audience:</td><td>EWG, LEWG</td></tr>
    <tr><td>Date:</td><td>2017-02-06</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 (dsankel@bloomberg.net)</td></tr>
</table>
<h1>Static 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="#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>
-->

<h2 id="introduction">Introduction</h2>
<p>This paper proposes to add support for compile-time reflection to standard C++. We propose that the compiler shall generate meta-objects &mdash; representations of certain program declarations, which can be reasoned-about at compile time. These meta-objects can then be used, through a set of operations to obtain various pieces of metadata, like declaration names, lists of scope members, information about specifiers, and so on. The meta-objects are implemented as anonymous types conforming to defined concepts, and the operations are implemented as class templates.</p>

<p>This paper is accompanied by two more papers &mdash; <a href="http://wg21.link/p0385">p0385</a>, which discusses the use cases, rationale, design decisions, future evolution of the proposed reflection facility and contains multiple examples of use and replies to frequently asked questions; and <a href="http://wg21.link/p0578">p0578</a> which gives a concise introduction to the feature set presented here.</p>
  
<p>Reflection proposed here behaves as follows:</p>
<pre><code>
enum E0194 { kFirst, kSecond };
using E0194_m = $reflect(E0194);
using kFirst_m = get_element_t&lt;0, get_enumerators_t&lt;E0194_m&gt;&gt;;
cout &lt;&lt; get_base_name_v&lt;kFirst_m&gt; &lt;&lt; '\n'; // prints "kFirst"
</code></pre>

  
<h2 id="other-proposals">Interplay with other proposals</h2>
<p>This proposal relies on the Concepts TS, including a resolution to its <a href="http://cplusplus.github.io/concepts-ts/ts-active.html#29">Issue 29</a>. It also assumes that WG21 will incorporate proper compile-time strings; until then, this proposal provides a placeholder implementation (see [reflect.ops.named]) to facilitate reasoning about the interfaces.</p>


<h2 id="proposed-wording">Proposed wording</h2>
  <p>The wording is assumed to provide the working paper for a new Technical Specification. Grayish background indicates proposed wording.</p>
  <p>This paper does not propose a feature-test macro as it provides a new header that can be tested against.</p>
  
<blockquote class="std">
<h3 id="compile-time-reflection">1 General <span class="section_name">[intro]</span></h3>
<h4>1.1 Scope <span class="section_name">[intro.scope]</span></h4>
  <p>This specification describes extensions to the C++ Programming Language as specified by the International Standard, ISO/IEC 14882. These extensions permit operations on source code. They include changes and additions to the existing library facilities as well as the extension of one core language facility.</p>
  
  <p>This specification requires the availability of ISO/IEC TS 19217:2015, <em>Programming Languages - C++ Extensions for Concepts Concepts</em> as a prerequisite.</p>

<h4>1.2 References <span class="section_name">[intro.refs]</span></h4>
<p>The following referenced documents are indispensable for the application of this document.</p>
<ul>
<li>ISO/IEC 14882:2014, <em>Programming Languages - C++</em>, referenced as (C++ [section])</li>
<li>ISO/IEC TS 19217:2015, <em>Programming Languages - C++ Extensions for Concepts</em>, referenced as (Concepts-TS [section]).</li>
</ul>

<h4>1.3 Namespaces and headers <span class="section_name">[intro.namespaces]</span></h4>
  <p>All components described here are declared in namespace <code>std::experimental::reflect::v1</code> unless otherwise specified. The header described in this specification shall import the contents of <code>std::experimental::reflect::v1</code> into <code>std::experimental::reflect</code> as if by:</p>
<pre><code>
namespace std::experimental::reflect {
  inline namespace v1 {}
}
</code></pre>
<p>Unless otherwise specified, references to other entities described here are assumed to be qualified with <code>std::experimental::reflect::v1::</code>, references to entities described in the C++ standard are assumed to be qualified with <code>std::</code>.</p>
<!-- <p>New headers are provided in the <code>&lt;experimental/meta/&gt;</code> directory.</p> -->
  
<table>
  <caption>Table 1 &mdash; Reflection library headers</caption>
  <tr><td>&lt;experimental/reflect&gt;</td></tr>
</table>

<h3>2 Lexical conventions <span class="section_name">[lex]</span></h3>
  
<h4>2.1 General <span class="section_name">[lex.general]</span></h4>
<p>This specification introduces the first steps of a new expression syntax to operate on the meta-level of C++. To clearly state this level of code, the new character <code>$</code> is preceding keywords belonging to the meta level.</p>

<h4>2.2 Character sets <span class="section_name">[lex.charset]</span></h4>
<p>In addition to the characters specified by (C++ [lex.general]), this specification adds <code>$</code> to the <em>basic source character set</em> as the 93rd graphical character.
  
<h4>2.3 Keywords <span class="section_name">[lex.key]</span></h4>
<p>In addition to the keywords specified by (C++ [lex.key]), as laid out in its Table 5, this specification adds <code>$reflect</code> to the set of keywords.</p>

<h3>3 Basic concepts <span class="section_name">[basic]</span></h3>
<h4>3.1 Fundamental types <span class="section_name">[basic.fundamental]</span></h4>
<p>In addition to (C++ [basic.fundamental]), an expression of type <em>cv</em> void can be used also as the operand of <code>$reflect</code>.</p>

<h3>4 Reflection operator <span class="section_name">[reflect-op]</span></h3>
<p>The result of the invocation of the <code>$reflect</code> trait (or template-level "operator") is a type satisfying <code>reflect::Object</code> and other <code>meta</code> concepts, depending on the operand. The returned type is implementation-defined. Meta-operations on it describe the operand, or the most recent redeclaration for operands that are declarations.</p>
<p>The $reflect operator takes an <em>id-expression</em> (C++ [expr.prim.id]) as operand, or <code>::</code>. The <em>id-expression</em> is understood as if used outside of the $reflect operator at the point of invocation of the <code>$reflect</code> operator; see also (C++ [stmt.ambig]). The program is ill-formed if the use of the operand as an existing name were ill-formed at the point of invocation of the <code>$reflect</code> operator.</p>
<p>The <em>id-expression</em> operand of the <code>$reflect</code> operator is an unevaluated operand (C++ [expr]).</p>
<p>If the <em>id-expression</em> operand of the <code>$reflect</code> operator is declared inside a function body, the program is ill-formed.</p>
<p>The resulting type of the <code>$reflect</code> operator reflects (describes) the operand.
Depending on the operand, the resulting type satisfies the following concept requirements (see Concepts-TS):</p>
<ul>
<li>If the operand of <code>$reflect</code> is <code>::</code>, then the result will be satisfying <code>reflect::GlobalScope</code> and will reflect the global scope.</li>
<li>Otherwise, the kind of <em>id-expression</em> is matched against the first column of Table 2, row by row, until the first match is found; the second column determines the Concept which the result will be satisfying.</li>
<li>The invocation of <code>$reflect</code> on any other kind of id-expression is ill-formed.</li>
</ul>

<table class="withBorder">
<caption>Table 2 &mdash; <code>meta</code> Concept satisfied by result of <code>$reflect</code> operation when invoked on <em>id-expression</em> kind</caption>
<thead><tr><th><em>id-expression</em> kind</th><th><code>meta</code> Concept</th></tr></thead>
<tbody>
<tr><td><em>union-name</em></td><td><code>reflect::Record</code></td></tr>
<tr><td><em>class-name</em></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>decltype-specifier</em></td><td>both <code>reflect::Type</code> and <code>reflect::Alias</code></td></tr>
<tr><td><em>typedef-name</em></td><td>both <code>reflect::Type</code> and <code>reflect::Alias</code></td></tr>
<tr><td>template <em>type-parameter</em></td><td>both <code>reflect::Type</code> and <code>reflect::Alias</code></td></tr>
<tr><td>a name introduced by a <em>using-declaration</em> or <em>using-directive</em></td><td>both <code>reflect::Type</code> and <code>reflect::Alias</code></td></tr>
<tr><td><em>type-name</em></td><td><code>reflect::Type</code></td></tr>
<tr><td><em>namespace-name</em></td><td><code>reflect::Namespace</code></td></tr>
<tr><td><em>namespace-alias</em></td><td>both <code>reflect::Namespace</code> and <code>reflect::Alias</code></td></tr>
<tr><td><em>class-data-member-name</em></td><td><code>reflect::Variable</code></td></tr>
<tr><td><em>variable-name</em></td><td><code>reflect::Variable</code></td></tr>
<tr><td><em>enumerator-name</em></td><td><code>reflect::Constant</code></td></tr>
</tbody>
</table>

<p>If the scope of the declaration of the <em>id-expression</em> is a class type, then the result of <code>$reflect</code> is also satisfying <code>reflect::RecordMember</code>.</p>

<p>If the scope of the declaration of the <em>id-expression</em> is an enum, then the result of <code>$reflect</code> is also satisfying <code>reflect::Enumerator</code>.</p>

<p>If the operand is a dependent name or type, <code>$reflect</code> is not evaluated. On such operands, evaluation is performed once the template is specialized and the dependent name or type is resolved.</p>

<h3>5 Library introduction<span class="section_name">[reflect]</span></h3>

<h4>5.1 In general<span class="section_name">[reflect.general]</span></h4>

<p>Compile-time constant metadata describing various aspects of a compiled program are provided indirectly by the means of types generated by the compiler &mdash; meta-objects. A meta-object is an anonymous type <em>reflecting</em> (representing) a particular declaration or another entity in a C++ program, while a <em>base-level</em> entity refers to code that is reflected by a meta-object. A meta-object can be reasoned-about at compile-time and provides access to metadata describing various properties of the reflected entity through a set of templates. The meta-object types themselves are unspecified except that they are <em>trivial classes</em> (C++ [class]).</p>

<p>[<em>Example:</em> With
<pre><code>
using int_m = $reflect(int);
</code></pre>
<code>int_m</code> is the meta-object reflecting the base-level entity <code>int</code>. <em>&mdash; end example</em>]</p>

<p>The actual metadata is obtained by instantiating templates constituting the interface of the meta-objects. These templates are collectively referred to as <em>meta-object operations</em>.</p>

<p>meta-objects reflecting different kinds of declarations conform to different meta-object concepts and have different interfaces &mdash; sets of templates applicable to the meta-objects. These concepts can also be used for meta-object classification.</p>

<p>meta-object concepts form a generalization-specialization hierarchy, with <code>reflect::Object</code> being the common generalization for all meta-objects.</p>

  
<!--
<h3>2 meta-object trait <span class="section_name">[trait]</span></h3>
<p>This section conceptually adds a new trait to [reflect.unary.cat], to distinguish between <em>meta-object</em> types generated by the compiler and all other types.</p>
  <p>Header &lt;experimental/ranges/type_traits&gt; synopsis</p>
  
<pre><code>
namespace std {
namespace experimental {

template &lt;class T&gt; struct is_meta-object;
template &lt;class T&gt; constexpr bool is_meta-object_v = is_meta-object&lt;T&gt;::value;

} // namespace experimental
} // namespace std
</code></pre>
-->

  
<!--  
  <p>Insert a new element in <em>Table 14, C++ library headers</em> of [general.namespaces], named <code>&lt;experimental/$reflect&gt;</code>.</p>
  -->
  
  <h4>5.2 Header <code>&lt;experimental/reflect&gt;</code> synopsis <span class="section_name">[reflect.synopsis]</span></h4>
<pre>
<code>

namespace std::experimental::reflect {

// 5.3 Meta-object concepts
template &lt;class T&gt; concept bool Object();
template &lt;class T&gt; concept bool ObjectSequence();
template &lt;Object T&gt; concept bool Named();
template &lt;Object T&gt; concept bool Alias();
template &lt;Object T&gt; concept bool RecordMember();
template &lt;Object T&gt; concept bool Enumerator();
template &lt;Object T&gt; concept bool Variable();
template &lt;Object T&gt; concept bool ScopeMember();
template &lt;Object T&gt; concept bool Typed();
template &lt;Object T&gt; concept bool Namespace();
template &lt;Object T&gt; concept bool GlobalScope();
template &lt;Object T&gt; concept bool Class();
template &lt;Object T&gt; concept bool Enum();
template &lt;Object T&gt; concept bool Record();
template &lt;Object T&gt; concept bool Scope();
template &lt;Object T&gt; concept bool Type();
template &lt;Object T&gt; concept bool Constant();
template &lt;Object T&gt; concept bool Base();


// 5.4 Meta-object operations
// 5.4.2 Overloaded operations
template &lt;class T&gt; is_public;
template &lt;class T&gt; is_protected;
template &lt;class T&gt; is_private;

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;

// 5.4.3 Object operations
template &lt;Object T1, Object T2&gt; struct reflects_same;
template &lt;Object T&gt; struct get_source_location;
template &lt;Object T&gt; struct get_source_line;
template &lt;Object T&gt; struct get_source_column;
template &lt;Object T&gt; struct get_source_file_name;<!--
template &lt;Object T&gt; struct get_source_function_name; unused: no $reflect on decls from function scope -->

template &lt;Object T1, Object T2&gt;
  constexpr auto reflects_same_v = reflects_same&lt;T1, T2&gt;::value;
template &lt;Object T&gt;
  constexpr auto get_source_location_v = get_source_location&lt;T&gt;::value;
template &lt;Object T&gt;
  constexpr auto get_source_line_v = get_source_line&lt;T&gt;::value;
template &lt;Object T&gt;
  constexpr auto get_source_column_v = get_source_column&lt;T&gt;::value;
template &lt;Object T&gt;
  constexpr auto get_source_file_name_v = get_source_file_name&lt;T&gt;::value;<!--
template &lt;Object T&gt;
  constexpr auto get_source_function_name_v = get_source_function_name&lt;T&gt;::value; -->

// 5.4.4 ObjectSequence operations
template &lt;ObjectSequence S&gt; struct get_size;
template &lt;size_t I, ObjectSequence S&gt; struct get_element;
template &lt;template &lt;class...&gt; class Tpl, ObjectSequence S&gt;
  struct unpack_sequence;

template &lt;ObjectSequence T&gt;
  constexpr auto get_size_v = get_size&lt;T&gt;::value;
template &lt;size_t I, ObjectSequence S&gt;
  using get_element_t = typename get&lt;I, S&gt;::type;
template &lt;template &lt;class...&gt; class Tpl, ObjectSequence S&gt;
  constexpr auto unpack_sequence_v = unpack_sequence&lt;Tpl, S&gt;::value;

// 5.4.5 Named operations
template &lt;Named T&gt; struct is_anonymous;
template &lt;Named T&gt; struct get_base_name;
template &lt;Named T&gt; struct get_display_name;

template &lt;Named T&gt;
  constexpr auto is_anonymous_v = is_anonymous&lt;T&gt;::value;
template &lt;Named T&gt;
  constexpr auto get_base_name_v = get_base_name&lt;T&gt;::value;
template &lt;Named T&gt;
  constexpr auto get_display_name_v = get_display_name&lt;T&gt;::value;

// 5.4.6 Alias operations
template &lt;Alias T&gt; struct get_aliased;

template &lt;Alias T&gt;
  using get_aliased_t = typename get_aliased&lt;T&gt;::type;

// 5.4.7 Type operations
template &lt;Typed T&gt; struct get_type;
template &lt;Type T&gt; struct get_reflected_type;
template &lt;Type T&gt; struct is_enum;
template &lt;Type T&gt; struct is_class;
template &lt;Type T&gt; struct is_struct;
template &lt;Type T&gt; struct is_union;

template &lt;Typed T&gt;
  using get_type_t = typename get_type&lt;T&gt;::type;
template &lt;Type T&gt;
  using get_reflected_type_t = typename get_reflected_type&lt;T&gt;::type;
template &lt;Type T&gt;
  constexpr auto is_enum_v = is_enum&lt;T&gt;::value;
template &lt;Type T&gt;
  constexpr auto is_class_v = is_class&lt;T&gt;::value;
template &lt;Type T&gt;
  constexpr auto is_struct_v = is_struct&lt;T&gt;::value;
template &lt;Type T&gt;
  constexpr auto is_union_v = is_union&lt;T&gt;::value;

// 5.4.8 Member operations
template &lt;ScopeMember T&gt; struct get_scope;
template &lt;RecordMember T&gt; struct is_public&lt;T&gt;;
template &lt;RecordMember T&gt; struct is_protected&lt;T&gt;;
template &lt;RecordMember T&gt; struct is_private&lt;T&gt;;

template &lt;ScopeMember T&gt;
  using get_scope_t = typename get_scope&lt;T&gt;::type;

// 5.4.9 Record and Enum 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;
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;
template &lt;Class T&gt; struct get_public_bases;
template &lt;Class T&gt; struct get_accessible_bases;
template &lt;Class T&gt; struct get_bases;
template &lt;Class T&gt; struct is_final;
template &lt;Enum T&gt; struct is_scoped_enum;
template &lt;Enum T&gt; struct get_enumerators;

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;
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;
template &lt;Class T&gt;
  using get_public_bases_t = typename get_public_bases&lt;T&gt;::type;
template &lt;Class T&gt;
  using get_accessible_bases_t = typename get_accessible_bases&lt;T&gt;::type;
template &lt;Class T&gt;
  using get_bases_t = typename get_bases&lt;T&gt;::type;
template &lt;Class T&gt;
  constexpr auto is_final_v = is_final&lt;T&gt;::value;
template &lt;Enum T&gt;
  constexpr auto is_scoped_enum_v = is_scoped_enum&lt;T&gt;::value;
template &lt;Enum T&gt;
  using get_enumerators_t = typename get_enumerators&lt;T&gt;::type;


// 5.4.10 Value operations
template &lt;Constant T&gt; struct get_constant;
template &lt;Variable T&gt; struct is_constexpr;
template &lt;Variable T&gt; struct is_static;
template &lt;Variable T&gt; struct get_pointer;

template &lt;Constant T&gt;
  constexpr auto get_constant_v = get_constant&lt;T&gt;::value;
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;

// 5.4.11 Base operations
template &lt;Base T&gt; struct get_class;
template &lt;Base T&gt; struct is_virtual;
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;
template &lt;Base T&gt;
  constexpr auto is_virtual_v = is_virtual&lt;T&gt;::value;

// 5.4.12 Namespace operations
template &lt;Namespace T&gt; struct is_inline;

template &lt;Namespace T&gt;
  constexpr auto is_inline_v = is_inline&lt;T&gt;::value;

} // namespace std::experimental::reflect
</code>
</pre>

  
<h4>5.3 Meta-object concepts <span class="section_name">[reflect.concepts]</span></h4>

<h4>5.3.1 In General <span class="section_name">[reflect.concepts.intro]</span></h4>
<p>Available operations on meta-objects are specified by function concepts (Concepts-TS [dcl.spec.concept]). These concepts are also used to specify the result type for <em>TransformationTrait</em>-style meta-operations that yield meta-objects.</p>

<h4>5.3.2 Concept <code>Object</code><span class="section_name">[reflect.object]</span></h4>
<pre class="function"><code>
template &lt;class T&gt; concept bool Object() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Object&lt;T&gt;()</code> is satisfied if and only if <code>T</code> is a meta-object, as generated by the <code>$reflect</code> operator or any of the meta-object operations.</dd>
</p>

<h4>5.3.3 Concept <code>ObjectSequence</code><span class="section_name">[reflect.objseq]</span></h4>
<pre class="function"><code>
template &lt;class T&gt; concept bool ObjectSequence() {
  return <em>see below</em>;
}
</code></pre>
<p><code>ObjectSequence&lt;T&gt;()</code> is satisfied if and only if <code>T</code> is a sequence of <code>Object</code>s, generated by some of the meta-object operations.</dd>
</p>

<h4>5.3.4 Concept <code>Named</code><span class="section_name">[reflect.named]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Named() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Named&lt;T&gt;()</code> is satisfied if and only if <code>T</code> is an <code>Object</code> with an associated (possibly empty) name.</dd>
</p>

<h4>5.3.5 Concept <code>Alias</code><span class="section_name">[reflect.alias]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Alias() {
  return Named&lt;T&gt;() &amp;&amp; <em>see below</em>;
}
</code></pre>
<p><code>Alias&lt;T&gt;()</code> is satisfied if and only if <code>T</code> is a <code>Named</code> that 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 <em>using-declaration</em> or a <em>using-directive</em>.</dd>
</p>

<h4>5.3.6 Concept <code>RecordMember</code><span class="section_name">[reflect.recordmember]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool RecordMember() {
  return <em>see below</em>;
}
</code></pre>
<p><code>RecordMember&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level <em>member-declaration</em>.<!-- covers members of class, struct, union --></dd>
</p>

<h4>5.3.7 Concept <code>Enumerator</code><span class="section_name">[reflect.enumerator]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Enumerator() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Enumerator&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level enumerator.</dd>
</p>

<h4>5.3.8 Concept <code>Variable</code><span class="section_name">[reflect.variable]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Variable() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Variable&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level variable or non-static data member.</dd>
</p>

<h4>5.3.9 Concept <code>ScopeMember</code><span class="section_name">[reflect.scopemember]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool ScopeMember() {
  return Scope&lt;T&gt; || RecordMember&lt;T&gt;() || Enumerator&lt;T&gt;() || Variable&lt;T&gt;();
}
</code></pre>
<p><code>ScopeMember&lt;T&gt;()</code> is satisfied if and only if <code>T</code> satisfies <code>Scope</code>, <code>RecordMember</code>, <code>Enumerator</code> or <code>Variable</code>.</dd>
</p>

<h4>5.3.10 Concept <code>Typed</code><span class="section_name">[reflect.typed]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Typed() {
  return Variable&lt;T&gt;() || Enumerator&lt;T&gt;();
}
</code></pre>
<p><code>Typed&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level variable or enumerator.<!-- variable or function--></dd>
</p>


<h4>5.3.11 Concept <code>Namespace</code><span class="section_name">[reflect.namespace]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Namespace() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Namespace&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level namespace (including the global namespace).</dd>
</p>

<h4>5.3.12 Concept <code>GlobalScope</code><span class="section_name">[reflect.globalscope]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool GlobalScope() {
  return <em>see below</em>;
}
</code></pre>
<p><code>GlobalScope&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects the global namespace.</dd>
</p>

<h4>5.3.13 Concept <code>Class</code><span class="section_name">[reflect.class]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Class() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Class&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a non-union class type.</dd>
</p>

<h4>5.3.14 Concept <code>Enum</code><span class="section_name">[reflect.enum]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Enum() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Enum&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects an enumeration type.</dd>
</p>

<h4>5.3.15 Concept <code>Record</code><span class="section_name">[reflect.record]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Record() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Record&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a class type.</dd>
</p>

<h4>5.3.16 Concept <code>Scope</code><span class="section_name">[reflect.scope]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Scope() {
  return Namespace&lt;T&gt;() || Record&lt;T&gt;() || Enum&lt;T&gt;();
}
</code></pre>
<p><code>Scope&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level namespace (including the global namespace), class or enumeration.</dd>
</p>

<h4>5.3.17 Concept <code>Type</code><span class="section_name">[reflect.type]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Type() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Type&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a base-level type.</dd>
</p>

<h4>5.3.18 Concept <code>Constant</code><span class="section_name">[reflect.const]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Constant() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Constant&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a constant expression (C++ [expr.const]).</dd>
</p>

<h4>5.3.19 Concept <code>Base</code><span class="section_name">[reflect.inherit]</span></h4>
<pre class="function"><code>
template &lt;Object T&gt; concept bool Base() {
  return <em>see below</em>;
}
</code></pre>
<p><code>Base&lt;T&gt;()</code> is satisfied if and only if <code>T</code> reflects a <em>base-specifier</em>, as returned by the template <code>get_bases</code>.</dd>
</p>



<h3>5.4 Meta-object Operations <span class="section_name">[reflect.ops]</span></h3>

<h4>5.4.1 In general <span class="section_name">[reflect.ops.intro]</span></h4>
<p>A meta-object operation extracts information from meta-objects. It is a class template taking one or more arguments, at least one of which models the meta-object concept. The result of a meta-object operation can be either a constant expression (C++ [expr.const]) or a type.</p>

<h4>5.4.2 "Overloaded" operations <span class="section_name">[reflect.ops.over]</span></h4>

<p class="function">
<code>
template &lt;class T&gt; is_public;<br/>
template &lt;class T&gt; is_protected;<br/>
template &lt;class T&gt; is_private;<br/>
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>These meta-object operations are "overloaded" by concept type below. The generic templates do not have a definition. When multiple concepts implement the same meta-object operation, its template will be partially specialized for the concepts implementing the operation. [<em>Note:</em> For "overloaded" operations, any meta-object will always satisfy at most one of the concepts that the operation is "overloaded" for. <em>&mdash; end note</em>]</dd>
<dt></dt><dd>[<em>Example:</em> An an operation <code>OP</code> "overloaded" on concepts <code>A</code> and <code>B</code> will be defined as follows:
<pre><code>
  template &lt;class T&gt; concept bool A() { return std::is_signed_v&lt;T&gt;; }
  template &lt;class T&gt; concept bool B() { return std::is_class_v&lt;T&gt;; }
  template &lt;class T&gt; struct OP; // undefined
  template &lt;A T&gt; struct OP&lt;T&gt; {...};
  template &lt;B T&gt; struct OP&lt;T&gt; {...};
  </code></pre> <em>&mdash; end example</em>]
  </dd></dl>

<h4>5.4.3 Object operations<span class="section_name">[reflect.ops.object]</span></h4>

<p class="function">
<code>
template &lt;Object T1, Object T2&gt; struct reflects_same;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>reflects_same&lt;T1, T2&gt;</code> shall meet the <code>BinaryTypeTrait</code> requirements (C++ [reflect.rqmts]), with a <code>BaseCharacteristic</code> of <code>true_type</code> if two meta-objects reflect the same base-level entity, otherwise with a <code>BaseCharacteristic</code> of <code>false_type</code>.</dd>
<dt></dt><dd>[<em>Note:</em> With <pre><code>
  class A; using a0 = $reflect(A);
  class A {}; using a1 = $reflect(A);
  </code></pre> <code>reflects_same_v&lt;a0, a1&gt;</code> will be <code>true</code> as <code>a0</code> and <code>a1</code> reflect the same underlying entity. <em>&mdash; end note</em>]
  </dd>
</dl>

<p class="function">
<code>
template &lt;Object T&gt; struct get_source_location;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_source_location&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]) with a <code>BaseCharacteristic</code> of <code>source_location</code>. The <code>source_location</code> returned by <code>get_source_location&lt;T&gt;</code> is the <code>source_location</code> of the most recent declaration of the base-level entity described by <code>T</code>.</dd>
</dl>

<p class="function">
<code>
template &lt;Object T&gt; struct get_source_line;<br/>
template &lt;Object T&gt; struct get_source_column;<br/>
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of above templates shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]) with a <code>BaseCharacteristic</code> of <code>uint_least32_t</code> and a value of <code>get_source_location&lt;T&gt;::line()</code> (for <code>get_source_line&lt;T&gt;</code>) and <code>get_source_location&lt;T&gt;::column()</code> (for <code>get_source_column&lt;T&gt;</code>).</dd>
<dt>[<em>Note:</em></dt>
<dd>These versions of <code>get_source_location</code> members are provided to facilitate template meta programming. <em>&mdash; end note</em>]</dd>
</dl>

<p class="function">
<code>
template &lt;Object T&gt; struct get_source_file_name;<!-- <br/>
template &lt;Object T&gt; struct get_source_function_name; -->
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_source_file_name&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]) with a <code>BaseCharacteristic</code> of <code>integral_constant&lt;const char (&amp;)[N], STR&gt;</code>, where <code>STR</code> is the name (or a reference to a name) of a static, constant expression character array (NTBS) of length <code>N</code>, as if declared as <code>static constexpr char STR[N] = ...;</code>. The value of the NTBS consists of the same character values as the character sequence referred to by <code>get_source_location&lt;T&gt;::file_name()</code>.</dd>
<dt>[<em>Note:</em></dt>
<dd>This version of <code>get_source_location::file_name()</code> is provided to facilitate template meta programming. <em>&mdash; end note</em>]</dd>
</dl>


<h4>5.4.4 ObjectSequence operations<span class="section_name">[reflect.ops.objseq]</span></h4>

<p class="function">
<code>
template &lt;ObjectSequence S&gt; struct get_size;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_size&lt;S&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]) with a <code>BaseCharacteristic</code> of <code>integral_constant&lt;size_t, N&gt;</code>, where <code>N</code> is the number of elements in the object sequence.</dd>
</dl>

<p class="function">
<code>
template &lt;size_t I, ObjectSequence S&gt; struct get_element;
</code>
</p>
<dl class="attribute">
<dt>Remarks:</dt>
<dd>All specializations of <code>get_element&lt;I, S&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> corresponds to the <code>I</code><sup>th</sup> element <code>Object</code> in <code>S</code>, where the indexing is zero-based.</dd>
</dl>

<p class="function">
<code>
template &lt;template &lt;class...&gt; class Tpl, ObjectSequence S&gt;<br/>
&nbsp;&nbsp;struct unpack_sequence;
</code>
</p>
<dl class="attribute">
<dt>Remarks:</dt>
<dd>All specializations of <code>unpack_sequence&lt;Tpl, S&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is an alias to the template <code>Tpl</code> specialized with the types in <code>S</code>.</dd>
</dl>


<h4>5.4.5 Named operations<span class="section_name">[reflect.ops.named]</span></h4>

<p class="function">
<code>
template &lt;Named T&gt; struct is_anonymous;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_anonymous&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]). If <code>T</code> reflects an anonymous base-level entity, the <code>BaseCharacteristic</code> of <code>is_anonymous&lt;T&gt;</code> is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd>
</dl>


<p class="function">
<code>
template &lt;Named T&gt; struct get_base_name;<br/>
template &lt;Named T&gt; struct get_display_name;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]) with a <code>BaseCharacteristic</code> of <code>integral_constant&lt;const char (&amp;)[N], STR&gt;</code>, where <code>STR</code> is the name (or a reference to a name) of a static, constant expression character array (NTBS) of length <code>N</code>, as if declared as <code>static constexpr char STR[N] = ...;</code>.
<ul><li>For <code>T</code> reflecting an anonymous base-level entity, the string's value is the empty string.</li>
<li>For <code>T</code> reflecting a <code>decltype-specifier</code>, the string's value is the empty string for <code>get_base_name&lt;T&gt;</code> and implementation-defined for <code>get_display_name&lt;T&gt;</code>.</li>
<li>In all other cases, the string's value is implementation-defined for <code>get_display_name&lt;T&gt;</code> and has the following value for <code>get_base_name&lt;T&gt;</code>:
<ul>
  <li>for an <code>Alias</code>, the unqualified name of the aliasing declaration: the identifier introduced by a <em>type-parameter</em> or the name introduced by a <em>using-declaration</em>, <em>using-directive</em>, typedef or alias declaration;</li>
  <li>for a specialization of a class template, the <em>template-name</em>;</li>
  <li>for a class type, the <em>class-name</em>;</li>
  <li>for a namespace, the unqualified <em>namespace-name</em>;</li>
  <li>for a enumeration type, the unqualified <em>enum-name</em>;</li>
  <li>for all other <em>simple-type-specifiers</em>, the name stated in the "Type" column of Table 9 in (C++ [dcl.type.simple]);</li>
  <li>for a variable, the unqualified <em>variable-name</em>;</li>
  <li>for a enumerator, the unqualified <em>enumerator-name</em>;</li>
  <li>for a class data member, the unqualified <em>class-data-member-name</em>.</li>
</ul>
Any <em>cv</em>-qualifiers, pointers, references and array specifiers (including <code>"["</code> and <code>"]"</code>) are removed from the string value of <code>get_base_name&lt;T&gt;</code>.
</li>
 </ul></dd>
<dt>[<em>Note:</em></dt>
<dd>With <pre><code>
  namespace n { template &lt;class T&gt; class A; }
  using a_m = $reflect(n::A&lt;int&gt;);
</code></pre>
the value of <code>get_base_name_v&lt;a_m&gt;</code> is <code>"A"</code> while the value of <code>get_display_name_v&lt;a_m&gt;</code> might be <code>"n::A&lt;int&gt;"</code>. <em>&mdash; end note</em>]
<dt>[<em>Note:</em></dt>
<dd>The length of the NTBS is <code>sizeof(get_display_name_v&lt;T&gt;) - 1</code>. <em>&mdash; end note</em>]
  </dd></dl>



<h4>5.4.6 Alias operations<span class="section_name">[reflect.ops.alias]</span></h4>

<p class="function">
<code>
template &lt;Alias T&gt; struct get_aliased;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_aliased&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is the <code>Named</code> meta-object reflecting
<ul><li>the redefined name, if <code>T</code> reflects a typedef or <em>alias-declaration</em>;</li>
<li>the template specialization's template argument value, if <code>T</code> reflects a template <em>type-parameter</em>;</li>
<li>the original declaration introduced by a <em>using-declaration</em> or a <em>using-directive</em>;</li>
<li>the aliased namespace of a <em>namespace-alias</em>.</li>
<li>the type denoted by the <em>decltype-specifier</em>.</li>
</ul>
The nested type named <code>type</code> must not itself be an <code>Alias</code>; instead, it is reflecting the underlying non-<code>Alias</code> entity.</dd>
<dt>[<em>Example:</em></dt>
<dd>For
  <pre><code>
using i0 = int; using i1 = i0;
</code></pre>
<code>get_aliased_t&lt;i1&gt;</code> reflects <code>int</code>. <em>&mdash; end example</em>]
</dd></dl>


<h4>5.4.7 Type operations<span class="section_name">[reflect.ops.type]</span></h4>

<p class="function">
<code>
template &lt;Typed T&gt; struct get_type;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_type&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is the <code>Type</code> reflecting the type of the base-level entity reflected by <code>T</code>.</dd>
<dt>[<em>Example:</em></dt>
<dd>For
  <pre><code>
int v; using v_m = $reflect(v);
</code></pre>
<code>get_type_t&lt;v_m&gt;</code> is <code>$reflect(int)</code>. <em>&mdash; end example</em>]
</dd></dl>

<p class="function">
<code>
template &lt;Type T&gt; struct get_reflected_type;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_reflected_type&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is the base-level type reflected by <code>T</code>.</dd></dl>

<p class="function">
<code>
template &lt;Type T&gt; struct is_enum;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_enum&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]). If <code>T</code> reflects an enumeration type, the <em>BaseCharacteristic</em> of <code>is_enum&lt;T&gt;</code> is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>

<p class="function">
<code>
template &lt;Type T&gt; struct is_class;<br/>
template &lt;Type T&gt; struct is_struct;<br/>
template &lt;Type T&gt; struct is_union;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]). If <code>T</code> reflects a class with <em>class-key</em> <code>class</code> (for <code>is_class&lt;T&gt;</code>), <code>struct</code> (for <code>is_struct&lt;T&gt;</code>), or <code>union</code> (for <code>is_union&lt;T&gt;</code>), the <em>BaseCharacteristic</em> of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>


<h4>5.4.8 Member operations<span class="section_name">[reflect.ops.member]</span></h4>

<p class="function">
<code>
template &lt;ScopeMember T&gt; struct get_scope;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_scope&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is the <code>Scope</code> reflecting a scope <em>S</em>. With <em>ST</em> being the scope of the declaration of the base-level entity 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 or enumeration scope.</dd></dl>

<p class="function">
<code>
template &lt;RecordMember T&gt; struct is_public&lt;T&gt;;<br/>
template &lt;RecordMember T&gt; struct is_protected&lt;T&gt;;<br/>
template &lt;RecordMember T&gt; struct is_private&lt;T&gt;;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these partial template specializations shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]). If <code>T</code> reflects a public member (for <code>is_public</code>), protected member (for <code>is_protected</code>) or private member (for <code>is_private</code>), the <em>BaseCharacteristic</em> of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>



<h4>5.4.9 Record and Enum operations<span class="section_name">[reflect.ops.record_enum]</span></h4>

<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;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.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 data members of the class reflected by <code>T</code>:
<ul>
  <li>for <code>get_public_data_members</code>, all public data members;</li>
  <li>for <code>get_accessible_data_members</code>, all data members that are accessible from the scope of the invocation of <code>$reflect</code> which generated (directly or indirectly) <code>T</code>; </li>
  <li>for <code>get_data_members</code>, all data members, irrespective of their accessibility.</li>
</ul>
The order of the elements in the <code>ObjectSequence</code> is the order of the declaration of the data members in the class reflected by <code>T</code>. The class reflected by <code>T</code> must be complete at the point of the invocation of <code>$reflect</code> which generated (directly or indirectly) <code>T</code>, otherwise the program is ill-formed.</dd>
<dt>Remarks:</dt>
<dd>
  The program is ill-formed if <code>T</code> reflects a closure type.
</dd>
</dl>

<p class="function">
<code>
template &lt;Record T&gt; struct get_public_member_types;<br/>
template &lt;Record T&gt; struct get_accessible_member_types;<br/>
template &lt;Record T&gt; struct get_member_types;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>Type</code> types that reflect the following subset of types declared in the class reflected by <code>T</code>:
<ul>
  <li>for <code>get_public_member_types</code>, all public members types;</li>
  <li>for <code>get_accessible_member_types</code>, all member types that are accessible from the scope of the invocation of <code>$reflect</code> which generated (directly or indirectly) <code>T</code>;</li>
  <li>for <code>get_member_types</code>, all member types, irrespective of their accessibility.</li>
</ul>
The order of the elements in the <code>ObjectSequence</code> is the order of the first declaration of the types in the class reflected by <code>T</code>. The class reflected by <code>T</code> must be complete at the point of the invocation of <code>$reflect</code> which generated (directly or indirectly) <code>T</code>, otherwise the program is ill-formed.</dd>
<dt>Remarks:</dt>
<dd>
  The program is ill-formed if <code>T</code> reflects a closure type.
</dd>
</dl>

<p class="function">
<code>
template &lt;Class T&gt; struct get_public_bases;<br/>
template &lt;Class T&gt; struct get_accessible_bases;<br/>
template &lt;Class T&gt; struct get_bases;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of these templates shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>Base</code> types that reflect the following subset of base classes of the class reflected by <code>T</code>:
<ul>
  <li>for <code>get_public_bases</code>, all public bases;</li>
  <li>for <code>get_accessible_bases</code>, all bases are taken into account whose public members are accessible from the scope of the invocation of <code>$reflect</code> which generated (directly or indirectly) <code>T</code>;</li>
  <li>for <code>get_bases</code>, all bases are taken into account, irrespective of their accessibility.</li>
</ul>
The order of the elements in the <code>ObjectSequence</code> is the order of the declaration of the base classes in the class reflected by <code>T</code>. The class reflected by <code>T</code> must be complete at the point of the invocation of <code>$reflect</code> which generated (directly or indirectly) <code>T</code>, otherwise the program is ill-formed.</dd>
<dt>Remarks:</dt>
<dd>
  The program is ill-formed if <code>T</code> reflects a closure type.
</dd>
</dl>

<p class="function">
<code>
template &lt;Class T&gt; struct is_final;
</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 (C++ [reflect.rqmts]). If <code>T</code> reflects a class that is marked with the <em>class-virt-specifier</em> <code>final</code>, the <em>BaseCharacteristic</em> 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;Enum T&gt; struct is_scoped_enum;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>is_scoped_enum&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]). If <code>T</code> reflects a <em>scoped enumeration</em>, the <em>BaseCharacteristic</em> 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;Enum T&gt; struct get_enumerators;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_enumerators&lt;T&gt;</code> shall meet the <code>TransformationTrait</code> requirements (C++ [reflect.rqmts]). The nested type named <code>type</code> is an alias to an <code>ObjectSequence</code> specialized with <code>Constant</code> types that reflect the enumerators of the enumeration type reflected by <code>T</code>.</dd></dl>



<h4>5.4.10 Value operations<span class="section_name">[reflect.ops.value]</span></h4>

<p class="function">
<code>
template &lt;Constant T&gt; struct get_constant;
</code>
</p>
<dl class="attribute">
<dt></dt>
<dd>All specializations of <code>get_constant&lt;T&gt;</code> shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]), with a  <em>BaseCharacteristic</em> of <code>integral_constant&lt;X, x&gt;</code>, where <code>X</code> is the type of the value reflected by <code>T</code> and <code>x</code> its value.</dd></dl>

<p class="function">
<code>
template &lt;Variable T&gt; struct is_constexpr;
</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 (C++ [reflect.rqmts]). If <code>T</code> reflects a variable declared with the <em>decl-specifier</em> <code>constexpr</code>, the <em>BaseCharacteristic</em> 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;
</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 (C++ [reflect.rqmts]). If <code>T</code> reflects a variable with static storage duration, the <em>BaseCharacteristic</em> 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;
</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 (C++ [reflect.rqmts]), with a  <em>BaseCharacteristic</em> of <code>integral_constant&lt;X, x&gt;</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>

<h4>5.4.11 Base operations<span class="section_name">[reflect.ops.derived]</span></h4>

<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 (C++ [reflect.rqmts]). The nested type named <code>type</code> is an alias to <code>$reflect(<em>X</em>)</code>, where <code><em>X</em></code> is the class of the <em>base-specifier</em> reflected by <code>T</code>.</dd></dl>


<p class="function">
<code>
template &lt;Base T&gt; struct is_virtual;<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>
<dl class="attribute">
<dt></dt>
<dd>All specializations of the template and of these partial template specializations shall meet the <code>UnaryTypeTrait</code> requirements (C++ [reflect.rqmts]). If <code>T</code> reflects a <em>base-specifier</em> with the <code>virtual</code> specifier (for <code>is_virtual</code>), with the <code>public</code> specifier or with an assumed (see C++ [class.access.base]) <code>public</code> specifier (for <code>is_public</code>), with the <code>protected</code> specifier (for <code>is_protected</code>), or with the <code>private</code> specifier or with an assumed <code>private</code> specifier (for <code>is_private</code>), then the <em>BaseCharacteristic</em> of the respective template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>



<h4>5.4.11 Namespace operations<span class="section_name">[reflect.ops.namespace]</span></h4>

<p class="function">
<code>
template &lt;Namespace T&gt; struct is_inline;
</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 (C++ [reflect.rqmts]). If <code>T</code> reflects an inline namespace, the <em>BaseCharacteristic</em> of the template specialization is <code>true_type</code>, otherwise it is <code>false_type</code>.</dd></dl>


</blockquote>

<!--
<h2 id="conclusion">Conclusion</h2>
<p>A variant has proven to be a useful tool. This paper proposes the necessary ingredients.</p>
-->

<h2 id="acknowledgments">Acknowledgments</h2>
<p>Thanks to Ricardo Fabiano de Andrade, Roland Bock and Klaim-Joël Lamotte 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>

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

<p>Refines the metaobject concepts and introduces
a concrete implementation of their interface by the means of templates similar
to the standard type traits. Describes some additions to the standard library
(mostly meta-programming utilities), which simplify the use of the metaobjects.
Answers some questions from the discussion about N3996 and expands the design
rationale.
</p>

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

<p>Incorporates the feedback from the discussion
about N4111 at the Urbana meeting, most notably reduces the set of metaobject concepts and refines their
definitions, removes some of the additions to the standard library added in the previous revisions.
Adds context-dependent reflection.
</p>

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

<p>Further refines the concepts from N4111; prefixes
the names of the metaobject operations with <code>get_</code>, adds new operations,
replaces the metaobject category tags with new metaobject traits.
Introduces a nested namespace <code>std::reflect</code> which contains most
of the reflection-related additions to the standard library.
Rephrases definition of meta objects using Concepts Lite. Specifies the
reflection operator name &mdash; <code>reflexpr</code>.
Introduces an experimental implementation of the reflection operator in clang.
Drops the context-dependent reflection from N4111 (will be re-introduced later).
</p>

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

<p>Dropped all metaobject traits except <code>is_metaobject</code>. All metaobject
classification is now done by using the concepts.</p>
<p>The <code>meta::Scoped</code> concept has been renamed to <code>meta::ScopeMember</code>.
The <code>meta::Constant</code> and <code>meta::Specifier</code> concepts,
and several new operations have been added.
</p>
<p>The aliases for the operation templates returning metaobjects had previously
the <code>_t</code> suffix; this has been changed to the <code>_m</code> suffix.</p>

<h4>Revision 6 (<a href="http://wg21.link/p0194r2">P0194R2</a>)</h4>

<p>The following concepts from P0194R1 were dropped in order to simplify
the proposal:
<code>meta::Linkable</code>, <code>meta::Enumerator</code>,
<code>meta::DataMember</code>, <code>meta::MemberType</code>,
<code>meta::EnumClass</code>, <code>meta::TypeAlias</code> and
<code>meta::NamespaceAlias</code>.
</p>
<p>The following concepts were added to the proposal:
<code>meta::TagType</code>, <code>meta::Record</code>,
<code>meta::Enumerator</code>.
</p>
<p>Unlike in the previous proposal, metaobjects reflecting anonymous entities -
the global scope, anonymous namespaces and classes, etc. <em>do</em> conform to the
<code>meta::Named</code> concept and implement the name-returning operations.
</p>
<p>Unlike in the previous proposal, metaobjects reflecting the global scope
<em>do</em> conform to the <code>meta::ScopeMember</code> concept and the
<code>meta::get_scope</code> operation. For arguments reflecting
the global scope returns a metaobject reflecting the global scope
(i.e. the global scope is its own scope).
</p>
<p>Metaobjects reflecting built-in types and types like pointers, references,
arrays, etc. now don't have a scope (i.e. they do not conform to the
<code>meta::ScopeMember</code> concept).
</p>
<p>We have added a different mechanism for distinguishing between
non-scoped and scoped <code>enum</code>s - the <code>meta::is_scoped_enum</code>
operation. Unlike in the previous proposal, <code>meta::Enum</code> reflecting
a non-scoped enum <em>is</em> a <code>meta::Scope</code>.
</p>
<p>We now allow the default construction and copy construction of
values of metaobject types.
</p>
<p>Direct reflection of class data members, member types and type aliases,
enumerators and global scope/namespace-level variables has been added.</p>
<p>The typedef (type-alias) reflection has been simplified based on the
feedback from Oulu. Previously we required reflection to be aware about all
aliases in a <em>"chain"</em> even in the context of templates.</p>
<p>The mechanism for enumerating public-only vs. all (including non-public ones)
class members has been changed. Now the <em>"basic"</em> operations like
<code>meta::get_data_members</code>, <code>meta::get_member_types</code>, etc.
return all members, and the <code>meta::get_public_data_members</code>,
<code>meta::get_public_member_types</code>, return only the public class members.
</p>

<h4>Revision 7 (<a href="http://wg21.link/p0194r3">P0194R3</a>)</h4>
<p>Major wording update, clarifying the behavior for instance on dependent names and function-local declarations. All examples but those required for the wording are now found in the design discussion paper, <a href="http://wg21.link/p0385">p0385</a>.</p>
<p>Rename header, namespace from <code>meta</code> to <code>reflect</code>. Target a TS.</p>
<p>Use of function-style concepts, following the example set by the Ranges TS, for consistency reasons. The name of the reflection operator was changed to <code>$reflect</code>; the <em>basic source character set</em> was adjusted accordingly.</p>
<p>In addition to <code>get_public_bases</code>, <code>get_public_data_members</code> and <code>get_public_member_types</code> and their sibling without <code>public</code>, a new sibling <code>get_accessible_...</code> was added. The <code>Specifier</code>, <code>TagType</code> and <code>Reversible</code> concepts were removed. So was the <code>is_metaobject</code> trait. The type of meta-object operations "returning" strings have been updated. The order of template parameters for <code>MetaSequence</code> operations has been matched to similar operations of <code>tuple</code>. The suffix <code>_m</code> was reverted to <code>_t</code>. <code>$reflect()</code> with an empty operand is disallowed.</p>
</div>



<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 id="ref-p0578">
<p>2. <em>Static reflection in a nutshell.</em> <a href="http://wg21.link/p0578">p0578</a></p>

<div id="ref-ConceptsTSIssue29">
<p>3. <a href="http://cplusplus.github.io/concepts-ts/ts-active.html#29"><em>C++ Concepts Active Issues List (Revision 4)</em>, Issue 29</a></p>
</div>

</body>
</html>
