Skip to content

Instantly share code, notes, and snippets.

@netcan
Created July 31, 2020 14:58
Show Gist options
  • Save netcan/a08d2268437c79c12654144ee92197bd to your computer and use it in GitHub Desktop.
Save netcan/a08d2268437c79c12654144ee92197bd to your computer and use it in GitHub Desktop.
static reflection
/*************************************************************************
> File Name: StaticRefl.hpp
> Author: Netcan
> Descripton: StaticRefl implement
> Blog: http://www.netcan666.com
> Mail: 1469709759@qq.com
> Created Time: 2020-07-31 20:15
************************************************************************/
#include <type_traits>
#include <iostream>
#include <utility>
#include <cstddef>
#define GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
_17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, \
_33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, \
_49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, n, ...) n
#define GET_ARG_COUNT(...) GET_NTH_ARG(__VA_ARGS__, \
64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \
16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define FOR_EACH(func, ...) GET_NTH_ARG(__VA_ARGS__, \
FOR_EACH_64, FOR_EACH_63, FOR_EACH_62, FOR_EACH_61, FOR_EACH_60, FOR_EACH_59, FOR_EACH_58, FOR_EACH_57, \
FOR_EACH_56, FOR_EACH_55, FOR_EACH_54, FOR_EACH_53, FOR_EACH_52, FOR_EACH_51, FOR_EACH_50, FOR_EACH_49, \
FOR_EACH_48, FOR_EACH_47, FOR_EACH_46, FOR_EACH_45, FOR_EACH_44, FOR_EACH_43, FOR_EACH_42, FOR_EACH_41, \
FOR_EACH_40, FOR_EACH_39, FOR_EACH_38, FOR_EACH_37, FOR_EACH_36, FOR_EACH_35, FOR_EACH_34, FOR_EACH_33, \
FOR_EACH_32, FOR_EACH_31, FOR_EACH_30, FOR_EACH_29, FOR_EACH_28, FOR_EACH_27, FOR_EACH_26, FOR_EACH_25, \
FOR_EACH_24, FOR_EACH_23, FOR_EACH_22, FOR_EACH_21, FOR_EACH_20, FOR_EACH_19, FOR_EACH_18, FOR_EACH_17, \
FOR_EACH_16, FOR_EACH_15, FOR_EACH_14, FOR_EACH_13, FOR_EACH_12, FOR_EACH_11, FOR_EACH_10, FOR_EACH_9, \
FOR_EACH_8, FOR_EACH_7, FOR_EACH_6, FOR_EACH_5, FOR_EACH_4, FOR_EACH_3, FOR_EACH_2, FOR_EACH_1 ) \
(func, 0, __VA_ARGS__)
#define FOR_EACH_1(func, i, arg) func(i, arg);
#define FOR_EACH_2(func, i, arg, ...) func(i, arg); FOR_EACH_1(func, i + 1, __VA_ARGS__)
#define FOR_EACH_3(func, i, arg, ...) func(i, arg); FOR_EACH_2(func, i + 1, __VA_ARGS__)
#define FOR_EACH_4(func, i, arg, ...) func(i, arg); FOR_EACH_3(func, i + 1, __VA_ARGS__)
#define FOR_EACH_5(func, i, arg, ...) func(i, arg); FOR_EACH_4(func, i + 1, __VA_ARGS__)
#define FOR_EACH_6(func, i, arg, ...) func(i, arg); FOR_EACH_5(func, i + 1, __VA_ARGS__)
#define FOR_EACH_7(func, i, arg, ...) func(i, arg); FOR_EACH_6(func, i + 1, __VA_ARGS__)
#define FOR_EACH_8(func, i, arg, ...) func(i, arg); FOR_EACH_7(func, i + 1, __VA_ARGS__)
#define FOR_EACH_9(func, i, arg, ...) func(i, arg); FOR_EACH_8(func, i + 1, __VA_ARGS__)
#define FOR_EACH_10(func, i, arg, ...) func(i, arg); FOR_EACH_9(func, i + 1, __VA_ARGS__)
#define FOR_EACH_11(func, i, arg, ...) func(i, arg); FOR_EACH_10(func, i + 1, __VA_ARGS__)
#define FOR_EACH_12(func, i, arg, ...) func(i, arg); FOR_EACH_11(func, i + 1, __VA_ARGS__)
#define FOR_EACH_13(func, i, arg, ...) func(i, arg); FOR_EACH_12(func, i + 1, __VA_ARGS__)
#define FOR_EACH_14(func, i, arg, ...) func(i, arg); FOR_EACH_13(func, i + 1, __VA_ARGS__)
#define FOR_EACH_15(func, i, arg, ...) func(i, arg); FOR_EACH_14(func, i + 1, __VA_ARGS__)
#define FOR_EACH_16(func, i, arg, ...) func(i, arg); FOR_EACH_15(func, i + 1, __VA_ARGS__)
#define FOR_EACH_17(func, i, arg, ...) func(i, arg); FOR_EACH_16(func, i + 1, __VA_ARGS__)
#define FOR_EACH_18(func, i, arg, ...) func(i, arg); FOR_EACH_17(func, i + 1, __VA_ARGS__)
#define FOR_EACH_19(func, i, arg, ...) func(i, arg); FOR_EACH_18(func, i + 1, __VA_ARGS__)
#define FOR_EACH_20(func, i, arg, ...) func(i, arg); FOR_EACH_19(func, i + 1, __VA_ARGS__)
#define FOR_EACH_21(func, i, arg, ...) func(i, arg); FOR_EACH_20(func, i + 1, __VA_ARGS__)
#define FOR_EACH_22(func, i, arg, ...) func(i, arg); FOR_EACH_21(func, i + 1, __VA_ARGS__)
#define FOR_EACH_23(func, i, arg, ...) func(i, arg); FOR_EACH_22(func, i + 1, __VA_ARGS__)
#define FOR_EACH_24(func, i, arg, ...) func(i, arg); FOR_EACH_23(func, i + 1, __VA_ARGS__)
#define FOR_EACH_25(func, i, arg, ...) func(i, arg); FOR_EACH_24(func, i + 1, __VA_ARGS__)
#define FOR_EACH_26(func, i, arg, ...) func(i, arg); FOR_EACH_25(func, i + 1, __VA_ARGS__)
#define FOR_EACH_27(func, i, arg, ...) func(i, arg); FOR_EACH_26(func, i + 1, __VA_ARGS__)
#define FOR_EACH_28(func, i, arg, ...) func(i, arg); FOR_EACH_27(func, i + 1, __VA_ARGS__)
#define FOR_EACH_29(func, i, arg, ...) func(i, arg); FOR_EACH_28(func, i + 1, __VA_ARGS__)
#define FOR_EACH_30(func, i, arg, ...) func(i, arg); FOR_EACH_29(func, i + 1, __VA_ARGS__)
#define FOR_EACH_31(func, i, arg, ...) func(i, arg); FOR_EACH_30(func, i + 1, __VA_ARGS__)
#define FOR_EACH_32(func, i, arg, ...) func(i, arg); FOR_EACH_31(func, i + 1, __VA_ARGS__)
#define FOR_EACH_33(func, i, arg, ...) func(i, arg); FOR_EACH_32(func, i + 1, __VA_ARGS__)
#define FOR_EACH_34(func, i, arg, ...) func(i, arg); FOR_EACH_33(func, i + 1, __VA_ARGS__)
#define FOR_EACH_35(func, i, arg, ...) func(i, arg); FOR_EACH_34(func, i + 1, __VA_ARGS__)
#define FOR_EACH_36(func, i, arg, ...) func(i, arg); FOR_EACH_35(func, i + 1, __VA_ARGS__)
#define FOR_EACH_37(func, i, arg, ...) func(i, arg); FOR_EACH_36(func, i + 1, __VA_ARGS__)
#define FOR_EACH_38(func, i, arg, ...) func(i, arg); FOR_EACH_37(func, i + 1, __VA_ARGS__)
#define FOR_EACH_39(func, i, arg, ...) func(i, arg); FOR_EACH_38(func, i + 1, __VA_ARGS__)
#define FOR_EACH_40(func, i, arg, ...) func(i, arg); FOR_EACH_39(func, i + 1, __VA_ARGS__)
#define FOR_EACH_41(func, i, arg, ...) func(i, arg); FOR_EACH_40(func, i + 1, __VA_ARGS__)
#define FOR_EACH_42(func, i, arg, ...) func(i, arg); FOR_EACH_41(func, i + 1, __VA_ARGS__)
#define FOR_EACH_43(func, i, arg, ...) func(i, arg); FOR_EACH_42(func, i + 1, __VA_ARGS__)
#define FOR_EACH_44(func, i, arg, ...) func(i, arg); FOR_EACH_43(func, i + 1, __VA_ARGS__)
#define FOR_EACH_45(func, i, arg, ...) func(i, arg); FOR_EACH_44(func, i + 1, __VA_ARGS__)
#define FOR_EACH_46(func, i, arg, ...) func(i, arg); FOR_EACH_45(func, i + 1, __VA_ARGS__)
#define FOR_EACH_47(func, i, arg, ...) func(i, arg); FOR_EACH_46(func, i + 1, __VA_ARGS__)
#define FOR_EACH_48(func, i, arg, ...) func(i, arg); FOR_EACH_47(func, i + 1, __VA_ARGS__)
#define FOR_EACH_49(func, i, arg, ...) func(i, arg); FOR_EACH_48(func, i + 1, __VA_ARGS__)
#define FOR_EACH_50(func, i, arg, ...) func(i, arg); FOR_EACH_49(func, i + 1, __VA_ARGS__)
#define FOR_EACH_51(func, i, arg, ...) func(i, arg); FOR_EACH_50(func, i + 1, __VA_ARGS__)
#define FOR_EACH_52(func, i, arg, ...) func(i, arg); FOR_EACH_51(func, i + 1, __VA_ARGS__)
#define FOR_EACH_53(func, i, arg, ...) func(i, arg); FOR_EACH_52(func, i + 1, __VA_ARGS__)
#define FOR_EACH_54(func, i, arg, ...) func(i, arg); FOR_EACH_53(func, i + 1, __VA_ARGS__)
#define FOR_EACH_55(func, i, arg, ...) func(i, arg); FOR_EACH_54(func, i + 1, __VA_ARGS__)
#define FOR_EACH_56(func, i, arg, ...) func(i, arg); FOR_EACH_55(func, i + 1, __VA_ARGS__)
#define FOR_EACH_57(func, i, arg, ...) func(i, arg); FOR_EACH_56(func, i + 1, __VA_ARGS__)
#define FOR_EACH_58(func, i, arg, ...) func(i, arg); FOR_EACH_57(func, i + 1, __VA_ARGS__)
#define FOR_EACH_59(func, i, arg, ...) func(i, arg); FOR_EACH_58(func, i + 1, __VA_ARGS__)
#define FOR_EACH_60(func, i, arg, ...) func(i, arg); FOR_EACH_59(func, i + 1, __VA_ARGS__)
#define FOR_EACH_61(func, i, arg, ...) func(i, arg); FOR_EACH_60(func, i + 1, __VA_ARGS__)
#define FOR_EACH_62(func, i, arg, ...) func(i, arg); FOR_EACH_61(func, i + 1, __VA_ARGS__)
#define FOR_EACH_63(func, i, arg, ...) func(i, arg); FOR_EACH_62(func, i + 1, __VA_ARGS__)
#define FOR_EACH_64(func, i, arg, ...) func(i, arg); FOR_EACH_63(func, i + 1, __VA_ARGS__)
#define STR(x) #x
#define STRING(x) STR(x)
#define PARE(...) __VA_ARGS__
#define EAT(...)
#define PAIR(x) PARE x // PAIR((int) x) => PARE(int) x => int x
#define STRIP(x) EAT x // STRIP((int) x) => EAT(int) x => x
#define FIELD_EACH(i, arg) \
PAIR(arg); \
template <typename T> \
struct FIELD<T, i> { \
T& obj; \
FIELD(T& obj): obj(obj) {} \
auto value() -> decltype(auto) { \
return (obj.STRIP(arg)); \
} \
static constexpr const char* name() { \
return STRING(STRIP(arg)); \
} \
} \
#define DEFINE_STRUCT(st, ...) \
struct st { \
template <typename, size_t> struct FIELD; \
static constexpr size_t _field_count_ = GET_ARG_COUNT(__VA_ARGS__); \
FOR_EACH(FIELD_EACH, __VA_ARGS__) \
}; \
template<typename T, typename F, size_t... Is>
inline constexpr void forEach(T&& obj, F&& f, std::index_sequence<Is...>) {
using TDECAY = std::decay_t<T>;
(void(f(typename TDECAY::template FIELD<TDECAY, Is>(obj).name(),
typename TDECAY::template FIELD<TDECAY, Is>(obj).value())), ...);
}
template<typename T, typename F>
inline constexpr void forEach(T&& obj, F&& f) {
forEach(std::forward<T>(obj),
std::forward<F>(f),
std::make_index_sequence<std::decay_t<T>::_field_count_>{});
}
template<typename T>
void dumpObj(T&& obj, const char* fieldName = "", int depth = 0) {
auto indent = [depth] {
for (int i = 0; i < depth; ++i) {
std::cout << " ";
}
};
if constexpr(std::is_class_v<std::decay_t<T>>) {
indent();
std::cout << fieldName << (*fieldName ? ": {" : "{") << std::endl;
forEach(obj, [depth](auto&& fieldName, auto&& value) {
dumpObj(value, fieldName, depth + 1);
});
indent();
std::cout << "}" << (depth == 0 ? "" : ",") << std::endl;
} else {
indent();
std::cout << fieldName << ": " << obj << "," << std::endl;
}
}
DEFINE_STRUCT(Point,
(double) x,
(double) y)
DEFINE_STRUCT(Rect,
(Point) p1,
(Point) p2,
(uint32_t) color)
int main(int argc, char** argv) {
Rect rect {
{1.2, 3.4},
{5.6, 7.8},
12345678,
};
dumpObj(rect);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment