Static reflection for C++17 (compile-time enumeration, attributes, proxies, overloads, template functions, metaprogramming).
refl-cpp is a header-only library which provides compile-time reflection and introspection capabilities to C++. By encoding type metadata in the type system, refl-cpp allows you to process types and their fields and functions via constexpr and template metaprogramming.
Using refl-cpp in your project? I want to hear about it: contact me by email (see my profile), open an issue or add the #refl-cpp tag to your topics!
Have a question? Try asking in the Gitter channel.
Want to support refl-cpp? Consider making a donation.
refl-cpp aims to provide a generic reflection system that is flexible enough to suit your needs while maintaining a relatively small API surface.
Some nice things refl-cpp supports out-of-the-box:
std::tuple
s associated with types and member descriptorsproxy<T>
types with the same members as T
that can be used to wrap or extend functionalityImplement a simple serialization system - example-serialization.cpp - View in Compiler Explorer
Implements an efficient generic serialization procedure from scratch
Simple SQL database abstraction - example-dao.cpp - View in Compiler Explorer
Implements a basic ORM system which can generate SQL statements at compile-time from model classes using custom properties
Iterate base classes with bases<>
- example-inheritance.cpp - View in Compiler Explorer
Uses the built-in bases<>
attribute to iterate over a type’s base classes
Access reflection information at runtime - example-custom-rtti.cpp - View in Compiler Explorer
Implements a basic runtime abstraction over refl-cpp which provides access to the reflection metadata at runtime via custom metadata objects
XML-based GUI with strongly-types properties - example-binding.cpp - View in Compiler Explorer
Implements a system for reading XML resources with refl-cpp, by building a custom runtime reflection layer on top of refl-cpp
Implement a generic builder class factory - example-builders.cpp - View in Compiler Explorer
Defines a generic builder<T>
class, which implements the builder pattern for any type T
.
Convert fields to accessor methods - example-proxy.cpp - View in Compiler Explorer
Uses the proxy feature to create a generic type value_proxy<T>
which exposes all fields of T
through accessors methods
View an array of structs as a struct of arrays - example-struct-of-arrays.cpp - View in Compiler Explorer
Uses the proxy feature to create a generic type struct_of_arrays<T>
which stores all members of T
in std::vector
, but also has an T operator[](int)
which constructs the individual objects on-demand
Generate a struct of std::optional
members - example-partials.cpp - View in Compiler Explorer
Uses the proxy feature to create a generic type partial<T>
which wraps all members of T
in std::optional
I started developing refl-cpp during my final year in high-school. I was supposed to be studying for exams, but I had just read the original Static Reflection (2017) proposal, and after realising that it wasn’t coming anytime soon, I decided that I had to try to cram as many of those features at possible into a compile-time library.
The library has grown and changed a lot since the early days, but even after several years, I still haven’t seen another reflection library that supports constexpr and template metaprogramming. With other libraries, you often have to walk a metadata structure at runtime, invoke function pointers, and use type-erasure. With refl-cpp, you process the type metadata at compile-time, via for_each
loops, all the types are there, and the compiler can often inline everything and generate the same code that you would have hand-written.
All utility functions in refl-cpp are constexpr (except the ones in refl::runtime
). Compilers will generally inline all loops and other constructs (when using -O2
) and generate code that runs just as fast as if it was hand-written.
Thanks to some special compile-time optimisations, type metadata is generally not instantiated (no code-gen needs to happen) when the types themselves are not used in reflection. With 0.12.2, there have also been some major reductions in compilation time when using properties #60.
That being said, a word of caution: I have observed that after around the 250 reflected members mark, compilation times start to grow rapidly. If your codebase contains lots of huge classes (+250 functions), and you need to have all of them reflected with refl-cpp
, this might be a deal breaker - benchmark before using.
To use refl-cpp as a single-header library, copy include/refl.hpp
to your include directory.
You can also consume refl-cpp as a CMake dependecy (3.14+ required, thanks @friendlyanon).
vcpkg install refl-cpp
(thanks @Vennor)conan install refl-cpp
The online documentation is built with Doxygen. Run doxygen Doxyfile
in docs/
to update it.
Run CMake with -Drefl-cpp_DEVELOPER_MODE=ON
and make the refl-cpp-tests
target.
Run CMake with -Drefl-cpp_DEVELOPER_MODE=ON
flag. You may also want to setup a custom preset for a more convenient developer experience (see this comment on #44).