ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/callback.pl
(Generate patch)

Comparing gvpe/src/callback.pl (file contents):
Revision 1.10 by pcg, Sun Dec 2 00:54:52 2007 UTC vs.
Revision 1.11 by pcg, Tue Dec 4 15:01:12 2007 UTC

31#ifndef CALLBACK_H__ 31#ifndef CALLBACK_H__
32#define CALLBACK_H__ 32#define CALLBACK_H__
33 33
34#define CALLBACK_H_VERSION 3 34#define CALLBACK_H_VERSION 3
35 35
36template<class signature> 36template<typename signature>
37struct callback_funtype_trait; 37struct callback;
38 38
39template<int arity, class signature> 39#define callback_set(callback,obj,klass,method) callback.set<klass, &klass::method> (obj)
40struct callback_get_impl;
41 40
42EOF 41EOF
43 42
44for my $a (0..10) { 43for my $a (0..10) {
45 my $CLASS = join "", map ", class A$_", 1..$a; 44 my $CLASS = join "", map ", class A$_", 1..$a;
46 my $TYPE = join ", ", map "A$_", 1..$a; 45 my $TYPE = join ", ", map "A$_", 1..$a;
47 my $ARG = join ", ", map "a$_", 1..$a; 46 my $ARG = join ", ", map "a$_", 1..$a;
48 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a; 47 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a;
49 my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a; 48 my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a;
50 my $TYPEvoid = $TYPE ? $TYPE : "void"; 49 my $TYPEvoid = $TYPE ? $TYPE : "void";
50 my $_ARG = $ARG ? ", $ARG" : "";
51 my $_TYPE = $TYPE ? ", $TYPE" : ""; 51 my $_TYPE = $TYPE ? ", $TYPE" : "";
52 my $_TYPEARG = $TYPEARG ? ", $TYPEARG" : "";
52 my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : ""; 53 my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : "";
53 54
54 print <<EOF; 55 print <<EOF;
55template<class R$CLASS> 56template<class R$CLASS>
56class callback$a 57struct callback<R ($TYPE)>
57{ 58{
58 struct klass; // it is vital that this is never defined 59 typedef R (*ptr_type)(void *self$_TYPE);
59 60
60 typedef R (klass::*ptr_type)($TYPE); 61private:
61 62
62 klass *o; 63 void *self;
63 R (klass::*m)($TYPE); 64 ptr_type func;
65
66protected:
67
68 template<typename method>
69 struct thunktype;
70
71 template<class klass>
72 struct thunktype<R (klass::*)>
73 {
74 typedef klass K;
75 };
76
77 template<class klass, R (klass::*method)($TYPE)>
78 static R thunk (void *self$_TYPEARG)
79 {
80 klass *obj = static_cast<klass *>(self);
81 return (obj->*method) ($ARG);
82 }
64 83
65public: 84public:
66 template<class O1, class O2> 85 template<class K, R (K::*method)($TYPE)>
67 explicit callback$a (O1 *object, R (O2::*method)($TYPE)) 86 void set (K *object)
68 { 87 {
69 o = reinterpret_cast<klass *>(object); 88 self = object;
70 m = reinterpret_cast<R (klass::*)($TYPE)>(method); 89 func = thunk<K, method>;
71 } 90 }
72 91
73 // this works because a standards-compliant C++ compiler
74 // basically can't help it: it doesn't have the knowledge
75 // required to miscompile (klass is not defined anywhere
76 // and nothing is known about the constructor arguments) :)
77 R call($TYPEARG) const 92 R call ($TYPEARG) const
78 { 93 {
79 return (o->*m) ($ARG); 94 return func (self$_ARG);
80 } 95 }
81 96
82 R operator ()($TYPEARG) const 97 R operator ()($TYPEARG) const
83 { 98 {
84 return call ($ARG); 99 return call ($ARG);
85 } 100 }
86}; 101};
87 102
88template<class R$CLASS>
89struct callback_funtype_trait$a
90{
91 static const int arity = $a;
92 typedef R type ($TYPEvoid);
93 typedef R result_type;
94 $TYPEDEFS
95};
96
97template<class R$CLASS>
98struct callback_funtype_trait<R ($TYPE)> : callback_funtype_trait$a<R$_TYPE>
99{
100};
101
102template<class signature>
103struct callback_get_impl<$a, signature>
104{
105 typedef callback_funtype_trait<signature> T;
106 typedef callback$a<typename T::result_type$_TTYPE> type;
107};
108
109EOF 103EOF
110} 104}
111 105
112print <<EOF 106print <<EOF
113 107
114template<class signature>
115struct callback : callback_get_impl<callback_funtype_trait<signature>::arity, signature>::type
116{
117 typedef typename callback_get_impl<callback_funtype_trait<signature>::arity, signature>::type base_type;
118
119 template<class O, class M>
120 explicit callback (O object, M method)
121 : base_type (object, method)
122 {
123 }
124};
125
126#endif 108#endif
127EOF 109EOF
128 110

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines