
Welcome to v0.3 of the meta::[[verse]]!

# Slide 1
# Slide 2
- Lead C++ Developer
- ISO C++ foundation and Boost foundation board member
- An active member of the ISO C++ Committee
- Israeli National Body Chair
- Library Evolution Work Group Chair
Inbal Levi
Reflection in C++
# Slide 3
- The ability of software to expose its internal structure
-
Static reflection - compiler exposes structure at compile time
- Disclaimers:
- May be possible to "carry" the data into the runtime...
- But may introduce performance, security, or other issues
- This is out of scope for this talk (and for C++26, as of now)
This Talk
# Slide 4
- Part I: Intro to reflection:
- A brief history of "Reflection" proposals in C++
- Latest proposal: "P2996: Reflection for C++26"
- Usage examples (reflection-based library) (*)
- Part II: Impact on our code bases
- Reflection as a Customization Point Mechanism
- Pipeline integration
- What's next?
(*) Examples from or derive from P2996, P3096, or EDG's implementation
# Slide 5
2015
Boost.Hana
(Louis Dionne)
Template metaprog. lib
A Brief History
# Slide 6
A Brief History
Typefull
vs.
Monotype
Type based
vs.
Value based
meta objects
# Slide 7
A Brief History
# Slide 8
What do I mean by "Reflection"?
// Lib.hpp
class LibType : public BaseOne, public BaseTwo
{
int a;
double b;
};
P2996
// main.cpp
#include <meta>
#include "Lib.hpp"
int main()
{
constexpr std::meta::info refexpr = ^^LibType;
auto res = std::meta::bases_of(refexpr);
}
* Note: This is a pseudo-code, does not work as is
# Slide 9
P2996: Reflection for C++26
-
Reflection Operator:
^^
-
Splicers: [
:
…:]
-
std::meta::info
-
Metafunctions
-
identifier_of
-
display_string_of
-
source_location_of
-
type_of
-
parent_of
-
dealias
-
Access modifiers: is_public, is_protected, is_private
-
Inheritance: is_virtual, is_pure_virtual, is_override, ...
-
Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...
-
Advanced Type Queries: is_complete_type, is_template, is_special_member, ...
-
template_of
-
template_arguments_of
3. Template Queries:
-
members_of
-
bases_of
-
(non)static_data_members_of
-
accessible_members_of(P3293R2) -
enumerators_of
2. Type Queries:
-
Name & Location:
(+ Other Type Predicates)
4. Member Queries:
5. substitute (template)
6. reflect Invoke (template)
7. extract<T>(info) (constexpr not required)
8. test_type(s) ("is_same")
9. reflect_value (template)
10. define_class (injection)
11. Data Layout:
12. (+) Type Traits...?
P2996
-
offset_of -> member_offsets
-
size_of
-
bit_size_of
-
alignment_of
auto rexpr = ^ int;
# Slide 10
The Reflection Operator (^^) (Lift)
P2996
AKA Unibrow

^
auto rexpr = ^^int;
# Slide 11
The Reflection Operator (^^) (Lift)
- Shifts expressions into a "meta" - "reflection info" object
- Object can then to be used as input to reflection utilities
error: meta type variables must be constexpr
constexpr auto rexpr = ^^int;
P2996
# Slide 12
Splicers
- Splice extract the C++ expression back from "meta::info"...
- ...To be then used regularly to write the C++ program
constexpr auto rexpr = ^^int;
typename[:rexpr:] a = 42;
What are you?
rexpr
meta::info obj, contains info on "int" type
typename[:rexpr:]
int
P2996
# Slide 13
P2996: Reflection for C++26
P2996
-
Reflection Operator: ^^
-
Splicers: [
:
…:]
-
std::meta::info
-
Metafunctions
-
identifier_of
-
display_string_of
-
source_location_of
-
type_of
-
parent_of
-
dealias
-
Access modifiers: is_public, is_protected, is_private
-
Inheritance: is_virtual, is_pure_virtual, is_override, ...
-
Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...
-
Advanced Type Queries: is_complete_type, is_template, is_special_member, ...
-
template_of
-
template_arguments_of
3. Template Queries:
-
members_of
-
bases_of
-
(non)static_data_members_of
-
accessible_members_of(P3293R2) -
enumerators_of
2. Type Queries:
-
Name & Location:
(+ Other Type Predicates)
4. Member Queries:
5. substitute (template)
6. reflect Invoke (template)
7. extract<T>(info) (constexpr not required)
8. test_type(s) ("is_same")
9. reflect_value (template)
10. define_class (injection)
11. Data Layout:
12. (+) Type Traits...?
-
offset_of -> member_offsets
-
size_of
-
bit_size_of
-
alignment_of
# Slide 14
std::meta::info

From: "Let's talk about abstraction layers"
P2996
# Slide 15
std::meta::info
Represents:
- Type and type alias
- Function or member function
- Variable, static data member, or structured binding
- Non-static data member
- Constant value
- Constant expression
- Template
- Namespaces
int a = 42;
constexpr auto b = ^^a;
std::cout << [:b:] << "\n"; // OK
std::cout << [:^^(a*2):] << "\n"; // Error
constexpr int a = 42;
constexpr auto b = ^^a;
std::cout << [:b:] << "\n"; // OK
std::cout << [:^^(a*2):] << "\n"; // OK
P2996
# Slide 16
std::meta::info
#include <iostream>
#include <experimental/meta>
class R;
constexpr std::meta::info res1 = ^^R;
constexpr auto print1 = std::meta::
is_complete_type(res1); // (1)
class R {
int a;
};
constexpr std::meta::info res2 = ^^R;
constexpr auto print2 = std::meta::
is_complete_type(res2); // (2)
constexpr auto print3 = std::meta::
is_complete_type(res1); // (3)
int main()
{
std::cout << "Res: " << print1 << "\n"; // (1)
std::cout << "Res: " << print2 << "\n"; // (2)
std::cout << "Res: " << print3 << "\n"; // (3)
}
P2996
https://godbolt.org/z/sYs39bj5e

# Slide 17
P2996: Reflection for C++26
P2996
-
Reflection Operator: ^^
-
Splicers: [
:
…:]
-
std::meta::info
-
Metafunctions
-
identifier_of
-
display_string_of
-
source_location_of
-
type_of
-
parent_of
-
dealias
-
Access modifiers: is_public, is_protected, is_private
-
Inheritance: is_virtual, is_pure_virtual, is_override, ...
-
Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...
-
Advanced Type Queries: is_complete_type, is_template, is_special_member, ...
-
template_of
-
template_arguments_of
3. Template Queries:
-
members_of
-
bases_of
-
(non)static_data_members_of
-
accessible_members_of(P3293R2) -
enumerators_of
2. Type Queries:
-
Name & Location:
(+ Other Type Predicates)
4. Member Queries:
5. substitute (template)
6. reflect Invoke (template)
7. extract<T>(info) (constexpr not required)
8. test_type(s) ("is_same")
9. reflect_value (template)
10. define_class (injection)
11. Data Layout:
12. (+) Type Traits...?
-
offset_of -> member_offsets
-
size_of
-
bit_size_of
-
alignment_of
# Slide 18
Metafunctions
constexpr auto a = 42;
std::cout << meta::name_of(^^a) << "\n";
All* the metafunctions accept "info" and return:
- string_view (e.g. identifier_of)
- std::meta::info (e.g. type_of)
- vector<std::meta::info> (e.g. bases_of)
- bool (e.g. is_concept)
- size_t (e.g. alignment_of)
- T (e.g. extract(info))
- source_location, member_offset (e.g. offset_of)
* Besides "reflect_value/object/function", which accepts type T
P2996
* Note: This is a pseudo-code, does not work as is
# Slide 19
Type Traits
- Two types of "Type Traits":
- Query the type
- Modify the type
- P2996 proposes the first type (e.g. is_nothrow_swappable)
- Interesting functionality available by the second type
- ...But this is more challenging, as it interferes with the compiler's representation of the program
P2996
# Slide 20
Reflection Logger
#include <string>
#include <experimental/meta>
consteval bool LogMembers(std::meta::info type)
{
// Verify type is a class/struct
// Ignore usecase of unnamed members (union/struct etc.)
std::__report_constexpr_value(name_of(type).data());
for (auto r : nonstatic_data_members_of(type))
{
std::__report_constexpr_value("\n\tmember:");
std::__report_constexpr_value(name_of(r).data());
}
return true;
}
// User code
struct Student
{
std::string name;
int id;
};
static_assert(LogMembers(^Student));
https://godbolt.org/z/oobfx9E7h
Reflection-Based Library

Based on example from EDG's CE implementation

# Slide 21
Command Line Args
// Members represent Args (should be known at compile time)
using namespace clap;
struct Args : Clap
{
Option<std::string, Flags{.use_short=true, .use_long=true}> name = "";
Option<int, Flags{.use_short=true, .use_long=true}> count = 0;
};
int main(int argc, char** argv)
{
auto opts = Args{}.parse(argc, argv);
for (int i = 0; i < opts.count; ++i)
{
std::cout << "Hello " << opts.name << "!\n";
}
}
https://godbolt.org/z/9GE3ePK71
Reflection-Based Library

Based on example from P2996
# Slide 22
Function Param Names
#include <experimental/meta>
#include <iostream>
consteval auto PrintParamK(std::meta::info r, size_t k)
{
return name_of(parameters_of(r)[k]);
}
// Function Declaration
void func(int first, int last);
void PrintFuncParamAfterDeclaration()
{
std::cout << "Param names: "
<< PrintParamK(^func, 0) << ", "
<< PrintParamK(^func, 1) << "\n";
}
// Function Definition
void func(int n, int ln)
{}
void PrintFuncParamAfterDefinition()
{
std::cout << "Param names: "
<< PrintParamK(^func, 0) << ", "
<< PrintParamK(^func, 1) << "\n";
}
int main()
{
PrintFuncParamAfterDeclaration(); // Param names: first, last
PrintFuncParamAfterDefinition(); // Param names: n, ln
}
Reflection-Based Library

https://godbolt.org/z/M84Ea6P88
Based on example from P3096
# Slide 23
Reflection Based Library
void PrintFuncParams()
{
std::cout << "Param names: "
<< PrintParamK(^func, 0) << ", "
<< PrintParamK(^func, 1) << "\n";
}
- Interaction between library code and user(*) code
void func(int first, int last);
// PrintParamsLocation1() { ... }
void func(int a, int b) { ... }
// PrintParamsLocation2() { ... }
int main()
{
PrintFuncParamsLocation1();
PrintFuncParamsLocation2();
}
Library Code
User(*) Code
"P3096: Function Parameter Reflection in Reflection for C++26"
(Adam Lach, Walter Genovese)
Reflection-Based Library
# Slide 24
Function Param Names
- P3096 Introduces the following options:
- Compile, No Guarantees
(Different compilers' output may be inconsistent) - Enforce Consistent Naming
(Don't compile if more than one option exists) - Mark by attribute (e.g. [[canonical]])
(Explicitly mark, otherwise ill-formed)
- Compile, No Guarantees

Reflection-Based Library
# Slide 25
Function Param Names
- Forward competability
void PrintFuncParams()
{
std::cout << "Param names: "
<< PrintParamK(^^func, 0) << ", "
<< PrintParamK(^^func, 1) << "\n";
}
void func(int first, int last);
// PrintParamsLocation1() { ... }
void func(int first, int last)
{ ... }
// PrintParamsLocation2() { ... }
int main()
{
PrintFuncParamsLocation1();
PrintFuncParamsLocation2();
}
Library Code
New User Code
void func(int first, int last);
// PrintParamsLocation1() { ... }
void func(int a, int b)
{ ... }
// PrintParamsLocation2() { ... }
int main()
{
PrintFuncParamsLocation1();
PrintFuncParamsLocation2();
}
"P3096: Function Parameter Reflection in Reflection for C++26"
(Adam Lach, Walter Genovese)
Reflection-Based Library
# Slide 26
Guarantees and requirements provided by the library
can be expressed as "Customization Points"

Reflection as CP
Detour: Customization Points
C++Now 2022, Cpp India 2022, CoreC++ 2022, CppCon 2023
"Customization Methods: Connecting User and C++ Library Code"

# Slide 27
Detour: Customization Points
Reflection as CP
- Interaction between library code and user (*) code:
- Virtual functions:
- Library side: declaration of virtual functions
- User side: overriding virtual functions
- Template instantiation:
- Library side: declare a template
- User side: instantiate template for their types
- Provide functionality to be detected by ADL:
- Library side: allows/expects functions by name
- User side: declares a function within their type to be detected by ADL
- And now - Reflection?
- Virtual functions:
C++Now 2022, Cpp India 2022, CoreC++ 2022, CppCon 2023
"Customization Methods: Connecting User and C++ Library Code"

# Slide 28
Reflection as Customization
template<class_type T, structural_subtype_of<T> U>
void LibFunc(const T& src, U& dst)
{
constexpr auto members = meta::data_members_of(reflexpr(src));
template for (constexpr meta::info a : members)
{
constexpr meta::info b = meta::lookup(dst, meta::name_of(a));
dst.|b| = src.|a|;
}
} // `structural_copy`
Example from "P2237: Metaprogramming" (Andrew Sutton)
C++Now 2022, Cpp India 2022, CoreC++ 2022, CppCon 2023
"Customization Methods: Connecting User and C++ Library Code"

Reflection as CP
# Slide 29
- Interaction between library code and user(*) code
int main()
{
type.[:get_member_i(0):] = 1;
type.[:get_member_i(1):] = 1;
type.[:member_named("pub"):] = 2;
type.[:member_named("prv"):] = 2;
}
Library Code
User(*) Code
Reflection as Customization

class LibType {
public:
int pub;
private:
int prv;
public:
void Print();
};
Reflection as CP
# Slide 30
Reflection Libraries
What will be the guarantees for "reflection libraries"?
More interesting papers:
- Scheduled next week for LEWG, the discussion is ongoing
- We would love your input!
Reflection as CP
# Slide 31
Pipeline Integration
Pipeline Integration
AppCode
LoggerLib
Compiler
LoggerLib.o
AppCode.o
Linker
version / macros
- The compiler provides:
- Standard version flag and implementation macros
- The library can then "ifdef" based on it to figure out
- Standard version
- Avaliable features
main.out
# Slide 32
Pipeline Integration
Pipeline Integration
main.out
Linker
main.o
AppCode
LoggerLib
Compiler
version / macros
Linker
OldAppCode
LoggerLib
Compiler
version / macros
Backward Compatibility
# Slide 33
What should we expect from "reflection libraries"?
What's Next?
Which guarantees do we need to provide?
- No compatibility between standard versions
- No backward compatibility for source code
- No guarantees for existing code?
What should be the outcome of "breaking the contract"
- The outcome of failures:
- Program is ill-formed (fails to compile)
- Program contains UB (undefined behavior)
- Errors at compile time:
- Should indicate to "reflection" stage (NOT "old" compilation)
- Throw exceptions(?)
- Warnings: Which level of feedback is given to correct mistakes?
# Slide 34
C++ 26 Reflection
How will Reflection impact our code bases?
Summary


?
From: https://isocpp.org/std/status (by Herb Sutter)
# Slide 35
Thank you!
Inbal Levi
sinbal2lextra@gmail.com
linkedin.com/in/inballevi/
Thank you!
Stay in touch!
Thanks to:
- CoreC++ user group
- Matus Chochlik
- David Sankel
- Corentin Jabot
- Lewis Baker
- Amir Kirsh
- Adi Shavit
Thank you for being passionate about C++!
-
Reflection Papers' authors!
Wyatt Childers, Peter Dimov, Dan Katz, Barry Revzin, Andrew Sutton, Faisal Vali, Daveed Vandevoorde, Matus Chochlik, Herb Sutter, Bjarne Stroustrup, David Sankel, Axel Naumann, Andrei Alexandrescu, Bryce Lelbach, Michael Garland, Louis Dionne, Adam Lach, Jagrut Dave, Walter Genovese, Saksham Sharma

Welcome to v0.3 of the meta::[[verse]]
By Inbal Levi
Welcome to v0.3 of the meta::[[verse]]
- 63