An simple head-only static reflection library.
- Automatic reflect aggregate types.
- Use one macro to reflect non-aggregate type.
- Read/write pravite members.
- Query member number and type.
Please see cppreference if you don't known what's aggregate type.
Name | Function |
---|---|
REFLECTION(type,m0,...) | A variadic macro used to reflect non-aggregate type. |
member_count | Get member number at compiler time. |
member_types | Get member type list at compiler time. |
member_type | Get i-th member type at compiler time. |
member_offsets | Get offset in bytes of all members at run-time. |
member_offset | Get offset in bytes of i-th member at run-time. |
member_of | Get reference of i-th member of one instance. |
#include "Reflection.hpp"
- Define your type:
struct Foo
{
int a0{ 0 };
char a1{ 0 };
float a2{ 0 };
};
- Use reflection:
Foo foo{};
constexpr auto nfield_Foo = member_count<Foo>; //--> 3
using field_types_Foo = member_types<Foo>; //--> Types<int,char,float>
auto&& field_offsets_Foo = member_offsets<Foo>(); //--> std::array<size_t,3>{0,4,8}
using type_Foo_a1 = member_type<Foo, 0>; //--> char
member_of<Foo, 2>(foo) = 1; //--> foo={0,0,1}, i.e. foo.a2=1
static_assert(nfield_Foo == 3);
static_assert(std::is_same_v<field_types_Foo, Types<int, char, float>>);
static_assert(member_count<Foo> == 3);
assert((field_offsets_Foo[0] == offsetof(Foo, a0)));
assert((field_offsets_Foo[1] == offsetof(Foo, a1)));
assert((field_offsets_Foo[2] == offsetof(Foo, a2)));
assert((member_offset<Foo, 1>() == offsetof(Foo, a1)));
- Define your type and reflect it:
class Bar
{
public:
int a0{ 0 };
char a1{ 0 };
inline static constexpr auto offset_a2() { return offsetof(Bar, a2); }
inline auto get_a2()const { return a2; }
private:
float a2{ 0 };
};
REFLECTION(Bar, a0, a1, a2)
- Use reflection:
Bar bar{};
constexpr auto nfield_Bar = member_count<Bar>; //--> 3
using field_types_Bar = member_types<Bar>; //--> Types<int,char,float>
auto&& field_offsets_Bar = member_offsets<Bar>(); //--> std::array<size_t,3>{0,4,8}
using type_Bar_a1 = member_type<Bar,2>; //--> float
member_of<Bar, 2>(bar) = 1; //--> bar={0,0,1}, i.e. bar.a2=1
static_assert(nfield_Bar == 3);
static_assert(std::is_same_v<field_types_Bar, Types<int, char, float>>);
assert((field_offsets_Bar[0] == offsetof(Foo, a0)));
assert((field_offsets_Bar[1] == offsetof(Foo, a1)));
assert((field_offsets_Bar[2] == Bar::offset_a2()));
assert((member_of<Bar, 2>(bar) == bar.get_a2()));
Please see demo.cpp to get complete demostration.