source: liblaziness/delegate.h @ 6

Last change on this file since 6 was 4, checked in by artyom, 13 years ago

liblaziness

File size: 14.9 KB
Line 
1#ifndef __FUNCTION_H__
2#define __FUNCTION_H__
3#include "r.h"
4#include <type_traits>
5#include "lambda_trait.h"
6
7template<typename T>
8class DelegateBase
9{
10        public:
11                typedef T ResultType;
12                DelegateBase() { }
13                virtual ~DelegateBase() { }
14                virtual R<T> operator () () = 0;
15};
16
17template<typename T, typename T1>
18class Delegate1Base
19{
20        public:
21                typedef T ResultType;
22                typedef T1 Arg1Type;
23                Delegate1Base() { }
24                virtual ~Delegate1Base() { }
25                virtual R<T> operator () (R<T1> arg) = 0;
26};
27
28template<typename T, typename T1, typename T2>
29class Delegate2Base
30{
31        public:
32                typedef T ResultType;
33                typedef T1 Arg1Type;
34                typedef T2 Arg2Type;
35                Delegate2Base() { }
36                virtual ~Delegate2Base() { }
37                virtual R<T> operator () (R<T1> arg1, R<T2> arg2) = 0;
38};
39
40template<typename T>
41class FunBase : public DelegateBase<T>
42{
43        public:
44                typedef R<T> (*FunType)();
45                FunBase(FunType fun) : DelegateBase<T>(), fun(fun) { }
46                virtual ~FunBase() { }
47                virtual R<T> operator () () override { return fun(); }
48        private:
49                FunType fun;
50};
51
52template<typename T, typename TFun>
53class FunLBase : public DelegateBase<T>
54{
55        public:
56                typedef TFun FunType;
57                FunLBase(FunType fun) : DelegateBase<T>(), fun(fun) { }
58                virtual ~FunLBase() { }
59                virtual R<T> operator () () override { return fun(); }
60        private:
61                FunType fun;
62};
63
64template<typename T, typename T1>
65class Funx1Base : public DelegateBase<T>
66{
67        public:
68                typedef R<T> (*FunType)(R<T1>);
69                Funx1Base(FunType fun, R<T1> arg1) : DelegateBase<T>(), fun(fun), arg1(arg1) { }
70                virtual ~Funx1Base() { }
71                virtual R<T> operator () () override { return fun(arg1); }
72        protected:
73                FunType fun;
74                R<T1> arg1;
75};
76
77template<typename T, typename T1, typename TFun>
78class Funx1LBase : public DelegateBase<T>
79{
80        public:
81                typedef TFun FunType;
82                Funx1LBase(FunType fun, R<T1> arg1) : DelegateBase<T>(), fun(fun), arg1(arg1) { }
83                virtual ~Funx1LBase() { }
84                virtual R<T> operator () () override { return fun(arg1); }
85        protected:
86                FunType fun;
87                R<T1> arg1;
88};
89
90template<typename T, typename T1, typename T2>
91class Funx2Base : public DelegateBase<T>
92{
93        public:
94                typedef R<T> (*FunType)(R<T1>, R<T2>);
95                Funx2Base(FunType fun, R<T1> arg1, R<T2> arg2) : DelegateBase<T>(), fun(fun), arg1(arg1), arg2(arg2) { }
96                virtual ~Funx2Base() { }
97                virtual R<T> operator () () override { return fun(arg1, arg2); }
98        protected:
99                FunType fun;
100                R<T1> arg1;
101                R<T2> arg2;
102};
103
104template<typename T, typename T1, typename T2, typename TFun>
105class Funx2LBase : public DelegateBase<T>
106{
107        public:
108                Funx2LBase(TFun fun, R<T1> arg1, R<T2> arg2) : DelegateBase<T>(), fun(fun), arg1(arg1), arg2(arg2) { }
109                virtual ~Funx2LBase() { }
110                virtual R<T> operator () () override { return fun(arg1, arg2); }
111        protected:
112                TFun fun;
113                R<T1> arg1;
114                R<T2> arg2;
115};
116
117template<typename T, typename T1, typename T2, typename T3>
118class Funx3Base : public DelegateBase<T>
119{
120        public:
121                typedef R<T> (*FunType)(R<T1>, R<T2>, R<T3>);
122                Funx3Base(FunType fun, R<T1> arg1, R<T2> arg2, R<T3> arg3) : DelegateBase<T>(), fun(fun), arg1(arg1), arg2(arg2), arg3(arg3) { }
123                virtual ~Funx3Base() { }
124                virtual R<T> operator () () override { return fun(arg1, arg2, arg3); }
125        protected:
126                FunType fun;
127                R<T1> arg1;
128                R<T2> arg2;
129                R<T3> arg3;
130};
131
132template<typename T, typename T1, typename T2, typename T3, typename TFun>
133class Funx3LBase : public DelegateBase<T>
134{
135        public:
136                typedef TFun FunType;
137                Funx3LBase(FunType fun, R<T1> arg1, R<T2> arg2, R<T3> arg3) : DelegateBase<T>(), fun(fun), arg1(arg1), arg2(arg2), arg3(arg3) { }
138                virtual ~Funx3LBase() { }
139                virtual R<T> operator () () override { return fun(arg1, arg2, arg3); }
140        protected:
141                FunType fun;
142                R<T1> arg1;
143                R<T2> arg2;
144                R<T3> arg3;
145};
146
147/**** 1 arg ****/
148
149template<typename T, typename T1>
150class Fun1Base : public Delegate1Base<T, T1>
151{
152        public:
153                typedef R<T> (*FunType)(R<T1>);
154                Fun1Base(FunType fun) : Delegate1Base<T, T1>(), fun(fun) { }
155                virtual ~Fun1Base() { }
156                virtual R<T> operator() (R<T1> arg) override { return fun(arg); }
157        protected:
158                FunType fun;
159};
160
161template<typename T, typename T1, typename TFun>
162class Fun1LBase : public Delegate1Base<T, T1>
163{
164        public:
165                typedef TFun FunType;
166                Fun1LBase(FunType fun) : Delegate1Base<T, T1>(), fun(fun) { }
167                virtual ~Fun1LBase() { }
168                virtual R<T> operator() (R<T1> arg) override { return fun(arg); }
169        protected:
170                FunType fun;
171};
172
173template<typename T, typename T1, typename TArg1>
174class Fun1x1Base : public Delegate1Base<T, T1>
175{
176        public:
177                typedef R<T> (*FunType)(R<TArg1>, R<T1>);
178                Fun1x1Base(FunType fun, R<TArg1> arg1) : Delegate1Base<T, T1>(), fun(fun), arg1(arg1) { }
179                virtual ~Fun1x1Base() { }
180                virtual R<T> operator () (R<T1> arg) override { return fun(arg1, arg); }
181        protected:
182                FunType fun;
183                R<TArg1> arg1;
184};
185
186template<typename T, typename T1, typename TArg1, typename TFun>
187class Fun1x1LBase : public Delegate1Base<T, T1>
188{
189        public:
190                typedef TFun FunType;
191                Fun1x1LBase(FunType fun, R<TArg1> arg1) : Delegate1Base<T, T1>(), fun(fun), arg1(arg1) { }
192                virtual ~Fun1x1LBase() { }
193                virtual R<T> operator () (R<T1> arg) override { return fun(arg1, arg); }
194        protected:
195                FunType fun;
196                R<TArg1> arg1;
197};
198
199/**** 2 args ****/
200
201template<typename T, typename T1, typename T2>
202class Fun2Base : public Delegate2Base<T, T1, T2>
203{
204        public:
205                typedef R<T> (*FunType)(R<T1>, R<T2>);
206                Fun2Base(FunType fun) : Delegate2Base<T, T1, T2>(), fun(fun) { }
207                virtual ~Fun2Base() { }
208                virtual R<T> operator() (R<T1> arg1, R<T2> arg2) override { return fun(arg1, arg2); }
209        protected:
210                FunType fun;
211};
212
213template<typename T, typename T1, typename T2, typename TFun>
214class Fun2LBase : public Delegate2Base<T, T1, T2>
215{
216        public:
217                typedef TFun FunType;
218                Fun2LBase(FunType fun) : Delegate2Base<T, T1, T2>(), fun(fun) { }
219                virtual ~Fun2LBase() { }
220                virtual R<T> operator() (R<T1> arg1, R<T2> arg2) override { return fun(arg1, arg2); }
221        protected:
222                FunType fun;
223};
224
225/**** refrence specializations to add more functionality ****/
226template <typename T>
227class R<DelegateBase<T>, true> : public R<DelegateBase<T>, false>
228{
229        protected:
230                // passing protected constructors
231                inline R(int i) : R< DelegateBase<T>, false >(i) { }
232        public:
233                // passing public constructors
234                inline R() : R< DelegateBase<T>, false>() { }
235                template<typename U, bool od> inline R(R<U, od>& o) : R< DelegateBase<T>, false>(o, 0)
236                {
237                        _assert_subclass<U, DelegateBase<typename U::ResultType>> ERRORBase; // U must be subclass of DelegateBase
238                        _assert_subclass<typename U::ResultType, T> ERRORItem; // result must be subclass of T
239                }
240                template<typename U, bool od> inline R(R<U, od>&& o) : R< DelegateBase<T>, false>(o, 0)
241                {
242                        _assert_subclass<U, DelegateBase<typename U::ResultType>> ERRORBase; // U must be subclass of DelegateBase
243                        _assert_subclass<typename U::ResultType, T> ERRORItem; // result must be subclass of T
244                }
245                // passing operator=
246                template<typename U, bool od> inline R< DelegateBase<T>, true >& operator=(R< DelegateBase<U>, od >&& o) { R< DelegateBase<T>, false >::operator=(o); return *this; }
247                template<typename U, bool od> inline R< DelegateBase<T>, true >& operator=(R< DelegateBase<U>, od >& o) { R< DelegateBase<T>, false >::operator=(o); return *this; }
248                // additional functionality
249                inline R<T> operator() () { return this->deref()(); }
250                // keep reference makeable with Ref::mk
251                friend class Ref;
252};
253
254template <typename T, typename T1>
255class R<Delegate1Base<T, T1>, true> : public R<Delegate1Base<T, T1>, false>
256{
257        protected:
258                // passing protected constructors
259                inline R(int i) : R< Delegate1Base<T, T1>, false >(i) { }
260        public:
261                // passing public constructors
262                inline R() : R< Delegate1Base<T, T1>, false>() { }
263                template<typename U, bool od> inline R(R<U, od>& o) : R< Delegate1Base<T, T1>, false>(o, 0)
264                {
265                        _assert_subclass<U, Delegate1Base<typename U::ResultType, typename U::Arg1Type>> ERRORBase; // U must be subclass of DelegateBase
266                        _assert_subclass<typename U::ResultType, T> ERRORItem; // result must be subclass of T
267                        _assert_subclass<typename U::Arg1Type, T1> ERRORArg1; // result must be subclass of T
268                }
269                template<typename U, bool od> inline R(R<U, od>&& o) : R< Delegate1Base<T, T1>, false>(o, 0)
270                {
271                        _assert_subclass<U, Delegate1Base<typename U::ResultType, typename U::Arg1Type>> ERRORBase; // U must be subclass of DelegateBase
272                        _assert_subclass<typename U::ResultType, T> ERRORItem; // result must be subclass of T
273                        _assert_subclass<typename U::Arg1Type, T1> ERRORArg1; // result must be subclass of T
274                }
275                // passing operator=
276                template<typename U, typename U1, bool od> inline R< Delegate1Base<T, T1>, true >& operator=(R< Delegate1Base<U, U1>, od >&& o) { R< DelegateBase<T>, false >::operator=(o); return *this; }
277                template<typename U, typename U1, bool od> inline R< Delegate1Base<T, T1>, true >& operator=(R< Delegate1Base<U, U1>, od >& o) { R< DelegateBase<T>, false >::operator=(o); return *this; }
278                // additional functionality
279                inline R<T> operator() (R<T1> arg1) { return this->deref()(arg1); }
280                // keep reference makeable with Ref::mk
281                friend class Ref;
282};
283
284template <typename T, typename T1, typename T2>
285class R<Delegate2Base<T, T1, T2>, true> : public R<Delegate2Base<T, T1, T2>, false>
286{
287        protected:
288                // passing protected constructors
289                inline R(int i) : R< Delegate2Base<T, T1, T2>, false >(i) { }
290        public:
291                // passing public constructors
292                inline R() : R< Delegate2Base<T, T1, T2>, false>() { }
293                template<typename U, bool od> inline R(R<U, od>& o) : R< Delegate2Base<T, T1, T2>, false>(o, 0)
294                {
295                        _assert_subclass<U, Delegate2Base<typename U::ResultType, typename U::Arg1Type, typename U::Arg2Type>> ERRORBase; // U must be subclass of DelegateBase
296                        _assert_subclass<typename U::ResultType, T> ERRORItem; // result must be subclass of T
297                        _assert_subclass<T1, typename U::Arg1Type> ERRORArg1; // arg must be superclass of T
298                        _assert_subclass<T2, typename U::Arg2Type> ERRORArg2; // arg must be superclass of T
299                }
300                template<typename U, bool od> inline R(R<U, od>&& o) : R< Delegate2Base<T, T1, T2>, false>(o, 0)
301                {
302                        _assert_subclass<U, Delegate2Base<typename U::ResultType, typename U::Arg1Type, typename U::Arg2Type>> ERRORBase; // U must be subclass of DelegateBase
303                        _assert_subclass<typename U::ResultType, T> ERRORItem; // result must be subclass of T
304                        _assert_subclass<T1, typename U::Arg1Type> ERRORArg1; // arg must be superclass of T
305                        _assert_subclass<T2, typename U::Arg2Type> ERRORArg2; // arg must be superclass of T
306                }
307                // passing operator=
308                template<typename U, typename U1, typename U2, bool od> inline R< Delegate2Base<T, T1, T2>, true >& operator=(R< Delegate2Base<U, U1, U2>, od >&& o) { R< DelegateBase<T>, false >::operator=(o); return *this; }
309                template<typename U, typename U1, typename U2, bool od> inline R< Delegate2Base<T, T1, T2>, true >& operator=(R< Delegate2Base<U, U1, U2>, od >& o) { R< DelegateBase<T>, false >::operator=(o); return *this; }
310                // additional functionality
311                inline R<T> operator() (R<T1> arg1, R<T2> arg2) { return this->deref()(arg1, arg2); }
312                // keep reference makeable with Ref::mk
313                friend class Ref;
314};
315
316/**** type aliases ****/
317
318template<typename T>
319using Delegate = R< DelegateBase<T> >;
320
321template<typename T, typename T1>
322using Delegate1 = R< Delegate1Base<T, T1> >;
323
324template<typename T, typename T1, typename T2>
325using Delegate2 = R< Delegate2Base<T, T1, T2> >;
326
327template<typename T>
328using Fun = R< FunBase<T> >;
329
330template<typename T, typename T1>
331using Funx1 = R< Funx1Base<T, T1> >;
332
333template<typename T, typename T1, typename T2>
334using Funx2 = R< Funx2Base<T, T1, T2> >;
335
336template<typename T, typename T1, typename T2, typename TFun>
337using Funx2L = R< Funx2LBase<T, T1, T2, TFun> >;
338
339template<typename T, typename T1, typename T2, typename T3>
340using Funx3 = R< Funx3Base<T, T1, T2, T3> >;
341
342
343template<typename T>
344Delegate<T> mkFun(R<T> (*fun)())
345{
346        return Ref::mk< FunBase<T>, typename FunBase<T>::FunType >(fun);
347}
348
349template<typename TFun>
350auto mkLFun(TFun fun) -> Delegate<typename decltype(fun())::etype>
351{
352        return Ref::mk<FunLBase<typename decltype(fun())::etype, TFun>> (fun);
353}
354
355template<typename T, typename T1>
356Delegate<T> mkFun(R<T> (*fun)(R<T1>), R<T1> arg1)
357{
358        return Ref::mk< Funx1Base<T, T1>, typename Funx1Base<T, T1>::FunType, R<T1> >(fun, arg1);
359}
360
361template<typename T1, typename TFun>
362auto mkLFun(TFun fun, R<T1> arg1) -> Delegate<typename decltype(fun(arg1))::etype>
363{
364        return Ref::mk<Funx1LBase<typename decltype(fun(arg1))::etype, T1, TFun>, TFun, R<T1>> (fun, arg1);
365}
366
367template<typename T, typename T1, typename T2>
368Delegate<T> mkFun(R<T> (*fun)(R<T1>, R<T2>), R<T1> arg1, R<T2> arg2)
369{
370        return Ref::mk< Funx2Base<T, T1, T2>, typename Funx2Base<T, T1, T2>::FunType, R<T1>, R<T2> >(fun, arg1, arg2);
371}
372
373template<typename T1, typename T2, typename TFun>
374auto mkLFun(TFun fun, R<T1> arg1, R<T2> arg2) -> Delegate<typename decltype(fun(arg1, arg2))::etype>
375{
376        return Ref::mk< Funx2LBase< typename decltype(fun(arg1, arg2))::etype, T1, T2, TFun>, TFun, R<T1>, R<T2> >(fun, arg1, arg2);
377}
378
379template<typename T, typename T1, typename T2, typename T3>
380Delegate<T> mkFun(R<T> (*fun)(R<T1>, R<T2>, R<T3>), R<T1> arg1, R<T2> arg2, R<T3> arg3)
381{
382        return Ref::mk< Funx3Base<T, T1, T2, T3>, typename Funx3Base<T, T1, T2, T3>::FunType, R<T1>, R<T2>, R<T3> >(fun, arg1, arg2, arg3);
383}
384
385template<typename T1, typename T2, typename T3, typename TFun>
386auto mkLFun(TFun fun, R<T1> arg1, R<T2> arg2, R<T3> arg3) -> Delegate<typename decltype(fun(arg1, arg2, arg3))::etype>
387{
388        return Ref::mk<Funx3LBase< typename decltype(fun(arg1, arg2, arg3))::etype, T1, T2, T3, TFun>, TFun, R<T1>, R<T2>, R<T3>>(fun, arg1, arg2, arg3);
389}
390
391/**** 1 arg ****/
392
393template<typename T, typename T1>
394Delegate1<T, T1> mkFun1(R<T> (*fun)(R<T1>))
395{
396        return Ref::mk< Fun1Base<T, T1>, typename Fun1Base<T, T1>::FunType >(fun);
397}
398
399template<typename TFun>
400auto mkLFun1(TFun fun) -> Delegate1<typename lambdatype<TFun>::return_type::etype, typename lambdatype<TFun>::arg1_type::etype>
401{
402        return Ref::mk<Fun1LBase<typename lambdatype<TFun>::return_type::etype, typename lambdatype<TFun>::arg1_type::etype, TFun>, TFun>(fun);
403}
404
405template<typename T, typename T1, typename TArg1>
406Delegate1<T, T1> mkFun1(R<T> (*fun)(R<TArg1>, R<T1>), R<T1> arg)
407{
408        return Ref::mk< Fun1x1Base<T, T1, TArg1>, typename Fun1x1Base<T, T1, TArg1>::FunType, R<T1> >(fun, arg);
409}
410
411template<typename TFun, typename TArg1>
412auto mkLFun1(TFun fun, R<TArg1> arg1) -> Delegate1<typename lambdatype<TFun>::return_type::etype, typename lambdatype<TFun>::arg2_type::etype>
413{
414        return Ref::mk<Fun1x1LBase<typename lambdatype<TFun>::return_type::etype, typename lambdatype<TFun>::arg2_type::etype, TArg1, TFun>, TFun, R<TArg1>>(fun, arg1);
415}
416
417/**** 2 args ****/
418
419template<typename T, typename T1, typename T2>
420Delegate2<T, T1, T2> mkFun2(R<T> (*fun)(R<T1>, R<T2>))
421{
422        return Ref::mk< Fun2Base<T, T1, T2>, typename Fun2Base<T, T1, T2>::FunType >(fun);
423}
424
425template<typename TFun>
426auto mkLFun2(TFun fun) -> Delegate2<typename lambdatype<TFun>::return_type::etype, typename lambdatype<TFun>::arg1_type::etype, typename lambdatype<TFun>::arg2_type::etype>
427{
428        return Ref::mk<Fun2LBase<typename lambdatype<TFun>::return_type::etype, typename lambdatype<TFun>::arg1_type::etype, typename lambdatype<TFun>::arg2_type::etype, TFun>, TFun>(fun);
429}
430
431#endif
Note: See TracBrowser for help on using the repository browser.