1 | /* |
1 | /* |
2 | callback.h -- C++ callback mechanism |
2 | * callback.h -- C++ callback mechanism |
3 | |
3 | * Copyright (C) 2003-2018 Marc Lehmann <pcg@goof.com> |
|
|
4 | * |
|
|
5 | * This file is part of GVPE. |
|
|
6 | * |
4 | This program is free software; you can redistribute it and/or modify |
7 | * This program is free software; you can redistribute it and/or modify it |
5 | it under the terms of the GNU General Public License as published by |
8 | * under the terms of the GNU General Public License as published by the |
6 | the Free Software Foundation; either version 2 of the License, or |
9 | * Free Software Foundation; either version 3 of the License, or (at your |
7 | (at your option) any later version. |
10 | * option) any later version. |
8 | |
11 | * |
9 | This program is distributed in the hope that it will be useful, |
12 | * This program is distributed in the hope that it will be useful, but |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
12 | GNU General Public License for more details. |
15 | * Public License for more details. |
13 | |
16 | * |
14 | You should have received a copy of the GNU General Public License |
17 | * You should have received a copy of the GNU General Public License along |
15 | along with this program; if not, write to the Free Software |
18 | * with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * |
|
|
20 | * Additional permission under GNU GPL version 3 section 7 |
|
|
21 | * |
|
|
22 | * If you modify this Program, or any covered work, by linking or |
|
|
23 | * combining it with the OpenSSL project's OpenSSL library (or a modified |
|
|
24 | * version of that library), containing parts covered by the terms of the |
|
|
25 | * OpenSSL or SSLeay licenses, the licensors of this Program grant you |
|
|
26 | * additional permission to convey the resulting work. Corresponding |
|
|
27 | * Source for a non-source form of such a combination shall include the |
|
|
28 | * source code for the parts of OpenSSL used as well as that of the |
|
|
29 | * covered work. |
17 | */ |
30 | */ |
18 | |
31 | |
19 | #ifndef VPE_CALLBACK_H__ |
32 | #ifndef CALLBACK_H__ |
20 | #define VPE_CALLBACK_H__ |
33 | #define CALLBACK_H__ |
21 | |
34 | |
22 | template<class R, class A> |
35 | #define CALLBACK_H_VERSION 4 |
23 | class callback { |
|
|
24 | struct object { }; |
|
|
25 | |
36 | |
26 | void *obj; |
37 | template<typename signature> |
27 | R (object::*meth)(A arg); |
38 | struct callback; |
28 | |
39 | |
29 | // a proxy is a kind of recipe on how to call a specific class method |
|
|
30 | struct proxy_base { |
|
|
31 | virtual R call (void *obj, R (object::*meth)(A), A arg) = 0; |
|
|
32 | }; |
|
|
33 | template<class O1, class O2> |
40 | template<class R, class ...Args> |
34 | struct proxy : proxy_base { |
41 | struct callback<R (Args...)> |
35 | virtual R call (void *obj, R (object::*meth)(A), A arg) |
42 | { |
36 | { |
43 | typedef R (*ptr_type)(void *self, Args...); |
37 | ((reinterpret_cast<O1 *>(obj)) ->* (reinterpret_cast<R (O2::*)(A)>(meth))) |
|
|
38 | (arg); |
|
|
39 | } |
|
|
40 | }; |
|
|
41 | |
44 | |
42 | proxy_base *prxy; |
45 | template<class K, R (K::*method)(Args...)> |
|
|
46 | void set (K *object) |
|
|
47 | { |
|
|
48 | self = object; |
|
|
49 | func = thunk<K, method>; |
|
|
50 | } |
43 | |
51 | |
44 | public: |
52 | R call (Args... args) const |
45 | template<class O1, class O2> |
|
|
46 | callback (O1 *object, R (O2::*method)(A)) |
|
|
47 | { |
53 | { |
48 | static proxy<O1,O2> p; |
54 | return func (self, args...); |
49 | obj = reinterpret_cast<void *>(object); |
|
|
50 | meth = reinterpret_cast<R (object::*)(A)>(method); |
|
|
51 | prxy = &p; |
|
|
52 | } |
55 | } |
53 | |
56 | |
54 | R call(A arg) const |
57 | R operator ()(Args... args) const |
55 | { |
58 | { |
56 | return prxy->call (obj, meth, arg); |
59 | return call (args...); |
57 | } |
60 | } |
58 | |
61 | |
59 | R operator ()(A arg) const |
62 | private: |
|
|
63 | |
|
|
64 | void *self; |
|
|
65 | ptr_type func; |
|
|
66 | |
|
|
67 | template<class klass, R (klass::*method)(Args...)> |
|
|
68 | static R thunk (void *self, Args... args) |
60 | { |
69 | { |
61 | return call (arg); |
70 | klass *obj = static_cast<klass *>(self); |
|
|
71 | return (obj->*method) (args...); |
62 | } |
72 | } |
63 | }; |
73 | }; |
64 | |
74 | |
65 | #endif |
75 | #endif |
66 | |
|
|