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.13 by pcg, Wed Dec 5 18:19:50 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;
38
39template<int arity, class signature>
40struct callback_get_impl; 37struct callback;
41 38
42EOF 39EOF
43 40
44for my $a (0..10) { 41for my $a (0..10) {
45 my $CLASS = join "", map ", class A$_", 1..$a; 42 my $CLASS = join "", map ", class A$_", 1..$a;
46 my $TYPE = join ", ", map "A$_", 1..$a; 43 my $TYPE = join ", ", map "A$_", 1..$a;
47 my $ARG = join ", ", map "a$_", 1..$a; 44 my $ARG = join ", ", map "a$_", 1..$a;
48 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a; 45 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a;
49 my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a; 46 my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a;
50 my $TYPEvoid = $TYPE ? $TYPE : "void"; 47 my $TYPEvoid = $TYPE ? $TYPE : "void";
48 my $_ARG = $ARG ? ", $ARG" : "";
51 my $_TYPE = $TYPE ? ", $TYPE" : ""; 49 my $_TYPE = $TYPE ? ", $TYPE" : "";
50 my $_TYPEARG = $TYPEARG ? ", $TYPEARG" : "";
52 my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : ""; 51 my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : "";
53 52
54 print <<EOF; 53 print <<EOF;
55template<class R$CLASS> 54template<class R$CLASS>
56class callback$a 55struct callback<R ($TYPE)>
57{ 56{
58 struct klass; // it is vital that this is never defined 57 typedef R (*ptr_type)(void *self$_TYPE);
59 58
60 typedef R (klass::*ptr_type)($TYPE); 59 template<class K, R (K::*method)($TYPE)>
61 60 void set (K *object)
62 klass *o;
63 R (klass::*m)($TYPE);
64
65public:
66 template<class O1, class O2>
67 explicit callback$a (O1 *object, R (O2::*method)($TYPE))
68 { 61 {
69 o = reinterpret_cast<klass *>(object); 62 self = object;
70 m = reinterpret_cast<R (klass::*)($TYPE)>(method); 63 func = thunk<K, method>;
71 } 64 }
72 65
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 66 R call ($TYPEARG) const
78 { 67 {
79 return (o->*m) ($ARG); 68 return func (self$_ARG);
80 } 69 }
81 70
82 R operator ()($TYPEARG) const 71 R operator ()($TYPEARG) const
83 { 72 {
84 return call ($ARG); 73 return call ($ARG);
85 } 74 }
75
76private:
77
78 void *self;
79 ptr_type func;
80
81 template<class klass, R (klass::*method)($TYPE)>
82 static R thunk (void *self$_TYPEARG)
83 {
84 klass *obj = static_cast<klass *>(self);
85 return (obj->*method) ($ARG);
86 }
86}; 87};
87 88
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 89EOF
110} 90}
111 91
112print <<EOF 92print <<EOF
113 93
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 94#endif
127EOF 95EOF
128 96

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines