Welcome to v1.0 of the meta::[[verse]]!

# Slide 1
# Slide 2
  • C++ Software Engineer, OS Internals, Microsoft
  • 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

https://slides.com/inballevi/welcome-to-v1-0-of-the-meta-verse-pure-virtual/

Reflection in C++

# Slide 3
  • The ability of software to expose its internal structure
  • Static reflection - compiler exposes structure at compile time
     
  • Disclaimers:
    • It's 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:
    1. A brief history of "Reflection" proposals in C++
    2. Latest proposal: "P2996: Reflection for C++26"
    3. The complexity of reflection
  • Part II: Impact on our code bases
    1. Reflection-based libraries
    2. What's next?

(*) Examples from or derive from P2996, or EDG's implementation

2006

Template-based reflection
(Matúš Chochlik)
Mirror reflection library

2012

N3403: Use Cases for Compile-Time Reflection
(Mike Spertus)

# Slide 5

2014 - 2016

N3996: Static reflection (Matúš Chochlik)

N4113, N4239, N4027, N3984
(type traits, attributes, etc.)

2015

Boost.Hana
(Louis Dionne)
Template  metaprog. lib

A Brief History

2018

P0954: What do we want to do with reflection?
(Bjarne)

2017

P0194|P0385: Static Reflection
(Matúš, Axel, David)
P0590: A design for static reflection
(Andrew, Herb)
P0633: Exploring the design space
(Daveed, Louis)

2018

N4747: Reflection TS
(David)

# Slide 6

2018

P0993: Value-based reflection
(Andrew, Herb)
P1240: Scalable Reflection in C++
(Andrew, Faisal, Daveed)

2019

P0953: constexpr reflexpr
(Matúš, Axel, David)
P1733: User-friendly and Evolution-friendly Reflection: A Compromise
(David, Daveed)

A Brief History

Typefull
vs.
Monotype

Type based
vs.
Value based

meta objects

2020

P2087: Reflection Naming: fix reflexpr
(Mihail Naydenov)
P2040: Reflection-based lazy-evaluation
(Corentin)

2021

P2320: The Syntax of Static Reflection
(Andrew, Wyatt, Daveed)
(+ implementation: lock3 meta)

2023

P2996: Reflection for C++26
(Barry, Wyatt, Peter, Andrew, Faisal, Daveed)

2022

P2560: Comparing Value- and type- based reflection
(Matus)

# Slide 7

2023

P2911: Python Bindings (...)
(Adam, Jagrut)
P3010: Using reflection (...) JS Bindings
(Dan Katz)

A Brief History

2025

P2996R11
(+Dan Katz)

(1.5 years later)

# 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;
   constexpr auto res = std::meta::bases_of(refexpr)[0];
}

https://godbolt.org/z/WxdvKdcMY

# Slide 9

P2996: Reflection for C++26

P2996
  1. Reflection Operator: ^^

  2. Splicers: [::]

  3. std::meta::info

  4. Metafunctions

8. define_aggregate (inject)

  1. Name & Location:

3. Template Queries:

  1. identifier_of

  2. display_string_of

  3. source_location_of

  1. template_of

  2. template_arguments_of

9. Data Layout:

​4. Member Queries:

  1. offset_of -> member_offset

  2. size_of

  3. alignment_of

  4. bit_size_of

​2. Type Queries:

  1. members_of, bases_of

  2. (non)static_data_members_of

  3. enumerators_of

  1. type_of

  2. parent_of

  3. dealias
     

  4. Access modifiers: is_public, is_protected, is_private

  5. Inheritance: is_virtual, is_pure_virtual, is_override, ...

  6. Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...

  7. Advanced Type Queries: is_complete_type, is_template, is_special_member, ...

10. (+) Type Traits

(+ Other Type Predicates)

5. substitute (template)

6. extract<T>(info) (constexpr not required)

7. reflect_x (extended)

  1. reflect_value

  2. reflect_object

  3. reflect_function

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

* More about the typename in P2996/[dcl.type.splice]

# Slide 13

P2996: Reflection for C++26

P2996
  1. Reflection Operator: ^^

  2. Splicers: [::]

  3. std::meta::info

  4. Metafunctions

8. define_aggregate (inject)

  1. Name & Location:

3. Template Queries:

  1. identifier_of

  2. display_string_of

  3. source_location_of

  1. template_of

  2. template_arguments_of

9. Data Layout:

​4. Member Queries:

  1. offset_of -> member_offset

  2. size_of

  3. alignment_of

  4. bit_size_of

​2. Type Queries:

  1. members_of, bases_of

  2. (non)static_data_members_of

  3. enumerators_of

  1. type_of

  2. parent_of

  3. dealias
     

  4. Access modifiers: is_public, is_protected, is_private

  5. Inheritance: is_virtual, is_pure_virtual, is_override, ...

  6. Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...

  7. Advanced Type Queries: is_complete_type, is_template, is_special_member, ...

10. (+) Type Traits

(+ Other Type Predicates)

5. substitute (template)

6. extract<T>(info) (constexpr not required)

7. reflect_x (extended)

  1. reflect_value

  2. reflect_object

  3. reflect_function

# Slide 14

std::meta::info

From: "Let's talk about abstraction layers"

P2996
# Slide 15

std::meta::info

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

Represents:

  • Type and type alias
  • Function or member function
  • Variable, static data member, or structured binding
  • Non-static data member
  • Enumerators
  • Object that is a permitted result of a constant expression
  • Value with structural type that is a permitted result of a const evaluation
  • Template
  • Namespaces, namespace alias
# Slide 16

P2996: Reflection for C++26

  1. Reflection Operator: ^^

  2. Splicers: [::]

  3. std::meta::info

  4. Metafunctions

P2996

8. define_aggregate (inject)

  1. Name & Location:

3. Template Queries:

  1. identifier_of

  2. display_string_of

  3. source_location_of

  1. template_of

  2. template_arguments_of

9. Data Layout:

​4. Member Queries:

  1. offset_of -> member_offset

  2. size_of

  3. alignment_of

  4. bit_size_of

​2. Type Queries:

  1. members_of, bases_of

  2. (non)static_data_members_of

  3. enumerators_of

  1. type_of

  2. parent_of

  3. dealias
     

  4. Access modifiers: is_public, is_protected, is_private

  5. Inheritance: is_virtual, is_pure_virtual, is_override, ...

  6. Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...

  7. Advanced Type Queries: is_complete_type, is_template, is_special_member, ...

10. (+) Type Traits

(+ Other Type Predicates)

5. substitute (template)

6. extract<T>(info) (constexpr not required)

7. reflect_x (extended)

  1. reflect_value

  2. reflect_object

  3. reflect_function

# Slide 17

Metafunctions

constexpr auto a = 42;
std::cout << meta::name_of(^^a) << "\n";

All* the metafunctions accept "info" and return:

  1. string_view (e.g. identifier_of)
  2. std::meta::info (e.g. type_of)
  3. vector<std::meta::info> (e.g. bases_of)
  4. bool (e.g. is_concept)
  5. size_t (e.g. alignment_of)
  6. T (e.g. extract(info))
  7. source_location, member_offset (e.g. offset_of)

* Besides "reflect_value/object/function", which accepts type T

https://godbolt.org/z/9YW4bWGM7

constexpr auto a = 42;
std::cout << meta::identifier_of(^^a) << "\n";
P2996
# Slide 18

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

https://godbolt.org/z/cafxMPo4o

Complexity of Reflection
# 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
Complexity of Reflection
# Slide 20
  • 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();
};
Complexity of Reflection
# Slide 21

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(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
struct Student 
{
  std::string name;
  int id;
};

static_assert(LogMembers(^^Student));
Reflection-Based Library

Based on example from EDG's CE implementation

https://godbolt.org/z/Yddfxdq8j

# Slide 22

Detour: But what about AI?

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 23

Detour: But what about AI?

Summary
# Slide 24

Detour: But what about AI?

Summary
# Slide 25

Detour: But what about AI?

  • LLMs are trained on data to create weights
  • Algorithm aims for the "most fitting" result
  • There's non-determinism inherently in the process
  • Definetly with new models / versions

 

             

Summary

(Disclaimer: as of now...)

No guarantees between executions

# Slide 26

Detour: But what about "Rust"?

Rust's toolkit:

  1. "macros" - variadic, used as templates, expend pre-compiler
  2. "syn" - library for injecting tokens into the AST
  3. "procedural macro" - used to process AST into AST
Summary
C++ Rust
Approach Functions / traits Token manipulation
Failure Outcome Ill-formed / Compile Compile
Error indication constexpr exception Runtime / tests
# Slide 27

What should we expect from "reflection libraries"?

Guarantees we do not provide:

The outcome of "breaking the contract":

  1. The outcome of failures:
    1. Program is ill-formed (fails to compile)
    2. Program contains UB (undefined behavior)
  2. Errors at compile time:
    • Should indicate to "reflection" stage (NOT "old" compilation)
    • Throw constexpr exceptions (Thanks to Hana Dusíková!)
  3. Warnings: Which level of feedback is given to correct mistakes?
Summary
  1. No compatibility between standard versions
  2. No backward compatibility for source code
  3. No guarantees for existing code
# Slide 28

Summary

Which "reflection libs" should go into the standard library?

Would love your input!

More info:

  1. A brief history of "Reflection" proposals in C++
  2. Latest proposal: "P2996: Reflection for C++26"
  3. The complexity of reflection
  4. Reflection-based libraries
  5. What's next?
Summary
# Slide 29

Thank you!

Inbal Levi
sinbal2lextra@gmail.com

linkedin.com/in/inballevi/

Thank you!

Stay in touch!

Thanks to:

  • CoreC++ user group
  • Hana Dusíková (SG7 chair)
  • Matus Chochlik
  • David Sankel
  • Corentin Jabot
  • Lewis Baker
  • 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 v1.0 of the meta::[[verse]] - Pure Virtual

By Inbal Levi

Welcome to v1.0 of the meta::[[verse]] - Pure Virtual

  • 177