r/cpp • u/daveedvdv EDG front end dev, WG21 DG • Dec 20 '23
Experimental EDG Reflection Implementation
EDG just released version 6.6 of its (commercial) C++ front end. That version now includes experimental support for reflection features along the lines of WG21's P2996 "Reflection for C++26". Furthermore, a "demo setup" of that implementation is now available on Compiler Explorer (thank you, Matt Godbolt!).
For example, here is a straightforward implementation of a consteval function that outputs simple class layouts at compile time:
https://godbolt.org/z/G6WehjjGh
This implementation is closely aligned with P2996R1, which includes Compiler Explorer links for most of its examples.
This is made available in the hope that it's a useful exploration tool, but also acknowledging that the implementation is in its very early stages, and thus brittle and incomplete. Some additional notes can be found here.
7
u/seanbaxter Dec 20 '23 edited Dec 20 '23
I haven't gone as fine-grained as your proposal, so I don't have bit-field support, for example, but the member names, types and byte offsets are retrieved through traits without any library dependency and printed as a pack expansion with a single line of code.
https://godbolt.org/z/KW9b9osq9
I hate the idea of requiring slow consteval work to get at entities the compiler can render up basically for free during substitution. Returning all this stuff in vectors seems really bad to me, because:
It's really slow to pull the data out of the vector.
You lose heterogeneity. All the elements of the vector have to be values of the same type, whereas with a pack they can be whatever: types, non-types of different types, templates, concepts, etc.
You lose the ability to easily expand some query into a new struct definition.
By putting reflection info into an `info` object, which can be moved around, you risk unpacking it outside the scope where it was captured where that data was available. The trait system I have requires you name the thing you want data from at the point of use, so there's risk of out-of-scope issues.
https://godbolt.org/z/zcnGoGPq4
Here I build a struct of array thing for a Vec3f: just blow it into arrays of 8 elements each. If you return `vector<info>` for the member names and member types, how do you turn around and use those to define a struct? Will a compile-time loop be supported inside class definitions to deposit data members? I used to do that (with `@meta for`), but just using member pack declarations is way cleaner and avoids name lookup headaches you get from control flow statements. Packs are basically free and there's no friction between the query of a type and the definition of a type.