Created
January 14, 2024 05:42
-
-
Save IwakuraRein/f50e4b2d1ccc4ea4cdf191b478f5f41b to your computer and use it in GitHub Desktop.
Simple C++ Reflection with Template Specialization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <typeinfo> | |
#include <functional> | |
using ReflectionInfo = struct { | |
const unsigned no; | |
const char* name; | |
const std::type_info& type_info; | |
const std::size_t size; | |
}; | |
using ReflectionCallBack = std::function<void(const ReflectionInfo&, void*)>; | |
#define BEGIN_MEMBER_IMPL(C) static constexpr unsigned __reflection_begin_index {C+1};\ | |
template<unsigned x> static constexpr const ReflectionInfo& get_member_info();\ | |
template<unsigned x> auto& get_member();\ | |
template<unsigned x> auto const& get_member() const;\ | |
template<unsigned x> void __iterate(const ReflectionCallBack &);\ | |
template<> void __iterate<0xffffffffu>(const ReflectionCallBack &){}\ | |
template<unsigned x> void __iterate(ReflectionCallBack &&);\ | |
template<> void __iterate<0xffffffffu>(ReflectionCallBack &&){}\ | |
#define END_MEMBER_IMPL(C) static constexpr unsigned __reflection_end_index {C-1};\ | |
void iterate_members(const ReflectionCallBack &f) { __iterate<C-__reflection_begin_index-1>(f); }\ | |
void iterate_members(ReflectionCallBack&& f) { __iterate<C-__reflection_begin_index-1>(f); } | |
#define MEMBER_GET_IMPL(T, X, C) template<> static constexpr const ReflectionInfo& get_member_info<C-__reflection_begin_index>() { return { C-__reflection_begin_index, #X, typeid(T), sizeof(T) }; }\ | |
template<> typename auto& get_member<C-__reflection_begin_index>() { return X; }\ | |
template<> typename auto const& get_member<C-__reflection_begin_index>() const { return X; }\ | |
template<> void __iterate<C-__reflection_begin_index>(const ReflectionCallBack &f) {\ | |
f(get_member_info<C-__reflection_begin_index>(), &this->X);\ | |
__iterate<C-__reflection_begin_index-1>(f); }\ | |
template<> void __iterate<C-__reflection_begin_index>(ReflectionCallBack &&f) {\ | |
f(get_member_info<C-__reflection_begin_index>(), &this->X);\ | |
__iterate<C-__reflection_begin_index-1>(f); }\ | |
#define MEMBER_IMPL(T, X, C) T X; \ | |
MEMBER_GET_IMPL(T, X, C); | |
#define MEMBER_IMPL(T, X, Y, C) T X {Y}; \ | |
MEMBER_GET_IMPL(T, X, C); | |
#define BEGIN_MEMBER() BEGIN_MEMBER_IMPL(__COUNTER__) | |
#define END_MEMBER() END_MEMBER_IMPL(__COUNTER__) | |
#define MEMBER(X, Y) MEMBER_IMPL(X, Y, __COUNTER__) | |
#define MEMBER(X, Y, C) MEMBER_IMPL(X, Y, C, __COUNTER__) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment