Go to the documentation of this file.
9#define HOOKS_ENUM(...) enum Hooks { __VA_ARGS__, LAST };
11#define CREATE_MC1(m1) CREATE_METHOD_CHECKS(m1);
12#define CREATE_MC2(m1, m2) \
13 CREATE_METHOD_CHECKS(m1); \
14 CREATE_METHOD_CHECKS(m2);
15#define CREATE_MC3(m1, m2, m3) \
16 CREATE_METHOD_CHECKS(m1); \
17 CREATE_METHOD_CHECKS(m2); \
18 CREATE_METHOD_CHECKS(m3);
19#define CREATE_MC4(m1, m2, m3, m4) \
20 CREATE_METHOD_CHECKS(m1); \
21 CREATE_METHOD_CHECKS(m2); \
22 CREATE_METHOD_CHECKS(m3); \
23 CREATE_METHOD_CHECKS(m4);
24#define CREATE_MC5(m1, m2, m3, m4, m5) \
25 CREATE_METHOD_CHECKS(m1); \
26 CREATE_METHOD_CHECKS(m2); \
27 CREATE_METHOD_CHECKS(m3); \
28 CREATE_METHOD_CHECKS(m4); \
29 CREATE_METHOD_CHECKS(m5);
30#define CREATE_MC6(m1, m2, m3, m4, m5, m6) \
31 CREATE_METHOD_CHECKS(m1); \
32 CREATE_METHOD_CHECKS(m2); \
33 CREATE_METHOD_CHECKS(m3); \
34 CREATE_METHOD_CHECKS(m4); \
35 CREATE_METHOD_CHECKS(m5); \
36 CREATE_METHOD_CHECKS(m6);
37#define CREATE_MC7(m1, m2, m3, m4, m5, m6, m7) \
38 CREATE_METHOD_CHECKS(m1); \
39 CREATE_METHOD_CHECKS(m2); \
40 CREATE_METHOD_CHECKS(m3); \
41 CREATE_METHOD_CHECKS(m4); \
42 CREATE_METHOD_CHECKS(m5); \
43 CREATE_METHOD_CHECKS(m6); \
44 CREATE_METHOD_CHECKS(m7);
45#define CREATE_MC8(m1, m2, m3, m4, m5, m6, m7, m8) \
46 CREATE_METHOD_CHECKS(m1); \
47 CREATE_METHOD_CHECKS(m2); \
48 CREATE_METHOD_CHECKS(m3); \
49 CREATE_METHOD_CHECKS(m4); \
50 CREATE_METHOD_CHECKS(m5); \
51 CREATE_METHOD_CHECKS(m6); \
52 CREATE_METHOD_CHECKS(m7); \
53 CREATE_METHOD_CHECKS(m8);
54#define CREATE_MC9(m1, m2, m3, m4, m5, m6, m7, m8, m9) \
55 CREATE_METHOD_CHECKS(m1); \
56 CREATE_METHOD_CHECKS(m2); \
57 CREATE_METHOD_CHECKS(m3); \
58 CREATE_METHOD_CHECKS(m4); \
59 CREATE_METHOD_CHECKS(m5); \
60 CREATE_METHOD_CHECKS(m6); \
61 CREATE_METHOD_CHECKS(m7); \
62 CREATE_METHOD_CHECKS(m8); \
63 CREATE_METHOD_CHECKS(m9);
65#define OVERLOADED_MACRO(M, ...) _OVR(M, _COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)
66#define _OVR(macroName, number_of_args) _OVR_EXPAND(macroName, number_of_args)
67#define _OVR_EXPAND(macroName, number_of_args) macroName##number_of_args
69#define _COUNT_ARGS(...) _ARG_PATTERN_MATCH(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
70#define _ARG_PATTERN_MATCH(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
72#define HCHK_M(hName) \
74 static std::enable_if_t<is_##hName##_callable<P, hook_s>::value> register_##hName( \
76 c->registerHook(Hooks::hName, [&](H *hc) { p.hName(hc); }); \
79 static std::enable_if_t<!is_##hName##_callable<P, hook_s>::value> register_##hName( \
82#define HCHK_M1(h1) HCHK_M(h1)
83#define HCHK_M2(h1, h2) \
86#define HCHK_M3(h1, h2, h3) \
90#define HCHK_M4(h1, h2, h3, h4) \
95#define HCHK_M5(h1, h2, h3, h4, h5) \
101#define HCHK_M6(h1, h2, h3, h4, h5, h6) \
108#define HCHK_M7(h1, h2, h3, h4, h5, h6, h7) \
116#define HCHK_M8(h1, h2, h3, h4, h5, h6, h7, h8) \
125#define HCHK_M9(h1, h2, h3, h4, h5, h6, h7, h8, h9) \
136#define H_REG(hName) hookChecker<decltype(this), hook_s>::register_##hName(this, p)
138#define H_REG1(h1) H_REG(h1);
139#define H_REG2(h1, h2) \
142#define H_REG3(h1, h2, h3) \
146#define H_REG4(h1, h2, h3, h4) \
151#define H_REG5(h1, h2, h3, h4, h5) \
157#define H_REG6(h1, h2, h3, h4, h5, h6) \
164#define H_REG7(h1, h2, h3, h4, h5, h6, h7) \
172#define H_REG8(h1, h2, h3, h4, h5, h6, h7, h8) \
181#define H_REG9(h1, h2, h3, h4, h5, h6, h7, h8, h9) \
192#define DECLARE_HOOK(...) \
193 HOOKS_ENUM(__VA_ARGS__) \
194 OVERLOADED_MACRO(CREATE_MC, __VA_ARGS__) \
195 CREATE_METHOD_CHECKS(onRegister); \
196 template <class HookableClass, class hook_s> struct hookChecker { \
197 using H = std::remove_pointer_t<std::remove_reference_t<HookableClass>>; \
198 using hook_t = std::function<hook_s>; \
200 static std::enable_if_t<is_onRegister_callable<P, hook_s>::value, hook_t> \
201 getOnRegister(P &p) { \
202 return [&](H *hc) { p.onRegister(hc); }; \
206 static std::enable_if_t<!is_onRegister_callable<P, hook_s>::value, hook_t> \
207 getOnRegister(P &) { \
208 return [&](H *) {}; \
210 OVERLOADED_MACRO(HCHK_M, __VA_ARGS__) \
212 using hook_t = std::function<hook_s>; \
213 std::array<std::vector<hook_t>, Hooks::LAST> hooks; \
214 template <class P> hook_t registerPlugin(P &p) { \
215 OVERLOADED_MACRO(H_REG, __VA_ARGS__) \
216 return hookChecker<decltype(this), hook_s>::getOnRegister(p); \