Welcome to v1.0 of the meta::[[verse]]!
# Slide 1
# Slide 2
https://slides.com/inballevi/welcome-to-v1-0-of-the-meta-verse
# Slide 3
# Slide 4
# Slide 5
(*) Examples from or derive from P2996, P3096, or EDG's implementation
# Slide 6
Boost.Hana
(Louis Dionne)
Template metaprog. lib
A Brief History
Serialization
Delegates
Getters / Setters
Customization Points
# Slide 7
A Brief History
Typefull
vs.
Monotype
Type based
vs.
Value based
meta objects
# Slide 8
A Brief History
# Slide 9
// 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;
constexpr auto res = std::meta::bases_of(refexpr)[0];
}
https://godbolt.org/z/WxdvKdcMY
# Slide 10
Reflection Operator: ^^
Splicers: [:
…:]
std::meta::info
Metafunctions
P2996
10. define_aggregate (inject)
Name & Location:
3. Template Queries:
10. define_class (inject)
identifier_of
display_string_of
source_location_of
template_of
template_arguments_of
11. Data Layout:
4. Member Queries:
offset_of -> member_offset
size_of
alignment_of
bit_size_of
2. Type Queries:
members_of, bases_of
(non)static_data_members_of
accessible_members_of (P3293R2)
enumerators_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, ...
12. (+) Type Traits
(+ Other Type Predicates)
5. substitute (template)
6. reflect Invoke (template)
7. extract<T>(info) (constexpr not required)
8. test_type(s) ("is_same")
9. reflect_x (extended)
reflect_constant
reflect_object
reflect_function
auto rexpr = ^ int;
# Slide 11
P2996
AKA Unibrow
^
auto rexpr = ^^int;
# Slide 12
error: meta type variables must be constexpr
constexpr auto rexpr = ^^int;
P2996
# Slide 13
constexpr auto rexpr = ^^int;
typename[:rexpr:] a = 42;
What are you?
rexpr
meta::info obj, contains info on "int" type
typename[:rexpr:]
int
P2996
* More about the typename in P2996/[dcl.type.splice]
# Slide 14
P2996
Reflection Operator: ^^
Splicers: [:
…:]
std::meta::info
Metafunctions
Name & Location:
3. Template Queries:
10. define_aggregate (inject)
identifier_of
display_string_of
source_location_of
template_of
template_arguments_of
11. Data Layout:
4. Member Queries:
offset_of -> member_offset
size_of
alignment_of
bit_size_of
2. Type Queries:
members_of, bases_of
(non)static_data_members_of
accessible_members_of (P3293R2)
enumerators_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, ...
12. (+) Type Traits
(+ Other Type Predicates)
5. substitute (template)
6. reflect Invoke (template)
7. extract<T>(info) (constexpr not required)
8. test_type(s) ("is_same")
9. reflect_x (extended)
reflect_constant
reflect_object
reflect_function
# Slide 15
From: "Let's talk about abstraction layers"
P2996
# Slide 16
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 17
#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/cafxMPo4o
# Slide 18
P2996
Reflection Operator: ^^
Splicers: [:
…:]
std::meta::info
Metafunctions
Name & Location:
3. Template Queries:
10. define_aggregate (inject)
identifier_of
display_string_of
source_location_of
template_of
template_arguments_of
11. Data Layout:
4. Member Queries:
offset_of -> member_offset
size_of
alignment_of
bit_size_of
2. Type Queries:
members_of, bases_of
(non)static_data_members_of
accessible_members_of (P3293R2)
enumerators_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, ...
12. (+) Type Traits
(+ Other Type Predicates)
5. substitute (template)
6. reflect Invoke (template)
7. extract<T>(info) (constexpr not required)
8. test_type(s) ("is_same")
9. reflect_x (extended)
reflect_constant
reflect_object
reflect_function
# Slide 19
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
https://godbolt.org/z/9YW4bWGM7
constexpr auto a = 42;
std::cout << meta::identifier_of(^^a) << "\n";
# Slide 20
P2996
constexpr auto rexpr1 =
substitute(^^std::array, {^^int, reflect_value(3)});
typename[:rexpr1:] myArr1; // std::array<int, 3> myArr1
constexpr auto rexpr2 =
substitute(^^S, {^^int, 3});
typename[:rexpr2:] myArr2; // Fail
# Slide 21
P2996
constexpr auto expr1 =
extract<int>(reflect_value(3)); // OK
constexpr auto expr2 =
extract<int>(reflect_value("3")); // Fail
# Slide 22
P2996
# Slide 23
#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
}
https://godbolt.org/z/M84Ea6P88
Based on example from P3096
P2996
# Slide 24
P2996
# Slide 25
#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(identifier_of(type).data());
for (auto r : nonstatic_data_members_of(type))
{
std::__report_constexpr_value("\n\tmember:");
std::__report_constexpr_value(identifier_of(r).data());
}
return true;
}
// User code
static_assert(LogMembers(^^Student));
https://godbolt.org/z/Yddfxdq8j
Reflection-Based Library
Based on example from EDG's CE implementation
#include <string>
struct Student
{
std::string name;
int id;
};
https://drive.google.com/file/d/1SHDgRAqchwQXMopUecq0Ot5HCYYrKXta/view?usp=sharing
# 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
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 28
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
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 30
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 31
Pipeline Integration
AppCode
LoggerLib
Compiler
LoggerLib.o
AppCode.o
Linker
version / macros
main.out
# Slide 32
Pipeline Integration
main.out
Linker
main.o
AppCode
LoggerLib
Compiler
version / macros
Linker
OldAppCode
LoggerLib
Compiler
version / macros
Backward Compatibility
# Slide 33
Summary
Generate "MyTypeSerializer" class in a header (you can add .cpp file if needed), based on "MyType.h" which provide "serialize" and "deserialize" methods for "MyType", turning it into bytes buffer and back into a "MyType" class.
# Slide 34
Summary
# Slide 35
Summary
# Slide 36
Summary
# Slide 37
Summary
# Slide 38
Summary
Disclaimer: as of now...
# Slide 39
Rust's toolkit:
Summary
C++ | Rust | |
---|---|---|
Approach | Functions & traits | Token manipulation |
Failure Outcome | Ill-formed / Compile | Compile |
Error indication | constexpr exception | CT /RT / Tests |
# Slide 40
Which guarantees we provide:
Possible outcomes of "breaking the contract"
Summary
Errors at compile time:
# Slide 41
Which "reflection libs" should go into the standard library?
Would love your input!
More info:
What's Next?
# Slide 42
How will Reflection impact our code bases?
Summary
From: https://isocpp.org/std/status (by Herb Sutter)
# Slide 43
Inbal Levi
sinbal2lextra@gmail.com
linkedin.com/in/inballevi/
Thank you!
Stay in touch!
Thanks to:
Thank you for being passionate about C++!