ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/callback.pl
Revision: 1.10
Committed: Sun Dec 2 00:54:52 2007 UTC (16 years, 5 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +26 -39 lines
Log Message:
update callback.pl to use the same trick as libev uses

File Contents

# Content
1 #!/usr/bin/perl
2
3 use strict;
4
5 print <<EOF;
6 // THIS IS A GENERATED FILE: RUN callback.pl to regenerate it
7 // THIS IS A GENERATED FILE: callback.pl is part of the GVPE
8 // THIS IS A GENERATED FILE: distribution.
9
10 /*
11 callback.h -- C++ callback mechanism
12 Copyright (C) 2003-2007 Marc Lehmann <pcg\@goof.com>
13
14 This file is part of GVPE.
15
16 GVPE is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with gvpe; if not, write to the Free Software
28 Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31 #ifndef CALLBACK_H__
32 #define CALLBACK_H__
33
34 #define CALLBACK_H_VERSION 3
35
36 template<class signature>
37 struct callback_funtype_trait;
38
39 template<int arity, class signature>
40 struct callback_get_impl;
41
42 EOF
43
44 for my $a (0..10) {
45 my $CLASS = join "", map ", class A$_", 1..$a;
46 my $TYPE = join ", ", map "A$_", 1..$a;
47 my $ARG = join ", ", map "a$_", 1..$a;
48 my $TYPEARG = join ", ", map "A$_ a$_", 1..$a;
49 my $TYPEDEFS = join " ", map "typedef A$_ arg$_\_type;", 1..$a;
50 my $TYPEvoid = $TYPE ? $TYPE : "void";
51 my $_TYPE = $TYPE ? ", $TYPE" : "";
52 my $_TTYPE = $a ? join "", map ", typename T::arg$_\_type", 1..$a : "";
53
54 print <<EOF;
55 template<class R$CLASS>
56 class callback$a
57 {
58 struct klass; // it is vital that this is never defined
59
60 typedef R (klass::*ptr_type)($TYPE);
61
62 klass *o;
63 R (klass::*m)($TYPE);
64
65 public:
66 template<class O1, class O2>
67 explicit callback$a (O1 *object, R (O2::*method)($TYPE))
68 {
69 o = reinterpret_cast<klass *>(object);
70 m = reinterpret_cast<R (klass::*)($TYPE)>(method);
71 }
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) :)
77 R call($TYPEARG) const
78 {
79 return (o->*m) ($ARG);
80 }
81
82 R operator ()($TYPEARG) const
83 {
84 return call ($ARG);
85 }
86 };
87
88 template<class R$CLASS>
89 struct 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
97 template<class R$CLASS>
98 struct callback_funtype_trait<R ($TYPE)> : callback_funtype_trait$a<R$_TYPE>
99 {
100 };
101
102 template<class signature>
103 struct 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
109 EOF
110 }
111
112 print <<EOF
113
114 template<class signature>
115 struct 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
127 EOF
128