2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5 * Copyright (C) 2007 Craig Edwards <craigedwards@brainbox.cc>
6 * Copyright (C) 2012 Adam <Adam@anope.org>
8 * This file is part of InspIRCd. InspIRCd is free software: you can
9 * redistribute it and/or modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation, version 2.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /* Pending some sort of C++11 support */
27 template<typename ReturnType, typename... Args> class CoreExport Handler : public classbase
30 virtual ~Handler() { }
31 virtual ReturnType Call(Args...) = 0;
34 template<typename ReturnType, typename... Args> class CoreExport Caller
37 Handler<ReturnType, Args...>* target;
39 Caller(Handler<ReturnType, Args...>* initial) : target(initial) { }
42 virtual ReturnType operator()(const Args&... params)
44 return this->target->Call(params...);
48 /* Below here is compat with the old API */
49 #define HandlerBase0 Handler
50 #define HandlerBase1 Handler
51 #define HandlerBase2 Handler
52 #define HandlerBase3 Handler
53 #define HandlerBase4 Handler
54 #define HandlerBase5 Handler
55 #define HandlerBase6 Handler
56 #define HandlerBase7 Handler
57 #define HandlerBase8 Handler
59 #define caller1 Caller
60 #define caller2 Caller
61 #define caller3 Caller
62 #define caller4 Caller
63 #define caller5 Caller
64 #define caller6 Caller
65 #define caller7 Caller
66 #define caller8 Caller
68 #define DEFINE_HANDLER0(NAME, RETURN) \
69 class CoreExport NAME : public Handler<RETURN> { public: NAME() { } virtual RETURN Call(); }
71 #define DEFINE_HANDLER1(NAME, RETURN, V1) \
72 class CoreExport NAME : public Handler<RETURN, V1> { public: NAME() { } virtual RETURN Call(V1); }
74 #define DEFINE_HANDLER2(NAME, RETURN, V1, V2) \
75 class CoreExport NAME : public Handler<RETURN, V1, V2> { public: NAME() { } virtual RETURN Call(V1, V2); }
77 #define DEFINE_HANDLER3(NAME, RETURN, V1, V2, V3) \
78 class CoreExport NAME : public Handler<RETURN, V1, V2, V3> { public: NAME() { } virtual RETURN Call(V1, V2, V3); }
80 #define DEFINE_HANDLER4(NAME, RETURN, V1, V2, V3, V4) \
81 class CoreExport NAME : public Handler<RETURN, V1, V2, V3, V4> { public: NAME() { } virtual RETURN Call(V1, V2, V3, V4); }
83 #define DEFINE_HANDLER5(NAME, RETURN, V1, V2, V3, V4, V5) \
84 class CoreExport NAME : public Handler<RETURN, V1, V2, V3, V4, V5> { public: NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5); }
86 #define DEFINE_HANDLER6(NAME, RETURN, V1, V2, V3, V4, V5, V6) \
87 class CoreExport NAME : public Handler<RETURN, V1, V2, V3, V4, V5, V6> { public: NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5, V6); }
89 #define DEFINE_HANDLER7(NAME, RETURN, V1, V2, V3, V4, V5, V6, V7) \
90 class CoreExport NAME : public Handler<RETURN, V1, V2, V3, V4, V5, V6, V7> { public: NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5, V6, V7); }
92 #define DEFINE_HANDLER8(NAME, RETURN, V1, V2, V3, V4, V5, V6, V7, V8) \
93 class CoreExport NAME : public Handler<RETURN, V1, V2, V3, V4, V5, V6, V7, V8> { public: NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5, V6, V7, V8); }
97 /** The templates below can be auto generated by tools/create_templates.pl.
98 * They are used to represent a functor with a given number of parameters and
99 * a specific return type. To prevent passing the wrong number of parameters
100 * and have the compiler detect this error at build-time, each class is numbered
101 * according to the number of parameters it takes, e.g. caller0, caller1, caller2.
102 * These have been generated from zero parameters to eight.
104 * If you want to declare a functor which takes two parameters, a User and a Channel,
105 * and returns bool, simply create it like this:
107 * caller2<bool, User*, Channel*> MyFunction;
109 * and initialize it correctly, when placed into a class you will be able to call it:
111 * bool n = someclass->MyFunction(someuser, somechan);
113 * These functor templates work this way so that you can simply and easily allow
114 * for these class methods to be overridden from within a module, e.g. have a module
115 * which completely replaces the code for IsNick, etc. For example, with the example
118 * MyNewFunction replaceme(ServerInstance);
120 * someclass->MyFunction = \&replaceme;
122 * After this point, calls to someclass->MyFunction will call the new code in your
123 * replacement functor.
125 * This is a very powerful feature which should be considered 'advanced' and not for
126 * beginners. If you do not understand these templates, STAY AWAY from playing with
127 * this until you do, as if you get this wrong, this can generate some pretty long
128 * winded and confusing error messages at compile time.
130 template <typename ReturnType> class CoreExport HandlerBase0 : public classbase
133 virtual ReturnType Call() = 0;
134 virtual ~HandlerBase0() { }
137 template <typename ReturnType, typename Param1> class CoreExport HandlerBase1 : public classbase
140 virtual ReturnType Call(Param1) = 0;
141 virtual ~HandlerBase1() { }
144 template <typename ReturnType, typename Param1, typename Param2> class CoreExport HandlerBase2 : public classbase
147 virtual ReturnType Call(Param1, Param2) = 0;
148 virtual ~HandlerBase2() { }
151 template <typename ReturnType, typename Param1, typename Param2, typename Param3> class CoreExport HandlerBase3 : public classbase
154 virtual ReturnType Call(Param1, Param2, Param3) = 0;
155 virtual ~HandlerBase3() { }
158 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4> class CoreExport HandlerBase4 : public classbase
161 virtual ReturnType Call(Param1, Param2, Param3, Param4) = 0;
162 virtual ~HandlerBase4() { }
165 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5> class CoreExport HandlerBase5 : public classbase
168 virtual ReturnType Call(Param1, Param2, Param3, Param4, Param5) = 0;
169 virtual ~HandlerBase5() { }
172 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6> class CoreExport HandlerBase6 : public classbase
175 virtual ReturnType Call(Param1, Param2, Param3, Param4, Param5, Param6) = 0;
176 virtual ~HandlerBase6() { }
179 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6, typename Param7> class CoreExport HandlerBase7 : public classbase
182 virtual ReturnType Call(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = 0;
183 virtual ~HandlerBase7() { }
186 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6, typename Param7, typename Param8> class CoreExport HandlerBase8 : public classbase
189 virtual ReturnType Call(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = 0;
190 virtual ~HandlerBase8() { }
193 template <typename HandlerType> class CoreExport caller
198 caller(HandlerType* initial)
202 virtual ~caller() { }
205 template <typename ReturnType> class CoreExport caller0 : public caller< HandlerBase0<ReturnType> >
208 caller0(HandlerBase0<ReturnType>* initial)
209 : caller< HandlerBase0<ReturnType> >::caller(initial)
212 virtual ReturnType operator() ()
214 return this->target->Call();
218 template <typename ReturnType, typename Param1> class CoreExport caller1 : public caller< HandlerBase1<ReturnType, Param1> >
221 caller1(HandlerBase1<ReturnType, Param1>* initial)
222 : caller< HandlerBase1<ReturnType, Param1> >(initial)
225 virtual ReturnType operator() (Param1 param1)
227 return this->target->Call(param1);
231 template <typename ReturnType, typename Param1, typename Param2> class CoreExport caller2 : public caller< HandlerBase2<ReturnType, Param1, Param2> >
234 caller2(HandlerBase2<ReturnType, Param1, Param2>* initial)
235 : caller< HandlerBase2<ReturnType, Param1, Param2> >(initial)
238 virtual ReturnType operator() (Param1 param1, Param2 param2)
240 return this->target->Call(param1, param2);
244 template <typename ReturnType, typename Param1, typename Param2, typename Param3> class CoreExport caller3 : public caller< HandlerBase3<ReturnType, Param1, Param2, Param3> >
247 caller3(HandlerBase3<ReturnType, Param1, Param2, Param3>* initial)
248 : caller< HandlerBase3<ReturnType, Param1, Param2, Param3> >(initial)
251 virtual ReturnType operator() (Param1 param1, Param2 param2, Param3 param3)
253 return this->target->Call(param1, param2, param3);
257 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4> class CoreExport caller4 : public caller< HandlerBase4<ReturnType, Param1, Param2, Param3, Param4> >
260 caller4(HandlerBase4<ReturnType, Param1, Param2, Param3, Param4>* initial)
261 : caller< HandlerBase4<ReturnType, Param1, Param2, Param3, Param4> >(initial)
264 virtual ReturnType operator() (Param1 param1, Param2 param2, Param3 param3, Param4 param4)
266 return this->target->Call(param1, param2, param3, param4);
270 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5> class CoreExport caller5 : public caller< HandlerBase5<ReturnType, Param1, Param2, Param3, Param4, Param5> >
273 caller5(HandlerBase5<ReturnType, Param1, Param2, Param3, Param4, Param5>* initial)
274 : caller< HandlerBase5<ReturnType, Param1, Param2, Param3, Param4, Param5> >(initial)
277 virtual ReturnType operator() (Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5)
279 return this->target->Call(param1, param2, param3, param4, param5);
283 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6> class CoreExport caller6 : public caller< HandlerBase6<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6> >
286 caller6(HandlerBase6<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6>* initial)
287 : caller< HandlerBase6<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6> >(initial)
290 virtual ReturnType operator() (Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5, Param6 param6)
292 return this->target->Call(param1, param2, param3, param4, param5, param6);
296 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6, typename Param7> class CoreExport caller7 : public caller< HandlerBase7<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6, Param7> >
299 caller7(HandlerBase7<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6, Param7>* initial)
300 : caller< HandlerBase7<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6, Param7> >(initial)
303 virtual ReturnType operator() (Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5, Param6 param6, Param7 param7)
305 return this->target->Call(param1, param2, param3, param4, param5, param6, param7);
309 template <typename ReturnType, typename Param1, typename Param2, typename Param3, typename Param4, typename Param5, typename Param6, typename Param7, typename Param8> class CoreExport caller8 : public caller< HandlerBase8<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8> >
312 caller8(HandlerBase8<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8>* initial)
313 : caller< HandlerBase8<ReturnType, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8> >(initial)
316 virtual ReturnType operator() (Param1 param1, Param2 param2, Param3 param3, Param4 param4, Param5 param5, Param6 param6, Param7 param7, Param8 param8)
318 return this->target->Call(param1, param2, param3, param4, param5, param6, param7, param8);
322 /** These shorthand macros are used to define a functor class which only implements Call(). Most functors are like this.
323 * If you want something more complex, define them by hand.
325 * The first parameter to each macro is the class name to define, the second parameter is the return value of Call().
326 * The following parameters are the parameter types for Call(), and again, the macro is numbered to match the number of
327 * parameters, to prevent mistakes.
329 #define DEFINE_HANDLER0(NAME, RETURN) \
330 class CoreExport NAME : public HandlerBase0<RETURN> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(); }
332 #define DEFINE_HANDLER1(NAME, RETURN, V1) \
333 class CoreExport NAME : public HandlerBase1<RETURN, V1> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1); }
335 #define DEFINE_HANDLER2(NAME, RETURN, V1, V2) \
336 class CoreExport NAME : public HandlerBase2<RETURN, V1, V2> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2); }
338 #define DEFINE_HANDLER3(NAME, RETURN, V1, V2, V3) \
339 class CoreExport NAME : public HandlerBase3<RETURN, V1, V2, V3> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2, V3); }
341 #define DEFINE_HANDLER4(NAME, RETURN, V1, V2, V3, V4) \
342 class CoreExport NAME : public HandlerBase4<RETURN, V1, V2, V3, V4> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2, V3, V4); }
344 #define DEFINE_HANDLER5(NAME, RETURN, V1, V2, V3, V4, V5) \
345 class CoreExport NAME : public HandlerBase5<RETURN, V1, V2, V3, V4, V5> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5); }
347 #define DEFINE_HANDLER6(NAME, RETURN, V1, V2, V3, V4, V5, V6) \
348 class CoreExport NAME : public HandlerBase6<RETURN, V1, V2, V3, V4, V5, V6> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5, V6); }
350 #define DEFINE_HANDLER7(NAME, RETURN, V1, V2, V3, V4, V5, V6, V7) \
351 class CoreExport NAME : public HandlerBase7<RETURN, V1, V2, V3, V4, V5, V6, V7> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5, V6, V7); }
353 #define DEFINE_HANDLER8(NAME, RETURN, V1, V2, V3, V4, V5, V6, V7, V8) \
354 class CoreExport NAME : public HandlerBase8<RETURN, V1, V2, V3, V4, V5, V6, V7, V8> { public: NAME() { } virtual ~NAME() { } virtual RETURN Call(V1, V2, V3, V4, V5, V6, V7, V8); }