c4fefb8e32360a034c26a7cc49fd292e984dace3
[xonotic/netradiant.git] / libs / generic / callback.cpp
1 /*
2    Copyright (C) 2001-2006, William Joseph.
3    All Rights Reserved.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "callback.h"
23
24 #if defined( _DEBUG ) || defined( DOXYGEN )
25
26 namespace ExampleMemberCaller
27 {
28 // MemberCaller example
29 class Integer
30 {
31 public:
32 int value;
33
34 void printValue() const {
35         // print this->value here;
36 }
37
38 void setValue(){
39         value = 3;
40 }
41 // a typedef to make things more readable
42 typedef MemberCaller<Integer, &Integer::setValue> SetValueCaller;
43 };
44
45 void example(){
46         Integer foo = { 0 };
47
48         {
49                 Callback bar = ConstMemberCaller<Integer, &Integer::printValue>( foo );
50
51                 // invoke the callback
52                 bar(); // foo.printValue()
53         }
54
55
56         {
57                 // use the typedef to improve readability
58                 Callback bar = Integer::SetValueCaller( foo );
59
60                 // invoke the callback
61                 bar(); // foo.setValue()
62         }
63 }
64 // end example
65 }
66
67 namespace ExampleReferenceCaller
68 {
69 // ReferenceCaller example
70 void Int_printValue( const int& value ){
71         // print value here;
72 }
73
74 void Int_setValue( int& value ){
75         value = 3;
76 }
77
78 // a typedef to make things more readable
79 typedef ReferenceCaller<int, Int_setValue> IntSetValueCaller;
80
81 void example(){
82         int foo = 0;
83
84         {
85                 Callback bar = ConstReferenceCaller<int, Int_printValue>( foo );
86
87                 // invoke the callback
88                 bar(); // Int_printValue(foo)
89         }
90
91
92         {
93                 // use the typedef to improve readability
94                 Callback bar = IntSetValueCaller( foo );
95
96                 // invoke the callback
97                 bar(); // Int_setValue(foo)
98         }
99 }
100 // end example
101 }
102
103 #endif
104
105 namespace
106 {
107 class A1
108 {
109 };
110 class A2
111 {
112 };
113 class A3
114 {
115 };
116 class A4
117 {
118 };
119
120 class Test
121 {
122 public:
123 void test0(){
124 }
125 typedef Member<Test, void, &Test::test0> Test0;
126 typedef MemberCaller<Test, &Test::test0> Test0Caller;
127 void test0const() const {
128 }
129 typedef ConstMember<Test, void, &Test::test0const> Test0Const;
130 typedef ConstMemberCaller<Test, &Test::test0const> Test0ConstCaller;
131 void test1( A1 ){
132 }
133 typedef Member1<Test, A1, void, &Test::test1> Test1;
134 typedef MemberCaller1<Test, A1, &Test::test1> Test1Caller;
135 void test1const( A1 ) const {
136 }
137 typedef ConstMember1<Test, A1, void, &Test::test1const> Test1Const;
138 typedef ConstMemberCaller1<Test, A1, &Test::test1const> Test1ConstCaller;
139 void test2( A1, A2 ){
140 }
141 typedef Member2<Test, A1, A2, void, &Test::test2> Test2;
142 void test2const( A1, A2 ) const {
143 }
144 typedef ConstMember2<Test, A1, A2, void, &Test::test2const> Test2Const;
145 void test3( A1, A2, A3 ){
146 }
147 typedef Member3<Test, A1, A2, A3, void, &Test::test3> Test3;
148 void test3const( A1, A2, A3 ) const {
149 }
150 typedef ConstMember3<Test, A1, A2, A3, void, &Test::test3const> Test3Const;
151 };
152
153 void test0free(){
154 }
155 typedef FreeCaller<&test0free> Test0FreeCaller;
156 void test1free( A1 ){
157 }
158 typedef FreeCaller1<A1, &test1free> Test1FreeCaller;
159 void test2free( A1, A2 ){
160 }
161 typedef Function2<A1, A2, void, &test2free> Test2Free;
162 void test3free( A1, A2, A3 ){
163 }
164 typedef Function3<A1, A2, A3, void, &test3free> Test3Free;
165
166
167 void test0( Test& test ){
168 }
169 typedef ReferenceCaller<Test, &test0> Test0Caller;
170
171 void test0const( const Test& test ){
172 }
173 typedef ConstReferenceCaller<Test, &test0const> Test0ConstCaller;
174
175 void test0p( Test* test ){
176 }
177 typedef PointerCaller<Test, &test0p> Test0PCaller;
178
179 void test0constp( const Test* test ){
180 }
181 typedef ConstPointerCaller<Test, &test0constp> Test0ConstPCaller;
182
183 void test1( Test& test, A1 ){
184 }
185 typedef ReferenceCaller1<Test, A1, &test1> Test1Caller;
186
187 void test1const( const Test& test, A1 ){
188 }
189 typedef ConstReferenceCaller1<Test, A1, &test1const> Test1ConstCaller;
190
191 void test1p( Test* test, A1 ){
192 }
193 typedef PointerCaller1<Test, A1, &test1p> Test1PCaller;
194
195 void test1constp( const Test* test, A1 ){
196 }
197 typedef ConstPointerCaller1<Test, A1, &test1constp> Test1ConstPCaller;
198
199 void test2( Test& test, A1, A2 ){
200 }
201 typedef Function3<Test&, A1, A2, void, &test2> Test2;
202
203 void test3( Test& test, A1, A2, A3 ){
204 }
205 typedef Function4<Test&, A1, A2, A3, void, &test3> Test3;
206
207 void instantiate(){
208         Test test;
209         const Test& testconst = test;
210         {
211                 Callback a = Test0FreeCaller();
212                 Callback b = Test::Test0Caller( test );
213                 b = makeCallback0( Test::Test0(), test );
214                 Callback c = Test::Test0ConstCaller( testconst );
215                 c = makeCallback0( Test::Test0Const(), test );
216                 Test0Caller{ test };
217                 Test0ConstCaller{ testconst };
218                 Test0PCaller{ &test };
219                 Test0ConstPCaller{ &testconst };
220                 a();
221                 bool u = a != b;
222         }
223         {
224                 typedef Callback1<A1> TestCallback1;
225                 TestCallback1 a = Test1FreeCaller();
226                 TestCallback1 b = Test::Test1Caller( test );
227                 b = makeCallback1( Test::Test1(), test );
228                 TestCallback1 c = Test::Test1ConstCaller( testconst );
229                 c = makeCallback1( Test::Test1Const(), test );
230                 Test1Caller{ test };
231                 Test1ConstCaller{ testconst };
232                 Test1PCaller{ &test };
233                 Test1ConstPCaller{ &testconst };
234                 a( A1() );
235                 bool u = a != b;
236         }
237         {
238                 typedef Callback2<A1, A2> TestCallback2;
239                 TestCallback2 a = makeStatelessCallback2( Test2Free() );
240                 TestCallback2 b = makeCallback2( Test2(), test );
241                 makeCallback2( Test::Test2(), test );
242                 makeCallback2( Test::Test2Const(), test );
243                 a( A1(), A2() );
244                 bool u = a != b;
245         }
246         {
247                 typedef Callback3<A1, A2, A3> TestCallback3;
248                 TestCallback3 a = makeStatelessCallback3( Test3Free() );
249                 TestCallback3 b = makeCallback3( Test3(), test );
250                 makeCallback3( Test::Test3(), test );
251                 makeCallback3( Test::Test3Const(), test );
252                 a( A1(), A2(), A3() );
253                 bool u = a != b;
254         }
255 }
256 }