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.5 by pcg, Tue Apr 26 00:55:55 2005 UTC vs.
Revision 1.10 by pcg, Sun Dec 2 00:54:52 2007 UTC

1#!/usr/bin/perl 1#!/usr/bin/perl
2 2
3use strict;
4
3print <<EOF; 5print <<EOF;
4// THIS IS A GENERATED FILE, RUN callback.pl to regenerate it 6// THIS IS A GENERATED FILE: RUN callback.pl to regenerate it
5// THIS IS A GENERATED FILE, RUN callback.pl to regenerate it 7// THIS IS A GENERATED FILE: callback.pl is part of the GVPE
6// THIS IS A GENERATED FILE, RUN callback.pl to regenerate it 8// THIS IS A GENERATED FILE: distribution.
7// THIS IS A GENERATED FILE, RUN callback.pl to regenerate it
8// THIS IS A GENERATED FILE, RUN callback.pl to regenerate it
9// THIS IS A GENERATED FILE, RUN callback.pl to regenerate it
10 9
11/* 10/*
12 callback.h -- C++ callback mechanism 11 callback.h -- C++ callback mechanism
13 Copyright (C) 2003 Marc Lehmann <pcg\@goof.com> 12 Copyright (C) 2003-2007 Marc Lehmann <pcg\@goof.com>
14 13
15 This file is part of GVPE. 14 This file is part of GVPE.
16 15
17 GVPE is free software; you can redistribute it and/or modify 16 GVPE is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by 17 it under the terms of the GNU General Public License as published by
30*/ 29*/
31 30
32#ifndef CALLBACK_H__ 31#ifndef CALLBACK_H__
33#define CALLBACK_H__ 32#define CALLBACK_H__
34 33
34#define CALLBACK_H_VERSION 3
35
36template<class signature>
37struct callback_funtype_trait;
38
39template<int arity, class signature>
40struct callback_get_impl;
41
35EOF 42EOF
36 43
37for my $a (0..7) { 44for my $a (0..10) {
38 my $CLASS = join "", map ", class A$_", 1..$a; 45 my $CLASS = join "", map ", class A$_", 1..$a;
39 my $TYPE = join ", ", map "A$_", 1..$a; 46 my $TYPE = join ", ", map "A$_", 1..$a;
40 my $ARG = join ", ", map "a$_", 1..$a; 47 my $ARG = join ", ", map "a$_", 1..$a;
41 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a; 48 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a;
42 my $_ARG = $ARG ? ", $ARG" : ""; 49 my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a;
50 my $TYPEvoid = $TYPE ? $TYPE : "void";
43 my $_TYPEARG = $TYPEARG ? ", $TYPEARG" : ""; 51 my $_TYPE = $TYPE ? ", $TYPE" : "";
52 my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : "";
44 53
45 print <<EOF; 54 print <<EOF;
46template<class R$CLASS> 55template<class R$CLASS>
47class callback$a { 56class callback$a
48 struct object { }; 57{
58 struct klass; // it is vital that this is never defined
49 59
50 void *obj; 60 typedef R (klass::*ptr_type)($TYPE);
51 R (object::*meth)($TYPE);
52 61
53 /* a proxy is a kind of recipe on how to call a specific class method */ 62 klass *o;
54 struct proxy_base { 63 R (klass::*m)($TYPE);
55 virtual R call (void *obj, R (object::*meth)($TYPE)$_TYPEARG) = 0;
56 };
57 template<class O1, class O2>
58 struct proxy : proxy_base {
59 virtual R call (void *obj, R (object::*meth)($TYPE)$_TYPEARG)
60 {
61 ((reinterpret_cast<O1 *>(obj)) ->* (reinterpret_cast<R (O2::*)($TYPE)>(meth)))
62 ($ARG);
63 }
64 };
65
66 proxy_base *prxy;
67 64
68public: 65public:
69 template<class O1, class O2> 66 template<class O1, class O2>
70 callback$a (O1 *object, R (O2::*method)($TYPE)) 67 explicit callback$a (O1 *object, R (O2::*method)($TYPE))
71 { 68 {
72 static proxy<O1,O2> p;
73 obj = reinterpret_cast<void *>(object); 69 o = reinterpret_cast<klass *>(object);
74 meth = reinterpret_cast<R (object::*)($TYPE)>(method); 70 m = reinterpret_cast<R (klass::*)($TYPE)>(method);
75 prxy = &p;
76 } 71 }
77 72
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) :)
78 R call($TYPEARG) const 77 R call($TYPEARG) const
79 { 78 {
80 return prxy->call (obj, meth$_ARG); 79 return (o->*m) ($ARG);
81 } 80 }
82 81
83 R operator ()($TYPEARG) const 82 R operator ()($TYPEARG) const
84 { 83 {
85 return call ($ARG); 84 return call ($ARG);
86 } 85 }
87}; 86};
88 87
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
89EOF 109EOF
90} 110}
91 111
92print <<EOF 112print <<EOF
113
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
93#endif 126#endif
94EOF 127EOF
95 128

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines