Skip to content

Instantly share code, notes, and snippets.

@IwakuraRein
Created January 14, 2024 05:42
Show Gist options
  • Save IwakuraRein/f50e4b2d1ccc4ea4cdf191b478f5f41b to your computer and use it in GitHub Desktop.
Save IwakuraRein/f50e4b2d1ccc4ea4cdf191b478f5f41b to your computer and use it in GitHub Desktop.
Simple C++ Reflection with Template Specialization
#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