Welcome to v0.2 of the meta::[[verse]]!
# Slide 1
# Slide 2
# Slide 3
# Slide 4
(*) Examples from or derive from P2996, P3096, or EDG's implementation
# Slide 5
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
// 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
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
error: meta type variables must be constexpr
constexpr auto rexpr = ^int;
P2996
# Slide 11
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 12
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 13
From: "Let's talk about abstraction layers"
P2996
# Slide 14
Represents:
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 15
#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 16
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 17
constexpr auto a = 42;
std::cout << meta::name_of(^a) << "\n";
All* the metafunctions accept "info" and return:
* Besides "reflect_value/object/function", which accepts type T
P2996
* Note: This is a pseudo-code, does not work as is
# Slide 18
P2996
# Slide 19
#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 20
// 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 21
#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 22
void PrintFuncParams()
{
std::cout << "Param names: "
<< PrintParamK(^func, 0) << ", "
<< PrintParamK(^func, 1) << "\n";
}
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 23
Reflection-Based Library
# Slide 24
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 25
Guarantees and requirements provided by the library
can be expressed as "Customization Points"
Reflection as CP
C++Now 2022, Cpp India 2022, CoreC++ 2022, CppCon 2023
"Customization Methods: Connecting User and C++ Library Code"
# Slide 26
Reflection as CP
C++Now 2022, Cpp India 2022, CoreC++ 2022, CppCon 2023
"Customization Methods: Connecting User and C++ Library Code"
# Slide 27
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 28
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
class LibType {
public:
int pub;
private:
int prv;
public:
void Print();
};
Reflection as CP
# Slide 29
What will be the guarantees for "reflection libraries"?
More interesting papers:
Reflection as CP
# Slide 30
Pipeline Integration
AppCode
LoggerLib
Compiler
LoggerLib.o
AppCode.o
Linker
version / macros
main.out
# Slide 31
Pipeline Integration
main.out
Linker
main.o
AppCode
LoggerLib
Compiler
version / macros
Linker
OldAppCode
LoggerLib
Compiler
version / macros
Backward Compatibility
# Slide 32
What's Next?
Which guarantees do we need to provide?
What should be the outcome of "breaking the contract"
# Slide 33
How will Reflection impact our code bases?
Summary
?
From: https://isocpp.org/std/status (by Herb Sutter)
# Slide 34
Inbal Levi
sinbal2lextra@gmail.com
linkedin.com/in/inballevi/
Thank you!
Stay in touch!
Thanks to:
Thank you for being passionate about C++!