更新:1、新增数据记录功能,将过程数据录入数据库;

2、增加输入点迹数据、凝聚后点迹数据记录;

Signed-off-by: waiwaylee <waiwaylee@foxmail.com>
This commit is contained in:
2026-09-30 09:02:28 +08:00
parent ff9b111d34
commit a4f32e4036
111 changed files with 321343 additions and 262 deletions
@@ -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
@@ -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
+224
View File
@@ -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
+461
View File
@@ -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
+157
View File
@@ -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
+430
View File
@@ -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
File diff suppressed because it is too large Load Diff