更新:1、新增数据记录功能,将过程数据录入数据库;
2、增加输入点迹数据、凝聚后点迹数据记录; Signed-off-by: waiwaylee <waiwaylee@foxmail.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "common_macro.hpp"
|
||||
|
||||
#define YLT_MACRO_EXPAND(...) __VA_ARGS__
|
||||
|
||||
#define WRAP_ARGS0(w, o)
|
||||
#define WRAP_ARGS1(w, o, _1) w(o, _1)
|
||||
#include "generate/arg_list_macro_gen.hpp"
|
||||
|
||||
#define WRAP_ARGS_(w, object, ...) \
|
||||
YLT_CONCAT(WRAP_ARGS, YLT_ARG_COUNT(__VA_ARGS__)) \
|
||||
(w, object, ##__VA_ARGS__)
|
||||
#define WRAP_ARGS(w, object, ...) WRAP_ARGS_(w, object, ##__VA_ARGS__)
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#define YLT_CONCAT_(l, r) l##r
|
||||
|
||||
#define YLT_CONCAT(l, r) YLT_CONCAT_(l, r)
|
||||
|
||||
#define CONCAT_MEMBER(t, x) t.x
|
||||
|
||||
#define CONCAT_ADDR(T, x) &T::x
|
||||
|
||||
#define CONCAT_NAME(t, x) #x
|
||||
|
||||
namespace ylt::reflection {
|
||||
template <typename T>
|
||||
struct identity {};
|
||||
} // namespace ylt::reflection
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
// clang-format off
|
||||
|
||||
/*The following boilerplate code was generated using a Python script:
|
||||
max_fields = 124
|
||||
macro = "#define WRAP_ARGS"
|
||||
with open("generated_args.txt", "w", encoding="utf-8") as codefile:
|
||||
codefile.write("#ifdef _MSC_VER // Microsoft compilers\n\n")
|
||||
codefile.write("#define __NARGS(")
|
||||
codefile.write(
|
||||
",".join(['_{}'.format(num) for num in range(1, max_fields+2)])
|
||||
)
|
||||
codefile.write(", N, ...) N\n")
|
||||
codefile.write("#define NARGS_1(...) YLT_MACRO_EXPAND(__NARGS(__VA_ARGS__,")
|
||||
codefile.write(
|
||||
",".join(['{}'.format(num) for num in range(max_fields,-1,-1)])
|
||||
)
|
||||
codefile.write("))\n")
|
||||
codefile.write("#define AUGMENTER(...) unused, __VA_ARGS__\n")
|
||||
codefile.write("#define YLT_ARG_COUNT(...) NARGS_1(AUGMENTER(__VA_ARGS__))\n\n")
|
||||
codefile.write("#else // Others\n\n")
|
||||
codefile.write("#define YLT_ARG_COUNT(...) __NARGS(0, ##__VA_ARGS__,")
|
||||
codefile.write(
|
||||
",".join(['{}'.format(num) for num in range(max_fields,-1,-1)])
|
||||
)
|
||||
codefile.write(")\n")
|
||||
codefile.write("#define __NARGS(")
|
||||
codefile.write(
|
||||
",".join(['_{}'.format(num) for num in range(0,max_fields+1)])
|
||||
)
|
||||
codefile.write(", N, ...) N\n")
|
||||
codefile.write("#endif\n\n")
|
||||
codefile.write(
|
||||
"\n".join(
|
||||
[
|
||||
f"{macro}{i}(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS{i-1}(w,o,__VA_ARGS__))" for i in range(2, 126)
|
||||
]
|
||||
)
|
||||
)
|
||||
with open("generated_args.txt", "w", encoding="utf-8") as codefile:
|
||||
codefile.write("#ifdef _MSC_VER // Microsoft compilers\n\n")
|
||||
codefile.write("#define __NARGS(\n")
|
||||
codefile.write(
|
||||
",".join(['_{}'.format(num) for num in range(1, max_fields+2)])
|
||||
)
|
||||
codefile.write(", N, ...) N\n")
|
||||
codefile.write("#define NARGS_1(...) YLT_MACRO_EXPAND(__NARGS(__VA_ARGS__,")
|
||||
codefile.write(
|
||||
",".join(['{}'.format(num) for num in range(max_fields,-1,-1)])
|
||||
)
|
||||
codefile.write("))\n")
|
||||
codefile.write("#define AUGMENTER(...) unused, __VA_ARGS__\n")
|
||||
codefile.write("#define YLT_ARG_COUNT(...) NARGS_1(AUGMENTER(__VA_ARGS__))\n\n")
|
||||
codefile.write("#else // Others\n\n")
|
||||
codefile.write("#define YLT_ARG_COUNT(...) __NARGS(0, ##__VA_ARGS__,")
|
||||
codefile.write(
|
||||
",".join(['{}'.format(num) for num in range(max_fields,-1,-1)])
|
||||
)
|
||||
codefile.write(")\n")
|
||||
codefile.write("#define __NARGS(")
|
||||
codefile.write(
|
||||
",".join(['_{}'.format(num) for num in range(0,max_fields+1)])
|
||||
)
|
||||
codefile.write(", N, ...) N\n")
|
||||
codefile.write("#endif\n\n")
|
||||
codefile.write(
|
||||
"\n".join(
|
||||
[
|
||||
f"{macro}{i}(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS{i-1}(w,o,__VA_ARGS__))" for i in range(2, 126)
|
||||
]
|
||||
)
|
||||
)
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER // Microsoft compilers
|
||||
|
||||
#define __NARGS(_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,_65,_66,_67,_68,_69,_70,_71,_72,_73,_74,_75,_76,_77,_78,_79,_80,_81,_82,_83,_84,_85,_86,_87,_88,_89,_90,_91,_92,_93,_94,_95,_96,_97,_98,_99,_100,_101,_102,_103,_104,_105,_106,_107,_108,_109,_110,_111,_112,_113,_114,_115,_116,_117,_118,_119,_120,_121,_122,_123,_124,_125, N, ...) N
|
||||
#define NARGS_1(...) YLT_MACRO_EXPAND(__NARGS(__VA_ARGS__,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,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,0))
|
||||
#define AUGMENTER(...) unused, __VA_ARGS__
|
||||
#define YLT_ARG_COUNT(...) NARGS_1(AUGMENTER(__VA_ARGS__))
|
||||
|
||||
#else // Others
|
||||
|
||||
#define YLT_ARG_COUNT(...) __NARGS(0, ##__VA_ARGS__,256,255,254,253,252,251,250,249,248,247,246,245,244,243,242,241,240,239,238,237,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,213,212,211,210,209,208,207,206,205,204,203,202,201,200,199,198,197,196,195,194,193,192,191,190,189,188,187,186,185,184,183,182,181,180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165,164,163,162,161,160,159,158,157,156,155,154,153,152,151,150,149,148,147,146,145,144,143,142,141,140,139,138,137,136,135,134,133,132,131,130,129,128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,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,0)
|
||||
#define __NARGS(_0,_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,_65,_66,_67,_68,_69,_70,_71,_72,_73,_74,_75,_76,_77,_78,_79,_80,_81,_82,_83,_84,_85,_86,_87,_88,_89,_90,_91,_92,_93,_94,_95,_96,_97,_98,_99,_100,_101,_102,_103,_104,_105,_106,_107,_108,_109,_110,_111,_112,_113,_114,_115,_116,_117,_118,_119,_120,_121,_122,_123,_124,_125,_126,_127,_128,_129,_130,_131,_132,_133,_134,_135,_136,_137,_138,_139,_140,_141,_142,_143,_144,_145,_146,_147,_148,_149,_150,_151,_152,_153,_154,_155,_156,_157,_158,_159,_160,_161,_162,_163,_164,_165,_166,_167,_168,_169,_170,_171,_172,_173,_174,_175,_176,_177,_178,_179,_180,_181,_182,_183,_184,_185,_186,_187,_188,_189,_190,_191,_192,_193,_194,_195,_196,_197,_198,_199,_200,_201,_202,_203,_204,_205,_206,_207,_208,_209,_210,_211,_212,_213,_214,_215,_216,_217,_218,_219,_220,_221,_222,_223,_224,_225,_226,_227,_228,_229,_230,_231,_232,_233,_234,_235,_236,_237,_238,_239,_240,_241,_242,_243,_244,_245,_246,_247,_248,_249,_250,_251,_252,_253,_254,_255,_256, N, ...) N
|
||||
#endif
|
||||
|
||||
#define WRAP_ARGS2(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS1(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS3(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS2(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS4(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS3(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS5(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS4(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS6(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS5(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS7(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS6(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS8(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS7(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS9(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS8(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS10(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS9(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS11(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS10(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS12(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS11(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS13(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS12(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS14(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS13(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS15(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS14(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS16(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS15(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS17(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS16(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS18(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS17(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS19(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS18(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS20(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS19(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS21(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS20(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS22(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS21(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS23(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS22(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS24(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS23(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS25(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS24(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS26(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS25(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS27(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS26(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS28(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS27(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS29(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS28(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS30(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS29(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS31(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS30(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS32(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS31(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS33(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS32(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS34(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS33(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS35(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS34(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS36(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS35(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS37(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS36(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS38(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS37(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS39(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS38(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS40(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS39(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS41(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS40(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS42(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS41(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS43(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS42(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS44(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS43(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS45(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS44(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS46(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS45(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS47(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS46(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS48(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS47(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS49(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS48(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS50(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS49(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS51(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS50(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS52(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS51(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS53(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS52(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS54(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS53(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS55(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS54(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS56(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS55(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS57(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS56(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS58(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS57(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS59(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS58(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS60(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS59(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS61(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS60(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS62(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS61(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS63(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS62(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS64(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS63(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS65(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS64(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS66(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS65(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS67(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS66(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS68(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS67(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS69(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS68(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS70(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS69(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS71(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS70(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS72(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS71(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS73(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS72(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS74(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS73(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS75(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS74(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS76(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS75(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS77(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS76(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS78(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS77(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS79(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS78(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS80(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS79(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS81(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS80(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS82(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS81(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS83(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS82(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS84(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS83(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS85(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS84(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS86(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS85(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS87(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS86(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS88(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS87(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS89(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS88(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS90(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS89(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS91(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS90(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS92(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS91(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS93(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS92(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS94(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS93(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS95(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS94(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS96(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS95(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS97(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS96(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS98(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS97(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS99(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS98(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS100(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS99(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS101(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS100(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS102(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS101(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS103(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS102(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS104(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS103(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS105(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS104(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS106(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS105(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS107(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS106(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS108(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS107(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS109(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS108(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS110(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS109(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS111(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS110(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS112(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS111(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS113(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS112(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS114(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS113(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS115(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS114(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS116(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS115(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS117(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS116(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS118(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS117(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS119(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS118(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS120(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS119(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS121(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS120(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS122(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS121(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS123(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS122(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS124(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS123(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS125(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS124(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS126(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS125(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS127(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS126(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS128(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS127(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS129(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS128(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS130(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS129(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS131(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS130(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS132(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS131(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS133(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS132(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS134(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS133(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS135(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS134(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS136(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS135(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS137(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS136(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS138(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS137(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS139(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS138(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS140(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS139(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS141(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS140(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS142(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS141(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS143(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS142(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS144(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS143(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS145(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS144(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS146(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS145(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS147(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS146(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS148(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS147(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS149(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS148(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS150(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS149(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS151(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS150(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS152(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS151(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS153(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS152(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS154(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS153(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS155(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS154(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS156(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS155(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS157(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS156(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS158(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS157(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS159(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS158(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS160(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS159(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS161(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS160(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS162(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS161(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS163(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS162(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS164(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS163(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS165(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS164(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS166(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS165(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS167(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS166(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS168(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS167(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS169(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS168(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS170(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS169(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS171(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS170(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS172(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS171(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS173(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS172(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS174(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS173(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS175(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS174(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS176(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS175(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS177(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS176(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS178(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS177(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS179(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS178(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS180(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS179(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS181(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS180(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS182(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS181(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS183(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS182(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS184(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS183(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS185(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS184(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS186(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS185(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS187(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS186(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS188(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS187(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS189(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS188(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS190(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS189(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS191(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS190(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS192(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS191(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS193(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS192(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS194(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS193(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS195(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS194(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS196(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS195(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS197(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS196(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS198(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS197(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS199(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS198(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS200(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS199(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS201(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS200(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS202(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS201(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS203(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS202(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS204(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS203(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS205(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS204(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS206(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS205(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS207(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS206(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS208(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS207(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS209(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS208(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS210(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS209(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS211(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS210(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS212(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS211(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS213(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS212(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS214(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS213(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS215(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS214(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS216(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS215(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS217(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS216(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS218(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS217(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS219(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS218(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS220(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS219(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS221(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS220(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS222(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS221(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS223(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS222(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS224(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS223(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS225(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS224(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS226(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS225(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS227(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS226(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS228(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS227(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS229(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS228(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS230(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS229(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS231(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS230(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS232(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS231(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS233(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS232(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS234(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS233(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS235(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS234(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS236(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS235(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS237(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS236(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS238(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS237(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS239(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS238(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS240(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS239(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS241(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS240(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS242(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS241(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS243(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS242(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS244(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS243(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS245(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS244(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS246(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS245(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS247(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS246(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS248(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS247(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS249(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS248(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS250(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS249(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS251(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS250(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS252(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS251(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS253(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS252(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS254(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS253(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS255(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS254(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS256(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS255(w,o,__VA_ARGS__))
|
||||
#define WRAP_ARGS257(w,o,_1, ...) w(o, _1),YLT_MACRO_EXPAND(WRAP_ARGS256(w,o,__VA_ARGS__))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,224 @@
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#if __has_include(<ylt/util/expected.hpp>)
|
||||
#include <ylt/util/expected.hpp>
|
||||
#else
|
||||
#include "iguana/ylt/util/expected.hpp"
|
||||
#endif
|
||||
|
||||
#include "reflect26_compat.hpp"
|
||||
#include "user_reflect_macro.hpp"
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#include "reflect26_core.hpp"
|
||||
#endif
|
||||
namespace struct_pack {
|
||||
template <typename T, uint64_t version>
|
||||
struct compatible;
|
||||
}
|
||||
namespace ylt::reflection {
|
||||
template <typename T>
|
||||
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
|
||||
#if __cpp_concepts >= 201907L
|
||||
template <typename Type>
|
||||
concept expected = requires(Type e) {
|
||||
typename remove_cvref_t<Type>::value_type;
|
||||
typename remove_cvref_t<Type>::error_type;
|
||||
typename remove_cvref_t<Type>::unexpected_type;
|
||||
e.has_value();
|
||||
e.error();
|
||||
requires std::is_same_v<void, typename remove_cvref_t<Type>::value_type> ||
|
||||
requires(Type e) {
|
||||
e.value();
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename T, typename = void>
|
||||
struct expected_impl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct expected_impl<T, std::void_t<typename remove_cvref_t<T>::value_type,
|
||||
typename remove_cvref_t<T>::error_type,
|
||||
typename remove_cvref_t<T>::unexpected_type,
|
||||
decltype(std::declval<T>().has_value()),
|
||||
decltype(std::declval<T>().error())>>
|
||||
: std::true_type {};
|
||||
// TODO: check e.value()
|
||||
template <typename T>
|
||||
constexpr bool expected = expected_impl<T>::value;
|
||||
#endif
|
||||
|
||||
#if __cpp_concepts >= 201907L
|
||||
template <typename Type>
|
||||
concept optional = !expected<Type> && requires(Type optional) {
|
||||
optional.value();
|
||||
optional.has_value();
|
||||
optional.operator*();
|
||||
typename remove_cvref_t<Type>::value_type;
|
||||
};
|
||||
#else
|
||||
template <typename T, typename = void>
|
||||
struct optional_impl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct optional_impl<T, std::void_t<decltype(std::declval<T>().value()),
|
||||
decltype(std::declval<T>().has_value()),
|
||||
decltype(std::declval<T>().operator*()),
|
||||
typename remove_cvref_t<T>::value_type>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool optional = !expected<T> && optional_impl<T>::value;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct pair_impl : std::false_type {};
|
||||
|
||||
template <typename F, typename S>
|
||||
struct pair_impl<std::pair<F, S>> : std::true_type {};
|
||||
|
||||
#if __cpp_concepts >= 201907L
|
||||
template <typename T>
|
||||
concept pair = pair_impl<remove_cvref_t<T>>::value;
|
||||
#else
|
||||
template <typename T>
|
||||
constexpr bool pair = pair_impl<remove_cvref_t<T>>::value;
|
||||
#endif
|
||||
|
||||
namespace internal {
|
||||
#if __cpp_concepts >= 201907L
|
||||
template <typename Type>
|
||||
concept tuple_size = requires(Type tuple) {
|
||||
std::tuple_size<remove_cvref_t<Type>>::value;
|
||||
};
|
||||
#else
|
||||
template <typename T, typename = void>
|
||||
struct tuple_size_impl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct tuple_size_impl<
|
||||
T, std::void_t<decltype(std::tuple_size<remove_cvref_t<T>>::value)>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool tuple_size = tuple_size_impl<T>::value;
|
||||
#endif
|
||||
|
||||
template <typename Type>
|
||||
constexpr inline bool is_compatible_v = false;
|
||||
|
||||
template <typename Type, uint64_t version>
|
||||
constexpr inline bool is_compatible_v<struct_pack::compatible<Type, version>> =
|
||||
true;
|
||||
|
||||
struct UniversalVectorType {
|
||||
template <typename T>
|
||||
operator std::vector<T>();
|
||||
};
|
||||
|
||||
struct UniversalType {
|
||||
template <typename T>
|
||||
operator T();
|
||||
};
|
||||
|
||||
struct UniversalIntegralType {
|
||||
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||
operator T();
|
||||
};
|
||||
|
||||
struct UniversalNullptrType {
|
||||
operator std::nullptr_t();
|
||||
};
|
||||
|
||||
struct UniversalOptionalType {
|
||||
template <typename U, typename = std::enable_if_t<optional<U>>>
|
||||
operator U();
|
||||
};
|
||||
|
||||
struct UniversalCompatibleType {
|
||||
template <typename U, typename = std::enable_if_t<is_compatible_v<U>>>
|
||||
operator U();
|
||||
};
|
||||
|
||||
template <typename T, typename construct_param_t, typename = void,
|
||||
typename... Args>
|
||||
struct is_constructable_impl : std::false_type {};
|
||||
template <typename T, typename construct_param_t, typename... Args>
|
||||
struct is_constructable_impl<
|
||||
T, construct_param_t,
|
||||
std::void_t<decltype(T{{Args{}}..., {construct_param_t{}}})>, Args...>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T, typename construct_param_t, typename... Args>
|
||||
constexpr bool is_constructable =
|
||||
is_constructable_impl<T, construct_param_t, void, Args...>::value;
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline constexpr std::size_t members_count_impl() {
|
||||
if constexpr (is_constructable<T, UniversalVectorType, Args...>) {
|
||||
return members_count_impl<T, Args..., UniversalVectorType>();
|
||||
}
|
||||
else if constexpr (is_constructable<T, UniversalType, Args...>) {
|
||||
return members_count_impl<T, Args..., UniversalType>();
|
||||
}
|
||||
else if constexpr (is_constructable<T, UniversalOptionalType, Args...>) {
|
||||
return members_count_impl<T, Args..., UniversalOptionalType>();
|
||||
}
|
||||
else if constexpr (is_constructable<T, UniversalIntegralType, Args...>) {
|
||||
return members_count_impl<T, Args..., UniversalIntegralType>();
|
||||
}
|
||||
else if constexpr (is_constructable<T, UniversalNullptrType, Args...>) {
|
||||
return members_count_impl<T, Args..., UniversalNullptrType>();
|
||||
}
|
||||
else if constexpr (is_constructable<T, UniversalCompatibleType, Args...>) {
|
||||
return members_count_impl<T, Args..., UniversalCompatibleType>();
|
||||
}
|
||||
else {
|
||||
return sizeof...(Args);
|
||||
}
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
inline constexpr std::size_t members_count() {
|
||||
using type = remove_cvref_t<T>;
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
if constexpr (internal::tuple_size<type>) {
|
||||
return std::tuple_size<type>::value;
|
||||
}
|
||||
else {
|
||||
return reflect26::members_count<type>();
|
||||
}
|
||||
#else
|
||||
if constexpr (is_out_ylt_refl_v<type>) {
|
||||
return refl_member_count(ylt::reflection::identity<type>{});
|
||||
}
|
||||
else if constexpr (is_inner_ylt_refl_v<type>) {
|
||||
return type::refl_member_count(ylt::reflection::identity<type>{});
|
||||
}
|
||||
else if constexpr (internal::tuple_size<type>) {
|
||||
return std::tuple_size<type>::value;
|
||||
}
|
||||
else if constexpr (std::is_aggregate_v<type>) {
|
||||
if constexpr (std::is_empty_v<type>) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return internal::members_count_impl<type>();
|
||||
}
|
||||
}
|
||||
else {
|
||||
static_assert(!sizeof(T), "not supported type!");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr std::size_t members_count_v = members_count<T>();
|
||||
} // namespace ylt::reflection
|
||||
@@ -0,0 +1,461 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
|
||||
#include "member_ptr.hpp"
|
||||
#include "reflect26_compat.hpp"
|
||||
#include "template_string.hpp"
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#include "reflect26_core.hpp"
|
||||
#endif
|
||||
|
||||
namespace ylt::reflection {
|
||||
|
||||
template <typename T>
|
||||
inline constexpr auto get_alias_field_names();
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <class T>
|
||||
struct Wrapper {
|
||||
using Type = T;
|
||||
T v;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
Wrapper(T) -> Wrapper<T>;
|
||||
|
||||
// This workaround is necessary for clang.
|
||||
template <class T>
|
||||
inline constexpr auto wrap(const T& arg) noexcept {
|
||||
return Wrapper{arg};
|
||||
}
|
||||
|
||||
template <auto ptr>
|
||||
inline constexpr std::string_view get_member_name() {
|
||||
#if defined(_MSC_VER)
|
||||
constexpr std::string_view func_name = __FUNCSIG__;
|
||||
#else
|
||||
constexpr std::string_view func_name = __PRETTY_FUNCTION__;
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
auto split = func_name.substr(0, func_name.size() - 2);
|
||||
return split.substr(split.find_last_of(":.") + 1);
|
||||
#elif defined(__GNUC__)
|
||||
auto split = func_name.substr(0, func_name.rfind(")}"));
|
||||
return split.substr(split.find_last_of(":") + 1);
|
||||
#elif defined(_MSC_VER)
|
||||
auto split = func_name.substr(0, func_name.rfind("}>"));
|
||||
return split.substr(split.rfind("->") + 2);
|
||||
#else
|
||||
static_assert(false,
|
||||
"You are using an unsupported compiler. Please use GCC, Clang "
|
||||
"or MSVC or switch to the rfl::Field-syntax.");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct member_tratis {};
|
||||
|
||||
template <class T, class Owner>
|
||||
struct member_tratis<T Owner::*> {
|
||||
using owner_type = Owner;
|
||||
using value_type = T;
|
||||
};
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_alias_struct_name_t : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_alias_struct_name_t<
|
||||
T, std::void_t<decltype(get_alias_struct_name((T*)nullptr))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_inner_alias_struct_name_t : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_inner_alias_struct_name_t<
|
||||
T, std::void_t<decltype(T::get_alias_struct_name((T*)nullptr))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_alias_struct_name_v = has_alias_struct_name_t<T>::value;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_inner_alias_struct_name_v =
|
||||
has_inner_alias_struct_name_t<T>::value;
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_alias_field_names_t : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_alias_field_names_t<
|
||||
T, std::void_t<decltype(get_alias_field_names((T*)nullptr))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_inner_alias_field_names_t : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct has_inner_alias_field_names_t<
|
||||
T, std::void_t<decltype(T::get_alias_field_names((T*)nullptr))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_alias_field_names_v = has_alias_field_names_t<T>::value;
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_inner_alias_field_names_v =
|
||||
has_inner_alias_field_names_t<T>::value;
|
||||
|
||||
template <typename T, typename U, size_t... Is>
|
||||
inline constexpr void init_arr_with_tuple(U& arr, std::index_sequence<Is...>) {
|
||||
constexpr auto tp = struct_to_tuple<T>();
|
||||
((arr[Is] = internal::get_member_name<internal::wrap(std::get<Is>(tp))>()),
|
||||
...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr std::array<std::string_view, members_count_v<T>>
|
||||
get_member_names() {
|
||||
using type = remove_cvref_t<T>;
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
return reflect26::member_names_array<type>();
|
||||
#else
|
||||
if constexpr (is_out_ylt_refl_v<type>) {
|
||||
return refl_member_names(ylt::reflection::identity<type>{});
|
||||
}
|
||||
else if constexpr (is_inner_ylt_refl_v<type>) {
|
||||
return type::refl_member_names(ylt::reflection::identity<type>{});
|
||||
}
|
||||
else {
|
||||
constexpr size_t Count = members_count_v<T>;
|
||||
std::array<std::string_view, Count> arr;
|
||||
#if __cplusplus >= 202002L && (!defined(_MSC_VER) || _MSC_VER >= 1930)
|
||||
constexpr auto tp = struct_to_tuple<T>();
|
||||
[&]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
((arr[Is] =
|
||||
internal::get_member_name<internal::wrap(std::get<Is>(tp))>()),
|
||||
...);
|
||||
}(std::make_index_sequence<Count>{});
|
||||
#else
|
||||
init_arr_with_tuple<T>(arr, std::make_index_sequence<Count>{});
|
||||
#endif
|
||||
return arr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
template <std::size_t N>
|
||||
struct member_names_linear_map {
|
||||
std::array<std::string_view, N> names;
|
||||
|
||||
constexpr std::size_t size() const noexcept { return N; }
|
||||
constexpr auto begin() const noexcept { return names.begin(); }
|
||||
constexpr auto end() const noexcept { return names.end(); }
|
||||
|
||||
static constexpr std::string_view normalized_name(std::string_view name) {
|
||||
return reflect26::normalized_member_name(name);
|
||||
}
|
||||
|
||||
constexpr std::size_t at(std::string_view name) const {
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
if (names[i] == name || normalized_name(names[i]) == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw std::out_of_range("unknown member name");
|
||||
}
|
||||
};
|
||||
#else
|
||||
template <typename T, size_t... Is>
|
||||
inline constexpr auto get_member_names_map_impl(T& name_arr,
|
||||
std::index_sequence<Is...>) {
|
||||
return frozen::unordered_map<frozen::string, size_t, sizeof...(Is)>{
|
||||
{name_arr[Is], Is}...};
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline constexpr auto get_member_names_map() {
|
||||
constexpr auto name_arr = get_member_names<T>();
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
return member_names_linear_map<name_arr.size()>{name_arr};
|
||||
#elif __cplusplus >= 202002L
|
||||
return [&]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
return frozen::unordered_map<frozen::string, size_t, name_arr.size()>{
|
||||
{name_arr[Is], Is}...};
|
||||
}(std::make_index_sequence<name_arr.size()>{});
|
||||
#else
|
||||
return get_member_names_map_impl(name_arr,
|
||||
std::make_index_sequence<name_arr.size()>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, typename Tuple, size_t... Is>
|
||||
inline auto get_member_offset_arr_impl(T& t, Tuple& tp,
|
||||
std::index_sequence<Is...>) {
|
||||
std::array<size_t, sizeof...(Is)> arr;
|
||||
((arr[Is] = size_t((const char*)&std::get<Is>(tp) - (char*)(&t))), ...);
|
||||
return arr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const auto& get_member_offset_arr(T&& t) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
[[maybe_unused]] static constexpr auto arr =
|
||||
reflect26::member_offsets<remove_cvref_t<T>>();
|
||||
return arr;
|
||||
#else
|
||||
constexpr size_t Count = members_count_v<T>;
|
||||
auto tp = ylt::reflection::object_to_tuple(std::forward<T>(t));
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
[[maybe_unused]] static std::array<size_t, Count> arr = {
|
||||
[&]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
std::array<size_t, Count> arr;
|
||||
((arr[Is] = size_t((const char*)&std::get<Is>(tp) - (char*)(&t))), ...);
|
||||
return arr;
|
||||
}(std::make_index_sequence<Count>{})}; // namespace internal
|
||||
|
||||
return arr;
|
||||
#else
|
||||
[[maybe_unused]] static std::array<size_t, Count> arr =
|
||||
get_member_offset_arr_impl(t, tp, std::make_index_sequence<Count>{});
|
||||
return arr;
|
||||
#endif
|
||||
#endif
|
||||
} // namespace ylt::reflection
|
||||
|
||||
template <typename T>
|
||||
inline const auto& get_member_offset_arr() {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
[[maybe_unused]] static constexpr auto arr =
|
||||
reflect26::member_offsets<remove_cvref_t<T>>();
|
||||
return arr;
|
||||
#else
|
||||
return get_member_offset_arr(internal::wrapper<T>::value);
|
||||
#endif
|
||||
} // namespace ylt::reflection
|
||||
} // namespace internal
|
||||
|
||||
template <typename... Args>
|
||||
inline constexpr auto tuple_to_variant(std::tuple<Args...>) {
|
||||
return std::variant<std::add_pointer_t<Args>...>{};
|
||||
}
|
||||
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
namespace internal {
|
||||
template <typename T, typename Member>
|
||||
using copy_const_t =
|
||||
std::conditional_t<std::is_const_v<std::remove_reference_t<T>>,
|
||||
std::add_const_t<Member>, Member>;
|
||||
|
||||
template <typename T, std::size_t... Is>
|
||||
inline constexpr auto struct_variant_reflect(std::index_sequence<Is...>) {
|
||||
static constexpr auto members = reflect26::data_members_array<T>();
|
||||
return std::variant<std::add_pointer_t<
|
||||
copy_const_t<T, reflect26::meta_type_t<members[Is]>>>...>{};
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
using struct_variant_t = decltype(internal::struct_variant_reflect<T>(
|
||||
std::make_index_sequence<members_count_v<remove_cvref_t<T>>>{}));
|
||||
#else
|
||||
template <typename T>
|
||||
using struct_variant_t = decltype(tuple_to_variant(
|
||||
std::declval<decltype(struct_to_tuple<remove_cvref_t<T>>())>));
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
constexpr auto member_names_map = internal::get_member_names_map<T>();
|
||||
|
||||
template <typename T>
|
||||
inline auto member_offsets = internal::get_member_offset_arr<T>();
|
||||
|
||||
template <auto member>
|
||||
inline constexpr size_t index_of() {
|
||||
using T = typename internal::member_tratis<
|
||||
std::remove_const_t<decltype(member)>>::owner_type;
|
||||
constexpr auto name = field_string<member>();
|
||||
constexpr auto names = internal::get_member_names<T>();
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
if (name == names[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return names.size();
|
||||
}
|
||||
|
||||
struct field_alias_t {
|
||||
std::string_view alias_name;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr auto get_alias_field_names() {
|
||||
if constexpr (internal::has_alias_field_names_v<T>) {
|
||||
return get_alias_field_names((T*)nullptr);
|
||||
}
|
||||
else if constexpr (internal::has_inner_alias_field_names_v<T>) {
|
||||
return T::get_alias_field_names((T*)nullptr);
|
||||
}
|
||||
else {
|
||||
return std::array<std::string_view, 0>{};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr std::string_view get_struct_name() {
|
||||
using U = ylt::reflection::remove_cvref_t<T>;
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
constexpr auto annotation_name = reflect26::type_name<U>();
|
||||
if constexpr (!annotation_name.empty()) {
|
||||
return annotation_name;
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
if constexpr (internal::has_alias_struct_name_v<U>) {
|
||||
return get_alias_struct_name((U*)nullptr);
|
||||
}
|
||||
else if constexpr (internal::has_inner_alias_struct_name_v<U>) {
|
||||
return U::get_alias_struct_name((U*)nullptr);
|
||||
}
|
||||
else {
|
||||
return type_string<U>();
|
||||
}
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr std::array<std::string_view, members_count_v<T>>
|
||||
get_member_names() {
|
||||
auto arr = internal::get_member_names<T>();
|
||||
using U = ylt::reflection::remove_cvref_t<T>;
|
||||
if constexpr (internal::has_alias_field_names_v<U> ||
|
||||
internal::has_inner_alias_field_names_v<U>) {
|
||||
constexpr auto alias_arr = get_alias_field_names<U>();
|
||||
for (size_t i = 0; i < alias_arr.size(); i++) {
|
||||
arr[alias_arr[i].index] = alias_arr[i].alias_name;
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
struct FixedString {
|
||||
char data[N];
|
||||
template <std::size_t... I>
|
||||
constexpr FixedString(const char (&s)[N], std::index_sequence<I...>)
|
||||
: data{s[I]...} {}
|
||||
constexpr FixedString(const char (&s)[N])
|
||||
: FixedString(s, std::make_index_sequence<N>()) {}
|
||||
constexpr std::string_view str() const {
|
||||
return std::string_view{data, N - 1};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr size_t index_of(std::string_view name) {
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
for (size_t i = 0; i < arr.size(); i++) {
|
||||
if (arr[i] == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return arr.size();
|
||||
}
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
template <typename T, FixedString name>
|
||||
inline constexpr size_t index_of() {
|
||||
return index_of<T>(name.str());
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T, size_t index>
|
||||
inline constexpr std::string_view name_of() {
|
||||
static_assert(index < members_count_v<T>, "index out of range");
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr std::string_view name_of(size_t index) {
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
if (index >= arr.size()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
template <typename Visit, typename U, size_t... Is>
|
||||
inline constexpr void for_each_impl(Visit&& func, U& arr,
|
||||
std::index_sequence<Is...>) {
|
||||
if constexpr (std::is_invocable_v<Visit, std::string_view, size_t>) {
|
||||
(func(arr[Is], Is), ...);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Visit, std::string_view>) {
|
||||
(func(arr[Is]), ...);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof(Visit) < 0,
|
||||
"invalid arguments, full arguments: [std::string_view, "
|
||||
"size_t], at least has std::string_view and make sure keep "
|
||||
"the order of arguments");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Visit>
|
||||
inline constexpr void for_each(Visit&& func) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
static constexpr auto arr = get_member_names<T>();
|
||||
[[maybe_unused]] size_t index = 0;
|
||||
template for (constexpr auto name : arr) {
|
||||
if constexpr (std::is_invocable_v<Visit, std::string_view, size_t>) {
|
||||
func(name, index++);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Visit, std::string_view>) {
|
||||
func(name);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof(Visit) < 0,
|
||||
"invalid arguments, full arguments: [std::string_view, "
|
||||
"size_t], at least has std::string_view and make sure keep "
|
||||
"the order of arguments");
|
||||
}
|
||||
}
|
||||
#elif __cplusplus >= 202002L
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
[&]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
if constexpr (std::is_invocable_v<Visit, std::string_view, size_t>) {
|
||||
(func(arr[Is], Is), ...);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Visit, std::string_view>) {
|
||||
(func(arr[Is]), ...);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof(Visit) < 0,
|
||||
"invalid arguments, full arguments: [std::string_view, "
|
||||
"size_t], at least has std::string_view and make sure keep "
|
||||
"the order of arguments");
|
||||
}
|
||||
}(std::make_index_sequence<arr.size()>{});
|
||||
#else
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
for_each_impl(std::forward<Visit>(func), arr,
|
||||
std::make_index_sequence<arr.size()>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ylt::reflection
|
||||
@@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
#include "member_count.hpp"
|
||||
#include "reflect26_compat.hpp"
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#include "reflect26_core.hpp"
|
||||
#endif
|
||||
|
||||
// modified based on:
|
||||
// https://github.com/getml/reflect-cpp/blob/main/include/rfl/internal/bind_fake_object_to_tuple.hpp
|
||||
// thanks for alxn4's great idea!
|
||||
namespace ylt::reflection {
|
||||
namespace internal {
|
||||
|
||||
template <class T, std::size_t n>
|
||||
struct object_tuple_view_helper {
|
||||
static constexpr auto tuple_view() {
|
||||
static_assert(
|
||||
sizeof(T) < 0,
|
||||
"\n\nThis error occurs for one of two reasons:\n\n"
|
||||
"1) You have created a struct with more than 256 fields, which is "
|
||||
"unsupported. \n\n"
|
||||
"2) Your struct is not an aggregate type. You can make it aggregated, "
|
||||
"or defined a YLT_REFL macro. \n\n");
|
||||
}
|
||||
|
||||
static constexpr auto tuple_view(T&) {
|
||||
static_assert(
|
||||
sizeof(T) < 0,
|
||||
"\n\nThis error occurs for one of two reasons:\n\n"
|
||||
"1) You have created a struct with more than 256 fields, which is "
|
||||
"unsupported. \n\n"
|
||||
"2) Your struct is not an aggregate type. You can make it aggregated, "
|
||||
"or defined a YLT_REFL macro. \n\n");
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
static constexpr decltype(auto) tuple_view(T&&, Visitor&&) {
|
||||
static_assert(
|
||||
sizeof(T) < 0,
|
||||
"\n\nThis error occurs for one of two reasons:\n\n"
|
||||
"1) You have created a struct with more than 256 fields, which is "
|
||||
"unsupported. \n\n"
|
||||
"2) Your struct is not an aggregate type. You can make it aggregated, "
|
||||
"or defined a YLT_REFL macro. \n\n");
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct object_tuple_view_helper<T, 0> {
|
||||
static constexpr auto tuple_view() { return std::tie(); }
|
||||
static constexpr auto tuple_view(T&) { return std::tie(); }
|
||||
|
||||
template <typename Visitor>
|
||||
static constexpr decltype(auto) tuple_view(T&&, Visitor&&) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct wrapper {
|
||||
inline static remove_cvref_t<T> value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline constexpr remove_cvref_t<T>& get_fake_object() noexcept {
|
||||
return wrapper<remove_cvref_t<T>>::value;
|
||||
}
|
||||
|
||||
#define RFL_INTERNAL_OBJECT_IF_YOU_SEE_AN_ERROR_REFER_TO_DOCUMENTATION_ON_C_ARRAYS( \
|
||||
n, ...) \
|
||||
template <class T> \
|
||||
struct object_tuple_view_helper<T, n> { \
|
||||
static constexpr auto tuple_view() { \
|
||||
auto& [__VA_ARGS__] = get_fake_object<remove_cvref_t<T>>(); \
|
||||
auto ref_tup = std::tie(__VA_ARGS__); \
|
||||
auto get_ptrs = [](auto&... _refs) { \
|
||||
return std::make_tuple(&_refs...); \
|
||||
}; \
|
||||
return std::apply(get_ptrs, ref_tup); \
|
||||
} \
|
||||
static constexpr auto tuple_view(T& t) { \
|
||||
auto& [__VA_ARGS__] = t; \
|
||||
return std::tie(__VA_ARGS__); \
|
||||
} \
|
||||
template <typename Visitor> \
|
||||
static constexpr decltype(auto) tuple_view(T&& t, Visitor&& visitor) { \
|
||||
auto&& [__VA_ARGS__] = t; \
|
||||
return visitor(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
|
||||
// such file is generate macro file
|
||||
#ifndef YLT_USE_CXX26_REFLECTION
|
||||
#include "internal/generate/member_macro.hpp"
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline constexpr auto tuple_view(T&& t) {
|
||||
return internal::object_tuple_view_helper<T, members_count_v<T>>::tuple_view(
|
||||
t);
|
||||
}
|
||||
|
||||
template <size_t Count, class T, typename Visitor>
|
||||
inline constexpr decltype(auto) tuple_view(T&& t, Visitor&& visitor) {
|
||||
return internal::object_tuple_view_helper<T, Count>::tuple_view(
|
||||
std::forward<T>(t), std::forward<Visitor>(visitor));
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
template <class T>
|
||||
inline constexpr auto struct_to_tuple() {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
return reflect26::data_members<remove_cvref_t<T>>();
|
||||
#else
|
||||
return internal::object_tuple_view_helper<T,
|
||||
members_count_v<T>>::tuple_view();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline constexpr auto object_to_tuple(T&& t) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
return reflect26::data_members<remove_cvref_t<T>>();
|
||||
#else
|
||||
using type = remove_cvref_t<T>;
|
||||
if constexpr (is_out_ylt_refl_v<type>) {
|
||||
return refl_object_to_tuple(std::forward<T>(t));
|
||||
}
|
||||
else if constexpr (is_inner_ylt_refl_v<type>) {
|
||||
return type::refl_object_to_tuple(std::forward<T>(t));
|
||||
}
|
||||
else {
|
||||
return internal::tuple_view(std::forward<T>(t));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, typename Visitor, size_t Count = members_count_v<T>>
|
||||
inline constexpr decltype(auto) visit_members(T&& t, Visitor&& visitor) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
return reflect26::for_each_data_member(std::forward<T>(t),
|
||||
std::forward<Visitor>(visitor));
|
||||
#else
|
||||
using type = remove_cvref_t<T>;
|
||||
if constexpr (is_out_ylt_refl_v<type>) {
|
||||
return refl_visit_members(std::forward<T>(t),
|
||||
std::forward<Visitor>(visitor));
|
||||
}
|
||||
else if constexpr (is_inner_ylt_refl_v<type>) {
|
||||
return t.refl_visit_members(std::forward<T>(t),
|
||||
std::forward<Visitor>(visitor));
|
||||
}
|
||||
else {
|
||||
return internal::tuple_view<Count>(std::forward<T>(t),
|
||||
std::forward<Visitor>(visitor));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // namespace ylt::reflection
|
||||
@@ -0,0 +1,430 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <variant>
|
||||
|
||||
#include "member_names.hpp"
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#include "reflect26_dispatch.hpp"
|
||||
#endif
|
||||
#include "template_switch.hpp"
|
||||
|
||||
namespace ylt::reflection {
|
||||
|
||||
namespace internal {
|
||||
template <typename Member, typename T>
|
||||
inline void set_member_ptr(Member& member, T t) {
|
||||
if constexpr (std::is_constructible_v<Member, T>) {
|
||||
member = t;
|
||||
}
|
||||
else {
|
||||
std::string str = "given type: ";
|
||||
str.append(type_string<std::remove_pointer_t<Member>>());
|
||||
str.append(" is not equal with real type: ")
|
||||
.append(type_string<std::remove_pointer_t<T>>());
|
||||
throw std::invalid_argument(str);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_variant : std::false_type {};
|
||||
|
||||
template <typename... T>
|
||||
struct is_variant<std::variant<T...>> : std::true_type {};
|
||||
|
||||
struct switch_helper {
|
||||
template <size_t index, typename Member, class Tuple>
|
||||
static constexpr size_t run(Member& member, Tuple& t) {
|
||||
if constexpr (index >= std::tuple_size_v<Tuple>) {
|
||||
return index;
|
||||
}
|
||||
else {
|
||||
if constexpr (is_variant<Member>::value) {
|
||||
member = Member{std::in_place_index<index>, &std::get<index>(t)};
|
||||
}
|
||||
else {
|
||||
set_member_ptr(member, &std::get<index>(t));
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef YLT_USE_CXX26_REFLECTION
|
||||
inline constexpr frozen::string filter_str(const frozen::string& str) {
|
||||
if (str.size() > 3 && str[0] == '_' && str[1] == '_' && str[2] == '_') {
|
||||
auto ptr = str.data() + 3;
|
||||
return frozen::string(ptr, str.size() - 3);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename value_type>
|
||||
struct offset_t {
|
||||
using type = value_type;
|
||||
size_t value;
|
||||
};
|
||||
|
||||
template <typename T, typename Tuple, size_t... Is>
|
||||
inline auto get_variant_type() {
|
||||
return std::variant<offset_t<
|
||||
ylt::reflection::remove_cvref_t<std::tuple_element_t<Is, Tuple>>>...>{};
|
||||
}
|
||||
|
||||
template <typename T, size_t... Is>
|
||||
inline constexpr auto get_variant_map_impl(std::index_sequence<Is...>) {
|
||||
using U = ylt::reflection::remove_cvref_t<T>;
|
||||
constexpr auto arr = ylt::reflection::get_member_names<U>();
|
||||
auto& offset_arr = get_member_offset_arr(wrapper<U>::value);
|
||||
using Tuple = decltype(ylt::reflection::object_to_tuple(std::declval<U>()));
|
||||
using ValueType = decltype(get_variant_type<U, Tuple, Is...>());
|
||||
return frozen::unordered_map<frozen::string, ValueType, sizeof...(Is)>{
|
||||
{filter_str(arr[Is]),
|
||||
ValueType{std::in_place_index<Is>,
|
||||
offset_t<ylt::reflection::remove_cvref_t<
|
||||
std::tuple_element_t<Is, Tuple>>>{offset_arr[Is]}}}...};
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
template <typename T, size_t... Is>
|
||||
inline auto get_variant_by_index_reflect(T& t, size_t index,
|
||||
std::index_sequence<Is...>) {
|
||||
using U = ylt::reflection::remove_cvref_t<T>;
|
||||
using variant = struct_variant_t<T>;
|
||||
static constexpr auto members = reflect26::data_members_array<U>();
|
||||
variant member_ptr;
|
||||
bool found = false;
|
||||
(
|
||||
[&] {
|
||||
if (!found && index == Is) {
|
||||
member_ptr.template emplace<Is>(std::addressof(t.[:members[Is]:]));
|
||||
found = true;
|
||||
}
|
||||
}(),
|
||||
...);
|
||||
if (!found) {
|
||||
std::string str = "index out of range, ";
|
||||
str.append("index: ")
|
||||
.append(std::to_string(index))
|
||||
.append(" is greater equal than member count ")
|
||||
.append(std::to_string(members_count_v<U>));
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
return member_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
inline constexpr auto get_variant_map() {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
static_assert(sizeof(T) < 0,
|
||||
"get_variant_map is not available with C++26 reflection; use "
|
||||
"reflect26::dispatch_by_name instead");
|
||||
#else
|
||||
return internal::get_variant_map_impl<T>(
|
||||
std::make_index_sequence<members_count_v<T>>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Member, typename T>
|
||||
inline Member& get(T& t, size_t index) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
Member* member_ptr = nullptr;
|
||||
bool found = reflect26::dispatch_by_index(t, index, [&](auto& field) {
|
||||
internal::set_member_ptr(member_ptr, std::addressof(field));
|
||||
});
|
||||
if (!found) {
|
||||
std::string str = "index out of range, ";
|
||||
str.append("index: ")
|
||||
.append(std::to_string(index))
|
||||
.append(" is greater equal than member count ")
|
||||
.append(std::to_string(members_count_v<remove_cvref_t<T>>));
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
return *member_ptr;
|
||||
#else
|
||||
auto ref_tp = object_to_tuple(t);
|
||||
constexpr size_t tuple_size = std::tuple_size_v<decltype(ref_tp)>;
|
||||
|
||||
if (index >= tuple_size) {
|
||||
std::string str = "index out of range, ";
|
||||
str.append("index: ")
|
||||
.append(std::to_string(index))
|
||||
.append(" is greater equal than member count ")
|
||||
.append(std::to_string(tuple_size));
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
Member* member_ptr = nullptr;
|
||||
template_switch<internal::switch_helper>(index, member_ptr, ref_tp);
|
||||
return *member_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Member, typename T>
|
||||
inline Member& get(T& t, std::string_view name) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
Member* member_ptr = nullptr;
|
||||
bool found = reflect26::dispatch_by_name(t, name, [&](auto& field) {
|
||||
internal::set_member_ptr(member_ptr, std::addressof(field));
|
||||
});
|
||||
if (!found) {
|
||||
throw std::out_of_range("unknown member name");
|
||||
}
|
||||
return *member_ptr;
|
||||
#else
|
||||
static constexpr auto map = member_names_map<T>;
|
||||
size_t index = map.at(name); // may throw out_of_range: unknown key.
|
||||
auto ref_tp = object_to_tuple(t);
|
||||
|
||||
Member* member_ptr = nullptr;
|
||||
template_switch<internal::switch_helper>(index, member_ptr, ref_tp);
|
||||
return *member_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline auto get(T& t, size_t index) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
using U = remove_cvref_t<T>;
|
||||
if constexpr (members_count_v<U> == 0) {
|
||||
throw std::out_of_range("index out of range, empty object");
|
||||
}
|
||||
else {
|
||||
return internal::get_variant_by_index_reflect(
|
||||
t, index, std::make_index_sequence<members_count_v<U>>{});
|
||||
}
|
||||
#else
|
||||
auto ref_tp = object_to_tuple(t);
|
||||
constexpr size_t tuple_size = std::tuple_size_v<decltype(ref_tp)>;
|
||||
if (index >= tuple_size) {
|
||||
std::string str = "index out of range, ";
|
||||
str.append("index: ")
|
||||
.append(std::to_string(index))
|
||||
.append(" is greater equal than member count ")
|
||||
.append(std::to_string(tuple_size));
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
|
||||
using variant = decltype(tuple_to_variant(ref_tp));
|
||||
variant member_ptr;
|
||||
template_switch<internal::switch_helper>(index, member_ptr, ref_tp);
|
||||
return member_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr auto get(T& t, std::string_view name) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
constexpr auto& map = member_names_map<T>;
|
||||
size_t index = map.at(name); // may throw out_of_range: unknown key.
|
||||
return get(t, index);
|
||||
#else
|
||||
constexpr auto& map = member_names_map<T>;
|
||||
size_t index = map.at(name); // may throw out_of_range: unknown key.
|
||||
return get(t, index);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <size_t index, typename T>
|
||||
inline constexpr auto& get(T& t) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
using U = remove_cvref_t<T>;
|
||||
static_assert(index < members_count_v<U>, "index out of range");
|
||||
decltype(auto) result = [&]() -> decltype(auto) {
|
||||
static constexpr auto members = reflect26::data_members_array<U>();
|
||||
return (t.[:members[index]:]);
|
||||
}();
|
||||
return result;
|
||||
#else
|
||||
auto ref_tp = object_to_tuple(t);
|
||||
|
||||
static_assert(index < std::tuple_size_v<decltype(ref_tp)>,
|
||||
"index out of range");
|
||||
|
||||
return std::get<index>(ref_tp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
template <FixedString name, typename T>
|
||||
inline constexpr auto& get(T& t) {
|
||||
constexpr size_t index = index_of<T, name>();
|
||||
return get<index>(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T, typename Field>
|
||||
inline size_t index_of(T& t, Field& value) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
using U = remove_cvref_t<T>;
|
||||
size_t index = 0;
|
||||
size_t result = members_count_v<U>;
|
||||
const auto value_addr =
|
||||
static_cast<const volatile void*>(std::addressof(value));
|
||||
reflect26::for_each_data_member(t, [&](auto& field, std::string_view, auto) {
|
||||
const auto field_addr =
|
||||
static_cast<const volatile void*>(std::addressof(field));
|
||||
if (result == members_count_v<U> && field_addr == value_addr) {
|
||||
result = index;
|
||||
}
|
||||
++index;
|
||||
});
|
||||
return result;
|
||||
#else
|
||||
const auto& offset_arr = member_offsets<T>;
|
||||
size_t cur_offset = (const char*)(&value) - (const char*)(&t);
|
||||
auto it = std::lower_bound(offset_arr.begin(), offset_arr.end(), cur_offset);
|
||||
if (it == offset_arr.end()) {
|
||||
return offset_arr.size();
|
||||
}
|
||||
|
||||
return std::distance(offset_arr.begin(), it);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Member>
|
||||
inline size_t index_of(Member member) {
|
||||
using T = typename member_traits<Member>::owner_type;
|
||||
static auto& t = internal::get_fake_object<T>();
|
||||
return index_of(t, t.*member);
|
||||
}
|
||||
|
||||
template <typename T, typename Field>
|
||||
inline constexpr std::string_view name_of(T& t, Field& value) {
|
||||
size_t index = index_of(t, value);
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
if (index == arr.size()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return arr[index];
|
||||
}
|
||||
|
||||
template <typename T, typename Visit, size_t... Is, typename... Args>
|
||||
inline constexpr void visit_members_impl0(Visit&& func,
|
||||
std::index_sequence<Is...>,
|
||||
Args&... args) {
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
(func(args, arr[Is]), ...);
|
||||
}
|
||||
|
||||
template <typename T, typename Visit, size_t... Is, typename... Args>
|
||||
inline constexpr void visit_members_impl(Visit&& func,
|
||||
std::index_sequence<Is...>,
|
||||
Args&... args) {
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
(func(args, arr[Is], Is), ...);
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
template <typename Visit, typename Field>
|
||||
inline constexpr void invoke_for_each_field(Visit& func, Field& field,
|
||||
std::string_view name,
|
||||
std::size_t index) {
|
||||
if constexpr (std::is_invocable_v<Visit&, Field&>) {
|
||||
func(field);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Visit&, Field&, std::string_view>) {
|
||||
func(field, name);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Visit&, Field&, std::string_view,
|
||||
std::size_t>) {
|
||||
func(field, name, index);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof(Visit) < 0,
|
||||
"invalid arguments, full arguments: [field_value&, "
|
||||
"std::string_view, size_t], at least has field_value and "
|
||||
"make sure keep the order of arguments");
|
||||
}
|
||||
}
|
||||
} // namespace internal
|
||||
|
||||
template <typename T, typename Visit>
|
||||
inline constexpr void for_each(T&& t, Visit&& func) {
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
using U = remove_cvref_t<T>;
|
||||
constexpr auto Count = members_count_v<U>;
|
||||
if constexpr (Count == 0) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
constexpr auto names = get_member_names<U>();
|
||||
reflect26::for_each_data_member(
|
||||
std::forward<T>(t),
|
||||
[&](auto& field, std::string_view name, auto index) {
|
||||
(void)name;
|
||||
internal::invoke_for_each_field(func, field, names[index], index);
|
||||
});
|
||||
}
|
||||
#else
|
||||
using Tuple = decltype(object_to_tuple(t));
|
||||
constexpr auto Count = std::tuple_size_v<Tuple>;
|
||||
if constexpr (Count == 0) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
using first_t = std::tuple_element_t<0, Tuple>;
|
||||
if constexpr (std::is_invocable_v<Visit, first_t>) {
|
||||
visit_members(t, [&func](auto&... args) {
|
||||
(func(args), ...);
|
||||
});
|
||||
}
|
||||
else {
|
||||
if constexpr (std::is_invocable_v<Visit, first_t, std::string_view>) {
|
||||
visit_members(t, [&](auto&... args) {
|
||||
#if __cplusplus >= 202002L && (!defined(_MSC_VER) || _MSC_VER >= 1930)
|
||||
[&]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
(func(args, arr[Is]), ...);
|
||||
}(std::make_index_sequence<sizeof...(args)>{});
|
||||
#else
|
||||
visit_members_impl0<T>(std::forward<Visit>(func),
|
||||
std::make_index_sequence<sizeof...(args)>{},
|
||||
args...);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Visit, first_t, std::string_view,
|
||||
size_t>) {
|
||||
visit_members(t, [&](auto&... args) {
|
||||
#if __cplusplus >= 202002L && (!defined(_MSC_VER) || _MSC_VER >= 1930)
|
||||
[&]<size_t... Is>(std::index_sequence<Is...>) mutable {
|
||||
constexpr auto arr = get_member_names<T>();
|
||||
(func(args, arr[Is], Is), ...);
|
||||
}(std::make_index_sequence<sizeof...(args)>{});
|
||||
#else
|
||||
visit_members_impl<T>(std::forward<Visit>(func),
|
||||
std::make_index_sequence<sizeof...(args)>{},
|
||||
args...);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof(Visit) < 0,
|
||||
"invalid arguments, full arguments: [field_value&, "
|
||||
"std::string_view, size_t], at least has field_value and "
|
||||
"make sure keep the order of arguments");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ylt::reflection
|
||||
|
||||
#if (defined(__GNUC__) && __GNUC__ > 10) || \
|
||||
((defined(__clang__) || defined(_MSC_VER)) && __has_include(<concepts>))
|
||||
#if __cplusplus >= 202002L
|
||||
template <ylt::reflection::FixedString s>
|
||||
inline constexpr auto operator""_ylts() {
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
#include <tuple>
|
||||
|
||||
#include "internal/common_macro.hpp"
|
||||
|
||||
namespace ylt::reflection {
|
||||
template <typename T, auto... field>
|
||||
struct private_visitor {
|
||||
friend inline constexpr auto get_private_ptrs(
|
||||
const ylt::reflection::identity<T>&) {
|
||||
constexpr auto tp = std::make_tuple(field...);
|
||||
return tp;
|
||||
}
|
||||
};
|
||||
} // namespace ylt::reflection
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
// GCC 16 uses __cpp_impl_reflection; future compilers may use __cpp_reflection
|
||||
#if (defined(__cpp_impl_reflection) && __cpp_impl_reflection >= 202406L) || \
|
||||
(defined(__cpp_reflection) && __cpp_reflection >= 202406L)
|
||||
#define YLT_USE_CXX26_REFLECTION 1
|
||||
#endif
|
||||
@@ -0,0 +1,241 @@
|
||||
#pragma once
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <meta>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace ylt::reflection::reflect26 {
|
||||
|
||||
template <std::size_t N>
|
||||
struct fixed_string {
|
||||
char data[N];
|
||||
|
||||
consteval fixed_string(const char (&str)[N]) {
|
||||
for (std::size_t i = 0; i < N; ++i) {
|
||||
data[i] = str[i];
|
||||
}
|
||||
}
|
||||
|
||||
consteval operator std::string_view() const { return {data, N - 1}; }
|
||||
};
|
||||
|
||||
template <fixed_string Name>
|
||||
struct field_name {
|
||||
static constexpr auto value = Name;
|
||||
};
|
||||
|
||||
template <fixed_string Name>
|
||||
struct struct_name {
|
||||
static constexpr auto value = Name;
|
||||
};
|
||||
|
||||
struct skip_base {};
|
||||
|
||||
struct skip_field {};
|
||||
|
||||
inline constexpr std::string_view normalized_member_name(
|
||||
std::string_view name) {
|
||||
if (name.size() > 3 && name[0] == '_' && name[1] == '_' && name[2] == '_') {
|
||||
name.remove_prefix(3);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
template <std::meta::info Info>
|
||||
using meta_type_t = typename[:std::meta::type_of(Info):];
|
||||
|
||||
template <std::meta::info Info>
|
||||
using remove_cvref_meta_type_t = std::remove_cvref_t<meta_type_t<Info>>;
|
||||
|
||||
template <std::meta::info Info>
|
||||
consteval auto annotations_array() {
|
||||
return std::define_static_array(std::meta::annotations_of(Info));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_field_name_annotation : std::false_type {};
|
||||
|
||||
template <fixed_string Name>
|
||||
struct is_field_name_annotation<field_name<Name>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_struct_name_annotation : std::false_type {};
|
||||
|
||||
template <fixed_string Name>
|
||||
struct is_struct_name_annotation<struct_name<Name>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_skip_base_annotation : std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_skip_base_annotation<skip_base> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_skip_field_annotation : std::false_type {};
|
||||
|
||||
template <>
|
||||
struct is_skip_field_annotation<skip_field> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool skip_base_v = false;
|
||||
|
||||
template <std::meta::info Info, template <typename> typename Predicate>
|
||||
consteval bool has_annotation() {
|
||||
static constexpr auto annotations = annotations_array<Info>();
|
||||
template for (constexpr auto annotation : annotations) {
|
||||
using annotation_t = remove_cvref_meta_type_t<annotation>;
|
||||
if constexpr (Predicate<annotation_t>::value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <std::meta::info Member>
|
||||
consteval std::string_view member_name() {
|
||||
static constexpr auto annotations = annotations_array<Member>();
|
||||
template for (constexpr auto annotation : annotations) {
|
||||
using annotation_t = remove_cvref_meta_type_t<annotation>;
|
||||
if constexpr (is_field_name_annotation<annotation_t>::value) {
|
||||
return annotation_t::value;
|
||||
}
|
||||
}
|
||||
return std::meta::identifier_of(Member);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval std::string_view type_name() {
|
||||
static constexpr auto annotations = annotations_array<^^T>();
|
||||
template for (constexpr auto annotation : annotations) {
|
||||
using annotation_t = remove_cvref_meta_type_t<annotation>;
|
||||
if constexpr (is_struct_name_annotation<annotation_t>::value) {
|
||||
return annotation_t::value;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
template <std::meta::info Info>
|
||||
consteval bool has_skip_base_annotation() {
|
||||
return has_annotation<Info, is_skip_base_annotation>();
|
||||
}
|
||||
|
||||
template <std::meta::info Base>
|
||||
consteval bool should_skip_base() {
|
||||
using base_type = meta_type_t<Base>;
|
||||
if constexpr (skip_base_v<std::remove_cvref_t<base_type>>) {
|
||||
return true;
|
||||
}
|
||||
else if constexpr (has_skip_base_annotation<Base>()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return has_skip_base_annotation<std::meta::type_of(Base)>();
|
||||
}
|
||||
}
|
||||
|
||||
template <std::meta::info Member>
|
||||
consteval bool should_skip_field() {
|
||||
return has_annotation<Member, is_skip_field_annotation>();
|
||||
}
|
||||
|
||||
template <std::meta::info Type>
|
||||
consteval void append_data_members(std::vector<std::meta::info>& members) {
|
||||
constexpr auto ctx = std::meta::access_context::unchecked();
|
||||
static constexpr auto bases =
|
||||
std::define_static_array(std::meta::bases_of(Type, ctx));
|
||||
template for (constexpr auto base : bases) {
|
||||
if constexpr (!should_skip_base<base>()) {
|
||||
append_data_members<std::meta::type_of(base)>(members);
|
||||
}
|
||||
}
|
||||
static constexpr auto direct_members =
|
||||
std::define_static_array(std::meta::nonstatic_data_members_of(Type, ctx));
|
||||
template for (constexpr auto member : direct_members) {
|
||||
if constexpr (!should_skip_field<member>()) {
|
||||
members.push_back(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval auto data_members() {
|
||||
std::vector<std::meta::info> members;
|
||||
append_data_members<^^T>(members);
|
||||
return members;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval auto data_members_array() {
|
||||
return std::define_static_array(data_members<std::remove_cvref_t<T>>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval std::size_t members_count() {
|
||||
return data_members<T>().size();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval auto member_names_array() {
|
||||
static constexpr auto members = data_members_array<T>();
|
||||
std::array<std::string_view, members.size()> names{};
|
||||
[[maybe_unused]] std::size_t index = 0;
|
||||
template for (constexpr auto member : members) {
|
||||
names[index++] = member_name<member>();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
template <template <typename...> typename Predicate, typename T>
|
||||
consteval std::size_t member_index_if() {
|
||||
static constexpr auto members = data_members_array<T>();
|
||||
std::size_t result = members.size();
|
||||
std::size_t index = 0;
|
||||
template for (constexpr auto member : members) {
|
||||
using member_t = remove_cvref_meta_type_t<member>;
|
||||
if constexpr (Predicate<member_t>::value) {
|
||||
if (result == members.size()) {
|
||||
result = index;
|
||||
}
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename Visitor>
|
||||
constexpr void for_each_data_member(T&& t, Visitor&& visitor) {
|
||||
static constexpr auto members = data_members_array<T>();
|
||||
[[maybe_unused]] std::size_t index = 0;
|
||||
template for (constexpr auto member : members) {
|
||||
visitor(t.[:member:], member_name<member>(), index++);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
consteval auto member_offsets() {
|
||||
static constexpr auto members = data_members_array<T>();
|
||||
std::array<std::size_t, members.size()> offsets{};
|
||||
[[maybe_unused]] std::size_t index = 0;
|
||||
template for (constexpr auto member : members) {
|
||||
auto offset = std::meta::offset_of(member);
|
||||
offsets[index++] = static_cast<std::size_t>(offset.bytes);
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
} // namespace ylt::reflection::reflect26
|
||||
|
||||
namespace ylt::reflection {
|
||||
using reflect26::field_name;
|
||||
using reflect26::fixed_string;
|
||||
using reflect26::skip_base;
|
||||
using reflect26::skip_field;
|
||||
using reflect26::struct_name;
|
||||
} // namespace ylt::reflection
|
||||
#endif // YLT_USE_CXX26_REFLECTION
|
||||
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#include <meta>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "member_names.hpp"
|
||||
|
||||
namespace ylt::reflection::reflect26 {
|
||||
|
||||
template <typename Func, typename Field>
|
||||
void invoke_dispatch(Func& func, Field& field, std::string_view name,
|
||||
std::size_t index) {
|
||||
if constexpr (std::is_invocable_v<Func&, Field&, std::string_view,
|
||||
std::size_t>) {
|
||||
func(field, name, index);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Func&, Field&, std::string_view>) {
|
||||
func(field, name);
|
||||
}
|
||||
else if constexpr (std::is_invocable_v<Func&, Field&>) {
|
||||
func(field);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof(Func) < 0,
|
||||
"invalid arguments, full arguments: [field_value&, "
|
||||
"std::string_view, size_t], at least has field_value and "
|
||||
"make sure keep the order of arguments");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
bool dispatch_by_name(T& obj, std::string_view key, Func&& func) {
|
||||
using U = ylt::reflection::remove_cvref_t<T>;
|
||||
static constexpr auto members = data_members_array<U>();
|
||||
if constexpr (members.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
static constexpr auto names = ylt::reflection::get_member_names<U>();
|
||||
bool found = false;
|
||||
[[maybe_unused]] std::size_t index = 0;
|
||||
template for (constexpr auto member : members) {
|
||||
if (!found && key == normalized_member_name(names[index])) {
|
||||
invoke_dispatch(func, obj.[:member:], names[index], index);
|
||||
found = true;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
template <std::size_t Index, typename T, typename Func>
|
||||
void dispatch_by_index(T& obj, Func&& func) {
|
||||
static constexpr auto members = data_members_array<T>();
|
||||
static_assert(Index < members.size(), "index out of range");
|
||||
func(obj.[:members[Index]:]);
|
||||
}
|
||||
|
||||
template <typename T, typename Func>
|
||||
bool dispatch_by_index(T& obj, std::size_t target, Func&& func) {
|
||||
static constexpr auto members = data_members_array<T>();
|
||||
if constexpr (members.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
bool found = false;
|
||||
[[maybe_unused]] std::size_t index = 0;
|
||||
template for (constexpr auto member : members) {
|
||||
if (!found && index == target) {
|
||||
invoke_dispatch(func, obj.[:member:], member_name<member>(), index);
|
||||
found = true;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ylt::reflection::reflect26
|
||||
#endif // YLT_USE_CXX26_REFLECTION
|
||||
@@ -0,0 +1,198 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include "frozen/string.h"
|
||||
#include "frozen/unordered_map.h"
|
||||
|
||||
namespace ylt::reflection {
|
||||
|
||||
#if defined(__clang__) || defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && __GNUC__ > 8)
|
||||
|
||||
template <typename T>
|
||||
constexpr std::string_view get_raw_name() {
|
||||
#ifdef _MSC_VER
|
||||
return __FUNCSIG__;
|
||||
#else
|
||||
return __PRETTY_FUNCTION__;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <auto T>
|
||||
constexpr std::string_view get_raw_name() {
|
||||
#ifdef _MSC_VER
|
||||
return __FUNCSIG__;
|
||||
#else
|
||||
return __PRETTY_FUNCTION__;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr std::string_view type_string() {
|
||||
constexpr std::string_view sample = get_raw_name<int>();
|
||||
constexpr size_t prefix_length = sample.find("int");
|
||||
constexpr std::string_view str = get_raw_name<T>();
|
||||
constexpr size_t suffix_length = sample.size() - prefix_length - 3;
|
||||
auto name =
|
||||
str.substr(prefix_length, str.size() - prefix_length - suffix_length);
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
constexpr std::string_view prefixes[] = {"class ", "struct ", "union ",
|
||||
"enum "};
|
||||
for (std::string_view prefix : prefixes) {
|
||||
if (name.size() >= prefix.size() &&
|
||||
name.substr(0, prefix.size()) == prefix) {
|
||||
name.remove_prefix(prefix.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return name;
|
||||
}
|
||||
|
||||
template <auto T>
|
||||
inline constexpr std::string_view enum_string() {
|
||||
constexpr std::string_view sample = get_raw_name<int>();
|
||||
constexpr size_t pos = sample.find("int");
|
||||
constexpr std::string_view str = get_raw_name<T>();
|
||||
constexpr auto next1 = str.rfind(sample[pos + 3]);
|
||||
#if defined(__clang__) || defined(_MSC_VER)
|
||||
constexpr auto s1 = str.substr(pos, next1 - pos);
|
||||
#else
|
||||
constexpr auto s1 = str.substr(pos + 5, next1 - pos - 5);
|
||||
#endif
|
||||
return s1;
|
||||
}
|
||||
|
||||
template <auto field>
|
||||
inline constexpr std::string_view field_string() {
|
||||
constexpr std::string_view raw_name = enum_string<field>();
|
||||
return raw_name.substr(raw_name.rfind(":") + 1);
|
||||
}
|
||||
|
||||
#if defined(__clang__) && (__clang_major__ >= 17)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
|
||||
#endif
|
||||
|
||||
template <typename E, E V>
|
||||
constexpr std::string_view get_raw_name_with_v() {
|
||||
#ifdef _MSC_VER
|
||||
return __FUNCSIG__;
|
||||
#else
|
||||
return __PRETTY_FUNCTION__;
|
||||
#endif
|
||||
}
|
||||
|
||||
// True means the V is a valid enum value, and the second of the result is the
|
||||
// name
|
||||
template <typename E, E V>
|
||||
constexpr std::pair<bool, std::string_view> try_get_enum_name() {
|
||||
constexpr std::string_view sample_raw_name = get_raw_name_with_v<int, 5>();
|
||||
constexpr size_t pos = sample_raw_name.find("5");
|
||||
constexpr std::string_view enum_raw_name = get_raw_name_with_v<E, V>();
|
||||
constexpr auto enum_end = enum_raw_name.rfind(&sample_raw_name[pos + 1]);
|
||||
#ifdef _MSC_VER
|
||||
constexpr auto enum_begin = enum_raw_name.rfind(',', enum_end) + 1;
|
||||
#else
|
||||
constexpr auto enum_begin = enum_raw_name.rfind(' ', enum_end) + 1;
|
||||
#endif
|
||||
constexpr std::string_view res =
|
||||
enum_raw_name.substr(enum_begin, enum_end - enum_begin);
|
||||
|
||||
constexpr size_t pos_brackets = res.find(')');
|
||||
|
||||
size_t pos_colon = res.find("::");
|
||||
return {pos_brackets == std::string_view::npos,
|
||||
res.substr(pos_colon == std::string_view::npos ? 0 : pos_colon + 2)};
|
||||
}
|
||||
|
||||
// Enumerate the numbers in a integer sequence to see if they are legal enum
|
||||
// value
|
||||
template <typename E, std::int64_t... Is>
|
||||
constexpr inline auto get_enum_arr(
|
||||
const std::integer_sequence<std::int64_t, Is...> &) {
|
||||
constexpr std::size_t N = sizeof...(Is);
|
||||
std::array<std::string_view, N> enum_names = {};
|
||||
std::array<E, N> enum_values = {};
|
||||
std::size_t num = 0;
|
||||
(([&]() {
|
||||
constexpr auto res = try_get_enum_name<E, static_cast<E>(Is)>();
|
||||
if constexpr (res.first) {
|
||||
// the Is is a valid enum value
|
||||
enum_names[num] = res.second;
|
||||
enum_values[num] = static_cast<E>(Is);
|
||||
++num;
|
||||
}
|
||||
})(),
|
||||
...);
|
||||
return std::make_tuple(num, enum_values, enum_names);
|
||||
}
|
||||
|
||||
template <std::size_t N, const std::array<int, N> &arr, size_t... Is>
|
||||
constexpr auto array_to_seq(const std::index_sequence<Is...> &) {
|
||||
return std::integer_sequence<std::int64_t, arr[Is]...>();
|
||||
}
|
||||
|
||||
// convert array to map
|
||||
template <typename E, size_t N, size_t... Is>
|
||||
constexpr inline auto get_enum_to_str_map(
|
||||
const std::array<std::string_view, N> &enum_names,
|
||||
const std::array<E, N> &enum_values, const std::index_sequence<Is...> &) {
|
||||
return frozen::unordered_map<E, frozen::string, sizeof...(Is)>{
|
||||
{enum_values[Is], enum_names[Is]}...};
|
||||
}
|
||||
|
||||
template <typename E, size_t N, size_t... Is>
|
||||
constexpr inline auto get_str_to_enum_map(
|
||||
const std::array<std::string_view, N> &enum_names,
|
||||
const std::array<E, N> &enum_values, const std::index_sequence<Is...> &) {
|
||||
return frozen::unordered_map<frozen::string, E, sizeof...(Is)>{
|
||||
{enum_names[Is], enum_values[Is]}...};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// the default generic enum_value
|
||||
// if the user has not defined a specialization template, this will be called
|
||||
template <typename T>
|
||||
struct enum_value {
|
||||
constexpr static std::array<int, 0> value = {};
|
||||
};
|
||||
|
||||
template <bool str_to_enum, typename E>
|
||||
constexpr inline auto get_enum_map() {
|
||||
#if defined(__clang__) || defined(_MSC_VER) || \
|
||||
(defined(__GNUC__) && __GNUC__ > 8)
|
||||
constexpr auto &arr = enum_value<E>::value;
|
||||
constexpr auto arr_size = arr.size();
|
||||
if constexpr (arr_size > 0) {
|
||||
// the user has defined a specialization template
|
||||
constexpr auto arr_seq =
|
||||
array_to_seq<arr_size, arr>(std::make_index_sequence<arr_size>());
|
||||
constexpr auto t = get_enum_arr<E>(arr_seq);
|
||||
if constexpr (str_to_enum) {
|
||||
return get_str_to_enum_map<E, arr_size>(
|
||||
std::get<2>(t), std::get<1>(t),
|
||||
std::make_index_sequence<std::get<0>(t)>{});
|
||||
}
|
||||
else {
|
||||
return get_enum_to_str_map<E, arr_size>(
|
||||
std::get<2>(t), std::get<1>(t),
|
||||
std::make_index_sequence<std::get<0>(t)>{});
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__clang__) && (__clang_major__ >= 17)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
} // namespace ylt::reflection
|
||||
@@ -0,0 +1,535 @@
|
||||
#pragma once
|
||||
|
||||
namespace ylt::reflection {
|
||||
[[noreturn]] inline void unreachable() {
|
||||
// Uses compiler specific extensions if possible.
|
||||
// Even if no extension is used, undefined behavior is still raised by
|
||||
// an empty function body and the noreturn attribute.
|
||||
#ifdef __GNUC__ // GCC, Clang, ICC
|
||||
__builtin_unreachable();
|
||||
#elif defined(_MSC_VER) // msvc
|
||||
__assume(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Func, typename... Args>
|
||||
constexpr decltype(auto) inline template_switch(size_t index, Args &&...args) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return Func::template run<0>(std::forward<Args>(args)...);
|
||||
case 1:
|
||||
return Func::template run<1>(std::forward<Args>(args)...);
|
||||
case 2:
|
||||
return Func::template run<2>(std::forward<Args>(args)...);
|
||||
case 3:
|
||||
return Func::template run<3>(std::forward<Args>(args)...);
|
||||
case 4:
|
||||
return Func::template run<4>(std::forward<Args>(args)...);
|
||||
case 5:
|
||||
return Func::template run<5>(std::forward<Args>(args)...);
|
||||
case 6:
|
||||
return Func::template run<6>(std::forward<Args>(args)...);
|
||||
case 7:
|
||||
return Func::template run<7>(std::forward<Args>(args)...);
|
||||
case 8:
|
||||
return Func::template run<8>(std::forward<Args>(args)...);
|
||||
case 9:
|
||||
return Func::template run<9>(std::forward<Args>(args)...);
|
||||
case 10:
|
||||
return Func::template run<10>(std::forward<Args>(args)...);
|
||||
case 11:
|
||||
return Func::template run<11>(std::forward<Args>(args)...);
|
||||
case 12:
|
||||
return Func::template run<12>(std::forward<Args>(args)...);
|
||||
case 13:
|
||||
return Func::template run<13>(std::forward<Args>(args)...);
|
||||
case 14:
|
||||
return Func::template run<14>(std::forward<Args>(args)...);
|
||||
case 15:
|
||||
return Func::template run<15>(std::forward<Args>(args)...);
|
||||
case 16:
|
||||
return Func::template run<16>(std::forward<Args>(args)...);
|
||||
case 17:
|
||||
return Func::template run<17>(std::forward<Args>(args)...);
|
||||
case 18:
|
||||
return Func::template run<18>(std::forward<Args>(args)...);
|
||||
case 19:
|
||||
return Func::template run<19>(std::forward<Args>(args)...);
|
||||
case 20:
|
||||
return Func::template run<20>(std::forward<Args>(args)...);
|
||||
case 21:
|
||||
return Func::template run<21>(std::forward<Args>(args)...);
|
||||
case 22:
|
||||
return Func::template run<22>(std::forward<Args>(args)...);
|
||||
case 23:
|
||||
return Func::template run<23>(std::forward<Args>(args)...);
|
||||
case 24:
|
||||
return Func::template run<24>(std::forward<Args>(args)...);
|
||||
case 25:
|
||||
return Func::template run<25>(std::forward<Args>(args)...);
|
||||
case 26:
|
||||
return Func::template run<26>(std::forward<Args>(args)...);
|
||||
case 27:
|
||||
return Func::template run<27>(std::forward<Args>(args)...);
|
||||
case 28:
|
||||
return Func::template run<28>(std::forward<Args>(args)...);
|
||||
case 29:
|
||||
return Func::template run<29>(std::forward<Args>(args)...);
|
||||
case 30:
|
||||
return Func::template run<30>(std::forward<Args>(args)...);
|
||||
case 31:
|
||||
return Func::template run<31>(std::forward<Args>(args)...);
|
||||
case 32:
|
||||
return Func::template run<32>(std::forward<Args>(args)...);
|
||||
case 33:
|
||||
return Func::template run<33>(std::forward<Args>(args)...);
|
||||
case 34:
|
||||
return Func::template run<34>(std::forward<Args>(args)...);
|
||||
case 35:
|
||||
return Func::template run<35>(std::forward<Args>(args)...);
|
||||
case 36:
|
||||
return Func::template run<36>(std::forward<Args>(args)...);
|
||||
case 37:
|
||||
return Func::template run<37>(std::forward<Args>(args)...);
|
||||
case 38:
|
||||
return Func::template run<38>(std::forward<Args>(args)...);
|
||||
case 39:
|
||||
return Func::template run<39>(std::forward<Args>(args)...);
|
||||
case 40:
|
||||
return Func::template run<40>(std::forward<Args>(args)...);
|
||||
case 41:
|
||||
return Func::template run<41>(std::forward<Args>(args)...);
|
||||
case 42:
|
||||
return Func::template run<42>(std::forward<Args>(args)...);
|
||||
case 43:
|
||||
return Func::template run<43>(std::forward<Args>(args)...);
|
||||
case 44:
|
||||
return Func::template run<44>(std::forward<Args>(args)...);
|
||||
case 45:
|
||||
return Func::template run<45>(std::forward<Args>(args)...);
|
||||
case 46:
|
||||
return Func::template run<46>(std::forward<Args>(args)...);
|
||||
case 47:
|
||||
return Func::template run<47>(std::forward<Args>(args)...);
|
||||
case 48:
|
||||
return Func::template run<48>(std::forward<Args>(args)...);
|
||||
case 49:
|
||||
return Func::template run<49>(std::forward<Args>(args)...);
|
||||
case 50:
|
||||
return Func::template run<50>(std::forward<Args>(args)...);
|
||||
case 51:
|
||||
return Func::template run<51>(std::forward<Args>(args)...);
|
||||
case 52:
|
||||
return Func::template run<52>(std::forward<Args>(args)...);
|
||||
case 53:
|
||||
return Func::template run<53>(std::forward<Args>(args)...);
|
||||
case 54:
|
||||
return Func::template run<54>(std::forward<Args>(args)...);
|
||||
case 55:
|
||||
return Func::template run<55>(std::forward<Args>(args)...);
|
||||
case 56:
|
||||
return Func::template run<56>(std::forward<Args>(args)...);
|
||||
case 57:
|
||||
return Func::template run<57>(std::forward<Args>(args)...);
|
||||
case 58:
|
||||
return Func::template run<58>(std::forward<Args>(args)...);
|
||||
case 59:
|
||||
return Func::template run<59>(std::forward<Args>(args)...);
|
||||
case 60:
|
||||
return Func::template run<60>(std::forward<Args>(args)...);
|
||||
case 61:
|
||||
return Func::template run<61>(std::forward<Args>(args)...);
|
||||
case 62:
|
||||
return Func::template run<62>(std::forward<Args>(args)...);
|
||||
case 63:
|
||||
return Func::template run<63>(std::forward<Args>(args)...);
|
||||
case 64:
|
||||
return Func::template run<64>(std::forward<Args>(args)...);
|
||||
case 65:
|
||||
return Func::template run<65>(std::forward<Args>(args)...);
|
||||
case 66:
|
||||
return Func::template run<66>(std::forward<Args>(args)...);
|
||||
case 67:
|
||||
return Func::template run<67>(std::forward<Args>(args)...);
|
||||
case 68:
|
||||
return Func::template run<68>(std::forward<Args>(args)...);
|
||||
case 69:
|
||||
return Func::template run<69>(std::forward<Args>(args)...);
|
||||
case 70:
|
||||
return Func::template run<70>(std::forward<Args>(args)...);
|
||||
case 71:
|
||||
return Func::template run<71>(std::forward<Args>(args)...);
|
||||
case 72:
|
||||
return Func::template run<72>(std::forward<Args>(args)...);
|
||||
case 73:
|
||||
return Func::template run<73>(std::forward<Args>(args)...);
|
||||
case 74:
|
||||
return Func::template run<74>(std::forward<Args>(args)...);
|
||||
case 75:
|
||||
return Func::template run<75>(std::forward<Args>(args)...);
|
||||
case 76:
|
||||
return Func::template run<76>(std::forward<Args>(args)...);
|
||||
case 77:
|
||||
return Func::template run<77>(std::forward<Args>(args)...);
|
||||
case 78:
|
||||
return Func::template run<78>(std::forward<Args>(args)...);
|
||||
case 79:
|
||||
return Func::template run<79>(std::forward<Args>(args)...);
|
||||
case 80:
|
||||
return Func::template run<80>(std::forward<Args>(args)...);
|
||||
case 81:
|
||||
return Func::template run<81>(std::forward<Args>(args)...);
|
||||
case 82:
|
||||
return Func::template run<82>(std::forward<Args>(args)...);
|
||||
case 83:
|
||||
return Func::template run<83>(std::forward<Args>(args)...);
|
||||
case 84:
|
||||
return Func::template run<84>(std::forward<Args>(args)...);
|
||||
case 85:
|
||||
return Func::template run<85>(std::forward<Args>(args)...);
|
||||
case 86:
|
||||
return Func::template run<86>(std::forward<Args>(args)...);
|
||||
case 87:
|
||||
return Func::template run<87>(std::forward<Args>(args)...);
|
||||
case 88:
|
||||
return Func::template run<88>(std::forward<Args>(args)...);
|
||||
case 89:
|
||||
return Func::template run<89>(std::forward<Args>(args)...);
|
||||
case 90:
|
||||
return Func::template run<90>(std::forward<Args>(args)...);
|
||||
case 91:
|
||||
return Func::template run<91>(std::forward<Args>(args)...);
|
||||
case 92:
|
||||
return Func::template run<92>(std::forward<Args>(args)...);
|
||||
case 93:
|
||||
return Func::template run<93>(std::forward<Args>(args)...);
|
||||
case 94:
|
||||
return Func::template run<94>(std::forward<Args>(args)...);
|
||||
case 95:
|
||||
return Func::template run<95>(std::forward<Args>(args)...);
|
||||
case 96:
|
||||
return Func::template run<96>(std::forward<Args>(args)...);
|
||||
case 97:
|
||||
return Func::template run<97>(std::forward<Args>(args)...);
|
||||
case 98:
|
||||
return Func::template run<98>(std::forward<Args>(args)...);
|
||||
case 99:
|
||||
return Func::template run<99>(std::forward<Args>(args)...);
|
||||
case 100:
|
||||
return Func::template run<100>(std::forward<Args>(args)...);
|
||||
case 101:
|
||||
return Func::template run<101>(std::forward<Args>(args)...);
|
||||
case 102:
|
||||
return Func::template run<102>(std::forward<Args>(args)...);
|
||||
case 103:
|
||||
return Func::template run<103>(std::forward<Args>(args)...);
|
||||
case 104:
|
||||
return Func::template run<104>(std::forward<Args>(args)...);
|
||||
case 105:
|
||||
return Func::template run<105>(std::forward<Args>(args)...);
|
||||
case 106:
|
||||
return Func::template run<106>(std::forward<Args>(args)...);
|
||||
case 107:
|
||||
return Func::template run<107>(std::forward<Args>(args)...);
|
||||
case 108:
|
||||
return Func::template run<108>(std::forward<Args>(args)...);
|
||||
case 109:
|
||||
return Func::template run<109>(std::forward<Args>(args)...);
|
||||
case 110:
|
||||
return Func::template run<110>(std::forward<Args>(args)...);
|
||||
case 111:
|
||||
return Func::template run<111>(std::forward<Args>(args)...);
|
||||
case 112:
|
||||
return Func::template run<112>(std::forward<Args>(args)...);
|
||||
case 113:
|
||||
return Func::template run<113>(std::forward<Args>(args)...);
|
||||
case 114:
|
||||
return Func::template run<114>(std::forward<Args>(args)...);
|
||||
case 115:
|
||||
return Func::template run<115>(std::forward<Args>(args)...);
|
||||
case 116:
|
||||
return Func::template run<116>(std::forward<Args>(args)...);
|
||||
case 117:
|
||||
return Func::template run<117>(std::forward<Args>(args)...);
|
||||
case 118:
|
||||
return Func::template run<118>(std::forward<Args>(args)...);
|
||||
case 119:
|
||||
return Func::template run<119>(std::forward<Args>(args)...);
|
||||
case 120:
|
||||
return Func::template run<120>(std::forward<Args>(args)...);
|
||||
case 121:
|
||||
return Func::template run<121>(std::forward<Args>(args)...);
|
||||
case 122:
|
||||
return Func::template run<122>(std::forward<Args>(args)...);
|
||||
case 123:
|
||||
return Func::template run<123>(std::forward<Args>(args)...);
|
||||
case 124:
|
||||
return Func::template run<124>(std::forward<Args>(args)...);
|
||||
case 125:
|
||||
return Func::template run<125>(std::forward<Args>(args)...);
|
||||
case 126:
|
||||
return Func::template run<126>(std::forward<Args>(args)...);
|
||||
case 127:
|
||||
return Func::template run<127>(std::forward<Args>(args)...);
|
||||
case 128:
|
||||
return Func::template run<128>(std::forward<Args>(args)...);
|
||||
case 129:
|
||||
return Func::template run<129>(std::forward<Args>(args)...);
|
||||
case 130:
|
||||
return Func::template run<130>(std::forward<Args>(args)...);
|
||||
case 131:
|
||||
return Func::template run<131>(std::forward<Args>(args)...);
|
||||
case 132:
|
||||
return Func::template run<132>(std::forward<Args>(args)...);
|
||||
case 133:
|
||||
return Func::template run<133>(std::forward<Args>(args)...);
|
||||
case 134:
|
||||
return Func::template run<134>(std::forward<Args>(args)...);
|
||||
case 135:
|
||||
return Func::template run<135>(std::forward<Args>(args)...);
|
||||
case 136:
|
||||
return Func::template run<136>(std::forward<Args>(args)...);
|
||||
case 137:
|
||||
return Func::template run<137>(std::forward<Args>(args)...);
|
||||
case 138:
|
||||
return Func::template run<138>(std::forward<Args>(args)...);
|
||||
case 139:
|
||||
return Func::template run<139>(std::forward<Args>(args)...);
|
||||
case 140:
|
||||
return Func::template run<140>(std::forward<Args>(args)...);
|
||||
case 141:
|
||||
return Func::template run<141>(std::forward<Args>(args)...);
|
||||
case 142:
|
||||
return Func::template run<142>(std::forward<Args>(args)...);
|
||||
case 143:
|
||||
return Func::template run<143>(std::forward<Args>(args)...);
|
||||
case 144:
|
||||
return Func::template run<144>(std::forward<Args>(args)...);
|
||||
case 145:
|
||||
return Func::template run<145>(std::forward<Args>(args)...);
|
||||
case 146:
|
||||
return Func::template run<146>(std::forward<Args>(args)...);
|
||||
case 147:
|
||||
return Func::template run<147>(std::forward<Args>(args)...);
|
||||
case 148:
|
||||
return Func::template run<148>(std::forward<Args>(args)...);
|
||||
case 149:
|
||||
return Func::template run<149>(std::forward<Args>(args)...);
|
||||
case 150:
|
||||
return Func::template run<150>(std::forward<Args>(args)...);
|
||||
case 151:
|
||||
return Func::template run<151>(std::forward<Args>(args)...);
|
||||
case 152:
|
||||
return Func::template run<152>(std::forward<Args>(args)...);
|
||||
case 153:
|
||||
return Func::template run<153>(std::forward<Args>(args)...);
|
||||
case 154:
|
||||
return Func::template run<154>(std::forward<Args>(args)...);
|
||||
case 155:
|
||||
return Func::template run<155>(std::forward<Args>(args)...);
|
||||
case 156:
|
||||
return Func::template run<156>(std::forward<Args>(args)...);
|
||||
case 157:
|
||||
return Func::template run<157>(std::forward<Args>(args)...);
|
||||
case 158:
|
||||
return Func::template run<158>(std::forward<Args>(args)...);
|
||||
case 159:
|
||||
return Func::template run<159>(std::forward<Args>(args)...);
|
||||
case 160:
|
||||
return Func::template run<160>(std::forward<Args>(args)...);
|
||||
case 161:
|
||||
return Func::template run<161>(std::forward<Args>(args)...);
|
||||
case 162:
|
||||
return Func::template run<162>(std::forward<Args>(args)...);
|
||||
case 163:
|
||||
return Func::template run<163>(std::forward<Args>(args)...);
|
||||
case 164:
|
||||
return Func::template run<164>(std::forward<Args>(args)...);
|
||||
case 165:
|
||||
return Func::template run<165>(std::forward<Args>(args)...);
|
||||
case 166:
|
||||
return Func::template run<166>(std::forward<Args>(args)...);
|
||||
case 167:
|
||||
return Func::template run<167>(std::forward<Args>(args)...);
|
||||
case 168:
|
||||
return Func::template run<168>(std::forward<Args>(args)...);
|
||||
case 169:
|
||||
return Func::template run<169>(std::forward<Args>(args)...);
|
||||
case 170:
|
||||
return Func::template run<170>(std::forward<Args>(args)...);
|
||||
case 171:
|
||||
return Func::template run<171>(std::forward<Args>(args)...);
|
||||
case 172:
|
||||
return Func::template run<172>(std::forward<Args>(args)...);
|
||||
case 173:
|
||||
return Func::template run<173>(std::forward<Args>(args)...);
|
||||
case 174:
|
||||
return Func::template run<174>(std::forward<Args>(args)...);
|
||||
case 175:
|
||||
return Func::template run<175>(std::forward<Args>(args)...);
|
||||
case 176:
|
||||
return Func::template run<176>(std::forward<Args>(args)...);
|
||||
case 177:
|
||||
return Func::template run<177>(std::forward<Args>(args)...);
|
||||
case 178:
|
||||
return Func::template run<178>(std::forward<Args>(args)...);
|
||||
case 179:
|
||||
return Func::template run<179>(std::forward<Args>(args)...);
|
||||
case 180:
|
||||
return Func::template run<180>(std::forward<Args>(args)...);
|
||||
case 181:
|
||||
return Func::template run<181>(std::forward<Args>(args)...);
|
||||
case 182:
|
||||
return Func::template run<182>(std::forward<Args>(args)...);
|
||||
case 183:
|
||||
return Func::template run<183>(std::forward<Args>(args)...);
|
||||
case 184:
|
||||
return Func::template run<184>(std::forward<Args>(args)...);
|
||||
case 185:
|
||||
return Func::template run<185>(std::forward<Args>(args)...);
|
||||
case 186:
|
||||
return Func::template run<186>(std::forward<Args>(args)...);
|
||||
case 187:
|
||||
return Func::template run<187>(std::forward<Args>(args)...);
|
||||
case 188:
|
||||
return Func::template run<188>(std::forward<Args>(args)...);
|
||||
case 189:
|
||||
return Func::template run<189>(std::forward<Args>(args)...);
|
||||
case 190:
|
||||
return Func::template run<190>(std::forward<Args>(args)...);
|
||||
case 191:
|
||||
return Func::template run<191>(std::forward<Args>(args)...);
|
||||
case 192:
|
||||
return Func::template run<192>(std::forward<Args>(args)...);
|
||||
case 193:
|
||||
return Func::template run<193>(std::forward<Args>(args)...);
|
||||
case 194:
|
||||
return Func::template run<194>(std::forward<Args>(args)...);
|
||||
case 195:
|
||||
return Func::template run<195>(std::forward<Args>(args)...);
|
||||
case 196:
|
||||
return Func::template run<196>(std::forward<Args>(args)...);
|
||||
case 197:
|
||||
return Func::template run<197>(std::forward<Args>(args)...);
|
||||
case 198:
|
||||
return Func::template run<198>(std::forward<Args>(args)...);
|
||||
case 199:
|
||||
return Func::template run<199>(std::forward<Args>(args)...);
|
||||
case 200:
|
||||
return Func::template run<200>(std::forward<Args>(args)...);
|
||||
case 201:
|
||||
return Func::template run<201>(std::forward<Args>(args)...);
|
||||
case 202:
|
||||
return Func::template run<202>(std::forward<Args>(args)...);
|
||||
case 203:
|
||||
return Func::template run<203>(std::forward<Args>(args)...);
|
||||
case 204:
|
||||
return Func::template run<204>(std::forward<Args>(args)...);
|
||||
case 205:
|
||||
return Func::template run<205>(std::forward<Args>(args)...);
|
||||
case 206:
|
||||
return Func::template run<206>(std::forward<Args>(args)...);
|
||||
case 207:
|
||||
return Func::template run<207>(std::forward<Args>(args)...);
|
||||
case 208:
|
||||
return Func::template run<208>(std::forward<Args>(args)...);
|
||||
case 209:
|
||||
return Func::template run<209>(std::forward<Args>(args)...);
|
||||
case 210:
|
||||
return Func::template run<210>(std::forward<Args>(args)...);
|
||||
case 211:
|
||||
return Func::template run<211>(std::forward<Args>(args)...);
|
||||
case 212:
|
||||
return Func::template run<212>(std::forward<Args>(args)...);
|
||||
case 213:
|
||||
return Func::template run<213>(std::forward<Args>(args)...);
|
||||
case 214:
|
||||
return Func::template run<214>(std::forward<Args>(args)...);
|
||||
case 215:
|
||||
return Func::template run<215>(std::forward<Args>(args)...);
|
||||
case 216:
|
||||
return Func::template run<216>(std::forward<Args>(args)...);
|
||||
case 217:
|
||||
return Func::template run<217>(std::forward<Args>(args)...);
|
||||
case 218:
|
||||
return Func::template run<218>(std::forward<Args>(args)...);
|
||||
case 219:
|
||||
return Func::template run<219>(std::forward<Args>(args)...);
|
||||
case 220:
|
||||
return Func::template run<220>(std::forward<Args>(args)...);
|
||||
case 221:
|
||||
return Func::template run<221>(std::forward<Args>(args)...);
|
||||
case 222:
|
||||
return Func::template run<222>(std::forward<Args>(args)...);
|
||||
case 223:
|
||||
return Func::template run<223>(std::forward<Args>(args)...);
|
||||
case 224:
|
||||
return Func::template run<224>(std::forward<Args>(args)...);
|
||||
case 225:
|
||||
return Func::template run<225>(std::forward<Args>(args)...);
|
||||
case 226:
|
||||
return Func::template run<226>(std::forward<Args>(args)...);
|
||||
case 227:
|
||||
return Func::template run<227>(std::forward<Args>(args)...);
|
||||
case 228:
|
||||
return Func::template run<228>(std::forward<Args>(args)...);
|
||||
case 229:
|
||||
return Func::template run<229>(std::forward<Args>(args)...);
|
||||
case 230:
|
||||
return Func::template run<230>(std::forward<Args>(args)...);
|
||||
case 231:
|
||||
return Func::template run<231>(std::forward<Args>(args)...);
|
||||
case 232:
|
||||
return Func::template run<232>(std::forward<Args>(args)...);
|
||||
case 233:
|
||||
return Func::template run<233>(std::forward<Args>(args)...);
|
||||
case 234:
|
||||
return Func::template run<234>(std::forward<Args>(args)...);
|
||||
case 235:
|
||||
return Func::template run<235>(std::forward<Args>(args)...);
|
||||
case 236:
|
||||
return Func::template run<236>(std::forward<Args>(args)...);
|
||||
case 237:
|
||||
return Func::template run<237>(std::forward<Args>(args)...);
|
||||
case 238:
|
||||
return Func::template run<238>(std::forward<Args>(args)...);
|
||||
case 239:
|
||||
return Func::template run<239>(std::forward<Args>(args)...);
|
||||
case 240:
|
||||
return Func::template run<240>(std::forward<Args>(args)...);
|
||||
case 241:
|
||||
return Func::template run<241>(std::forward<Args>(args)...);
|
||||
case 242:
|
||||
return Func::template run<242>(std::forward<Args>(args)...);
|
||||
case 243:
|
||||
return Func::template run<243>(std::forward<Args>(args)...);
|
||||
case 244:
|
||||
return Func::template run<244>(std::forward<Args>(args)...);
|
||||
case 245:
|
||||
return Func::template run<245>(std::forward<Args>(args)...);
|
||||
case 246:
|
||||
return Func::template run<246>(std::forward<Args>(args)...);
|
||||
case 247:
|
||||
return Func::template run<247>(std::forward<Args>(args)...);
|
||||
case 248:
|
||||
return Func::template run<248>(std::forward<Args>(args)...);
|
||||
case 249:
|
||||
return Func::template run<249>(std::forward<Args>(args)...);
|
||||
case 250:
|
||||
return Func::template run<250>(std::forward<Args>(args)...);
|
||||
case 251:
|
||||
return Func::template run<251>(std::forward<Args>(args)...);
|
||||
case 252:
|
||||
return Func::template run<252>(std::forward<Args>(args)...);
|
||||
case 253:
|
||||
return Func::template run<253>(std::forward<Args>(args)...);
|
||||
case 254:
|
||||
return Func::template run<254>(std::forward<Args>(args)...);
|
||||
case 255:
|
||||
return Func::template run<255>(std::forward<Args>(args)...);
|
||||
default:
|
||||
unreachable();
|
||||
// index shouldn't bigger than 256
|
||||
}
|
||||
}
|
||||
} // namespace ylt::reflection
|
||||
@@ -0,0 +1,178 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#include "internal/arg_list_macro.hpp"
|
||||
#include "reflect26_compat.hpp"
|
||||
|
||||
namespace ylt::reflection {
|
||||
template <typename T>
|
||||
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
||||
|
||||
template <class T>
|
||||
struct member_traits {
|
||||
using value_type = T;
|
||||
};
|
||||
|
||||
template <class T, class Owner>
|
||||
struct member_traits<T Owner::*> {
|
||||
using owner_type = Owner;
|
||||
using value_type = T;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using member_value_type_t = typename member_traits<T>::value_type;
|
||||
|
||||
#define YLT_REFL(STRUCT, ...) \
|
||||
template <typename Visitor> \
|
||||
inline static constexpr decltype(auto) refl_visit_members( \
|
||||
STRUCT &t, Visitor &&visitor) { \
|
||||
return visitor(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \
|
||||
} \
|
||||
template <typename Visitor> \
|
||||
inline static constexpr decltype(auto) refl_visit_members( \
|
||||
const STRUCT &t, Visitor &&visitor) { \
|
||||
return visitor(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \
|
||||
} \
|
||||
[[maybe_unused]] inline static decltype(auto) refl_object_to_tuple( \
|
||||
STRUCT &t) { \
|
||||
return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \
|
||||
} \
|
||||
[[maybe_unused]] inline static decltype(auto) refl_object_to_tuple( \
|
||||
const STRUCT &t) { \
|
||||
return std::tie(WRAP_ARGS(CONCAT_MEMBER, t, ##__VA_ARGS__)); \
|
||||
} \
|
||||
[[maybe_unused]] inline static constexpr decltype(auto) refl_member_names( \
|
||||
const ylt::reflection::identity<STRUCT> &t) { \
|
||||
constexpr std::array<std::string_view, YLT_ARG_COUNT(__VA_ARGS__)> arr{ \
|
||||
WRAP_ARGS(CONCAT_NAME, t, ##__VA_ARGS__)}; \
|
||||
return arr; \
|
||||
} \
|
||||
[[maybe_unused]] inline static constexpr std::size_t refl_member_count( \
|
||||
const ylt::reflection::identity<STRUCT> &t) { \
|
||||
return (std::size_t)YLT_ARG_COUNT(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
template <typename T, typename Tuple, typename Visitor>
|
||||
inline constexpr auto visit_private_fields_impl(T &&t, const Tuple &tp,
|
||||
Visitor &&visitor) {
|
||||
return std::apply(
|
||||
[&](auto... args) {
|
||||
return visitor(t.*args...);
|
||||
},
|
||||
tp);
|
||||
}
|
||||
|
||||
template <typename T, typename Visitor>
|
||||
inline constexpr auto visit_private_fields(T &&t, Visitor &&visitor) {
|
||||
auto tp = get_private_ptrs(
|
||||
identity<std::remove_const_t<std::remove_reference_t<T>>>{});
|
||||
return visit_private_fields_impl(std::forward<T>(t), tp, visitor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline static decltype(auto) refl_object_to_tuple_impl(T &&t) {
|
||||
auto tp = get_private_ptrs(
|
||||
identity<std::remove_const_t<std::remove_reference_t<T>>>{});
|
||||
auto to_ref = [&t](auto... fields) {
|
||||
return std::tie(t.*fields...);
|
||||
};
|
||||
return std::apply(to_ref, tp);
|
||||
}
|
||||
|
||||
#define YLT_REFL_PRIVATE_(STRUCT, ...) \
|
||||
namespace ylt::reflection { \
|
||||
inline constexpr auto get_private_ptrs(const identity<STRUCT> &t); \
|
||||
template struct private_visitor<STRUCT, ##__VA_ARGS__>; \
|
||||
} \
|
||||
template <typename Visitor> \
|
||||
inline static constexpr decltype(auto) refl_visit_members( \
|
||||
STRUCT &t, Visitor &&visitor) { \
|
||||
return visit_private_fields(t, std::forward<Visitor>(visitor)); \
|
||||
} \
|
||||
template <typename Visitor> \
|
||||
inline static constexpr decltype(auto) refl_visit_members( \
|
||||
const STRUCT &t, Visitor &&visitor) { \
|
||||
return visit_private_fields(t, std::forward<Visitor>(visitor)); \
|
||||
} \
|
||||
[[maybe_unused]] inline static decltype(auto) refl_object_to_tuple( \
|
||||
STRUCT &t) { \
|
||||
return refl_object_to_tuple_impl(t); \
|
||||
} \
|
||||
[[maybe_unused]] inline static decltype(auto) refl_object_to_tuple( \
|
||||
const STRUCT &t) { \
|
||||
return refl_object_to_tuple_impl(t); \
|
||||
} \
|
||||
[[maybe_unused]] inline static constexpr std::size_t refl_member_count( \
|
||||
const ylt::reflection::identity<STRUCT> &t) { \
|
||||
return (std::size_t)YLT_ARG_COUNT(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define YLT_REFL_PRIVATE(STRUCT, ...) \
|
||||
[[maybe_unused]] inline static constexpr decltype(auto) refl_member_names( \
|
||||
const ylt::reflection::identity<STRUCT> &t) { \
|
||||
constexpr std::array<std::string_view, YLT_ARG_COUNT(__VA_ARGS__)> arr{ \
|
||||
WRAP_ARGS(CONCAT_NAME, t, ##__VA_ARGS__)}; \
|
||||
return arr; \
|
||||
} \
|
||||
YLT_REFL_PRIVATE_(STRUCT, WRAP_ARGS(CONCAT_ADDR, STRUCT, ##__VA_ARGS__))
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_out_ylt_refl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_out_ylt_refl<T, std::void_t<decltype(refl_member_count(
|
||||
std::declval<ylt::reflection::identity<T>>()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_out_ylt_refl_v = is_out_ylt_refl<T>::value;
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_inner_ylt_refl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_inner_ylt_refl<
|
||||
T, std::void_t<decltype(std::declval<T>().refl_member_count(
|
||||
std::declval<ylt::reflection::identity<T>>()))>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_inner_ylt_refl_v = is_inner_ylt_refl<T>::value;
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_ylt_refl : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_ylt_refl_v = is_ylt_refl<remove_cvref_t<T>>::value;
|
||||
|
||||
template <typename T>
|
||||
struct is_ylt_refl<T, std::enable_if_t<is_inner_ylt_refl_v<T>>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_ylt_refl<T, std::enable_if_t<is_out_ylt_refl_v<T>>> : std::true_type {
|
||||
};
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct is_custom_reflect : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_custom_reflect<
|
||||
T, std::void_t<decltype(ylt_custom_reflect((T *)nullptr))>>
|
||||
: std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_custom_refl_v =
|
||||
is_custom_reflect<remove_cvref_t<T>>::value;
|
||||
#ifdef YLT_USE_CXX26_REFLECTION
|
||||
#undef YLT_REFL
|
||||
#undef YLT_REFL_PRIVATE
|
||||
#undef YLT_REFL_PRIVATE_
|
||||
#define YLT_REFL(STRUCT, ...)
|
||||
#define YLT_REFL_PRIVATE(STRUCT, ...)
|
||||
#define YLT_REFL_PRIVATE_(STRUCT, ...)
|
||||
#endif
|
||||
|
||||
} // namespace ylt::reflection
|
||||
+2464
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user