5 * Copyright (C) 2008-2009 Pawel Dziepak
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #error This file can not be compiled directly.
27 template<typename in
, typename out
>
28 union _type_transform
{
33 template<typename in
, typename out
>
34 out
type_transform(in trans
) {
35 _type_transform
<in
, out
> t
;
40 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
41 typename arg_type3
, typename arg_type4
, typename arg_type5
,
42 typename arg_type6
, typename arg_type7
>
43 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::~delegate() {}
45 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
46 typename arg_type3
, typename arg_type4
, typename arg_type5
,
47 typename arg_type6
, typename arg_type7
>
48 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::delegate() : owner((A
*)0), type(del_uninit
) { }
50 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
51 typename arg_type3
, typename arg_type4
, typename arg_type5
,
52 typename arg_type6
, typename arg_type7
>
53 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::delegate(const delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
,arg_type4
, arg_type5
, arg_type6
, arg_type7
> &x
) {
59 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
60 typename arg_type3
, typename arg_type4
, typename arg_type5
,
61 typename arg_type6
, typename arg_type7
>
62 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
,arg_type4
, arg_type5
, arg_type6
, arg_type7
> &delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator=(const delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
,arg_type4
, arg_type5
, arg_type6
, arg_type7
> &x
) {
70 /* Save method pointer for different number of arguments */
71 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
72 typename arg_type3
, typename arg_type4
, typename arg_type5
,
73 typename arg_type6
, typename arg_type7
>
75 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
, ret_type (T::*_ptr
)()) {
77 del
.type
= del_method
;
78 del
.ptr
.meth_a0
= type_transform
<ret_type (T::*)(),ret_type (A::*)()>(_ptr
);
79 del
.owner
= type_transform
<T
*,A
*>(obj
);
83 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
84 typename arg_type3
, typename arg_type4
, typename arg_type5
,
85 typename arg_type6
, typename arg_type7
>
87 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
, ret_type (T::*_ptr
)(arg_type1
)) {
90 del
.ptr
.meth_a1
= type_transform
<ret_type (T::*)(arg_type1
),ret_type (A::*)(arg_type1
)>(_ptr
);
91 del
.owner
= type_transform
<T
*,A
*>(obj
);
95 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
96 typename arg_type3
, typename arg_type4
, typename arg_type5
,
97 typename arg_type6
, typename arg_type7
>
99 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
,ret_type (T::*_ptr
)(arg_type1
, arg_type2
)) {
101 del
.type
= del_method
;
102 del
.ptr
.meth_a2
= type_transform
<ret_type (T::*)(arg_type1
, arg_type2
),
103 ret_type (A::*)(arg_type1
, arg_type2
)>(_ptr
);
104 del
.owner
= type_transform
<T
*,A
*>(obj
);
108 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
109 typename arg_type3
, typename arg_type4
, typename arg_type5
,
110 typename arg_type6
, typename arg_type7
>
112 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
,ret_type (T::*_ptr
)(arg_type1
, arg_type2
, arg_type3
)) {
114 del
.type
= del_method
;
115 del
.ptr
.meth_a3
= type_transform
<ret_type (T::*)(arg_type1
, arg_type2
, arg_type3
),
116 ret_type (A::*)(arg_type1
, arg_type2
, arg_type3
)>(_ptr
);
117 del
.owner
= type_transform
<T
*,A
*>(obj
);
121 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
122 typename arg_type3
, typename arg_type4
, typename arg_type5
,
123 typename arg_type6
, typename arg_type7
>
125 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
,ret_type (T::*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
)) {
127 del
.type
= del_method
;
128 del
.ptr
.meth_a4
= type_transform
<ret_type (T::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
),
129 ret_type (A::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
)>(_ptr
);
130 del
.owner
= type_transform
<T
*,A
*>(obj
);
134 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
135 typename arg_type3
, typename arg_type4
, typename arg_type5
,
136 typename arg_type6
, typename arg_type7
>
138 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
,ret_type (T::*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
)) {
140 del
.type
= del_method
;
141 del
.ptr
.meth_a5
= type_transform
<ret_type (T::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
),
142 ret_type (A::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
)>(_ptr
);
143 del
.owner
= type_transform
<T
*,A
*>(obj
);
147 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
148 typename arg_type3
, typename arg_type4
, typename arg_type5
,
149 typename arg_type6
, typename arg_type7
>
151 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
,ret_type (T::*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
)) {
153 del
.type
= del_method
;
154 del
.ptr
.meth_a6
= type_transform
<ret_type (T::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
),
155 ret_type (A::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
)>(_ptr
);
156 del
.owner
= type_transform
<T
*,A
*>(obj
);
160 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
161 typename arg_type3
, typename arg_type4
, typename arg_type5
,
162 typename arg_type6
, typename arg_type7
>
164 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::method(T
*obj
,ret_type (T::*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
)) {
166 del
.type
= del_method
;
167 del
.ptr
.meth_a7
= type_transform
<ret_type (T::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
),
168 ret_type (A::*)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
)>(_ptr
);
169 del
.owner
= type_transform
<T
*,A
*>(obj
);
173 /* Save function pointer for different number of arguments */
174 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
175 typename arg_type3
, typename arg_type4
, typename arg_type5
,
176 typename arg_type6
, typename arg_type7
>
177 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)()) {
179 del
.type
= del_function
;
180 del
.ptr
.func_a0
= _ptr
;
184 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
185 typename arg_type3
, typename arg_type4
, typename arg_type5
,
186 typename arg_type6
, typename arg_type7
>
187 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
)) {
189 del
.type
= del_function
;
190 del
.ptr
.func_a1
= _ptr
;
194 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
195 typename arg_type3
, typename arg_type4
, typename arg_type5
,
196 typename arg_type6
, typename arg_type7
>
197 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
, arg_type2
)) {
199 del
.type
= del_function
;
200 del
.ptr
.func_a2
= _ptr
;
204 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
205 typename arg_type3
, typename arg_type4
, typename arg_type5
,
206 typename arg_type6
, typename arg_type7
>
207 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
, arg_type2
, arg_type3
)) {
209 del
.type
= del_function
;
210 del
.ptr
.func_a3
=_ptr
;
214 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
215 typename arg_type3
, typename arg_type4
, typename arg_type5
,
216 typename arg_type6
, typename arg_type7
>
217 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
)) {
219 del
.type
= del_function
;
220 del
.ptr
.func_a4
= _ptr
;
224 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
225 typename arg_type3
, typename arg_type4
, typename arg_type5
,
226 typename arg_type6
, typename arg_type7
>
227 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
)) {
229 del
.type
= del_function
;
230 del
.ptr
.func_a5
= _ptr
;
234 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
235 typename arg_type3
, typename arg_type4
, typename arg_type5
,
236 typename arg_type6
, typename arg_type7
>
237 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
)) {
239 del
.type
= del_function
;
240 del
.ptr
.func_a6
= _ptr
;
244 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
245 typename arg_type3
, typename arg_type4
, typename arg_type5
,
246 typename arg_type6
, typename arg_type7
>
247 delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::function(ret_type (*_ptr
)(arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
)) {
249 del
.type
= del_function
;
250 del
.ptr
.func_a7
= _ptr
;
254 /* Calling function/method with different number of arguments */
255 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
256 typename arg_type3
, typename arg_type4
, typename arg_type5
,
257 typename arg_type6
, typename arg_type7
>
258 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::call(arg_type1 arg1
, arg_type2 arg2
, arg_type3 arg3
, arg_type4 arg4
, arg_type5 arg5
, arg_type6 arg6
, arg_type7 arg7
) const {
259 if (type
== del_method
)
260 return (owner
->*(ptr
.meth_a7
))(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
);
261 else if (type
== del_function
)
262 return ptr
.func_a7(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
);
267 /* Overloaded operators () for different numbers of arguments */
268 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
269 typename arg_type3
, typename arg_type4
, typename arg_type5
,
270 typename arg_type6
, typename arg_type7
>
271 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()() const {
272 return call(0, 0, 0, 0, 0, 0, 0);
275 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
276 typename arg_type3
, typename arg_type4
, typename arg_type5
,
277 typename arg_type6
, typename arg_type7
>
278 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
) const {
279 return call(arg1
, 0, 0, 0, 0, 0, 0);
282 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
283 typename arg_type3
, typename arg_type4
, typename arg_type5
,
284 typename arg_type6
, typename arg_type7
>
285 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
, arg_type2 arg2
) const {
286 return call(arg1
, arg2
, 0, 0, 0, 0, 0);
289 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
290 typename arg_type3
, typename arg_type4
, typename arg_type5
,
291 typename arg_type6
, typename arg_type7
>
292 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
, arg_type2 arg2
, arg_type3 arg3
) const {
293 return call(arg1
, arg2
, arg3
, 0, 0, 0, 0);
296 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
297 typename arg_type3
, typename arg_type4
, typename arg_type5
,
298 typename arg_type6
, typename arg_type7
>
299 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
, arg_type2 arg2
, arg_type3 arg3
, arg_type4 arg4
) const {
300 return call(arg1
, arg2
, arg3
, arg4
, 0, 0, 0);
303 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
304 typename arg_type3
, typename arg_type4
, typename arg_type5
,
305 typename arg_type6
, typename arg_type7
>
306 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
, arg_type2 arg2
, arg_type3 arg3
, arg_type4 arg4
, arg_type5 arg5
) const {
307 return call(arg1
, arg2
, arg3
, arg4
, arg5
, 0, 0);
310 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
311 typename arg_type3
, typename arg_type4
, typename arg_type5
,
312 typename arg_type6
, typename arg_type7
>
313 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
, arg_type2 arg2
, arg_type3 arg3
, arg_type4 arg4
, arg_type5 arg5
, arg_type6 arg6
) const {
314 return call(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, 0);
317 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
318 typename arg_type3
, typename arg_type4
, typename arg_type5
,
319 typename arg_type6
, typename arg_type7
>
320 ret_type delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator()(arg_type1 arg1
, arg_type2 arg2
, arg_type3 arg3
, arg_type4 arg4
, arg_type5 arg5
, arg_type6 arg6
, arg_type7 arg7
) const {
321 return call(arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
);
324 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
325 typename arg_type3
, typename arg_type4
, typename arg_type5
,
326 typename arg_type6
, typename arg_type7
>
327 bool delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::operator==(const delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
> &x
) const {
328 if (x
.owner
== owner
&& ptr
.meth_a0
== x
.ptr
.meth_a0
)
333 template<typename ret_type
, typename arg_type1
, typename arg_type2
,
334 typename arg_type3
, typename arg_type4
, typename arg_type5
,
335 typename arg_type6
, typename arg_type7
>
336 bool delegate
<ret_type
, arg_type1
, arg_type2
, arg_type3
, arg_type4
, arg_type5
, arg_type6
, arg_type7
>::null() const {
337 return type
== del_uninit
;