Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
function-erasure-test.cpp
Go to the documentation of this file.
1/*
2 FunctionErasure(Test) - verify the wrapping of functor object with type erasure
3
4 Copyright (C)
5 2009, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
19#include "lib/test/run.hpp"
22#include "lib/error.hpp"
24
25#include <functional>
26
27using ::test::Test;
28using lumiera::error::LUMIERA_ERROR_ASSERTION;
29
30
31
32namespace lib {
33namespace meta {
34namespace test {
35
36 using std::function;
37 using std::placeholders::_1;
38 using std::placeholders::_2;
39 using std::bind;
40
41
45
46 template<class HOL>
47 struct BuildEmptyFunctor { typedef long (*Type)(int,char); };
48 template<>
49 struct BuildEmptyFunctor<Efun> { typedef function<long(int,char)> Type; };
50
51
52 /*******************************************************************/
61 class FunctionErasure_test : public Test
62 {
63 virtual void
64 run (Arg)
65 {
66 function<void(int,char)> bindFunc = bind (testFunc,_1,_2);
67 function<void(int )> pAplFunc = bind (testFunc,_1,'x');
68 function<void( char)> membFunc = bind (&FunctionErasure_test::testMemberFunction,this, _1);
69
70 function<int(void)> getterFunc = &returnIt;
71
73 , Efun (bindFunc)
74 , Efun (pAplFunc)
75 , Efun (membFunc)
77 );
78
79 check_FunctPtrHolder(Efp(testFunc),Efp(&testFunc), Efp(returnIt));
80 check_VoidPtrHolder(Evoid(testFunc),Evoid(&testFunc),Evoid(returnIt));
81
83 detect_unboundFunctor(Efp(testFunc),Efp(&testFunc), Efp(returnIt));
84 detect_unboundFunctor(Evoid(testFunc),Evoid(&testFunc),Evoid(returnIt));
85 }
86
87 void
89 {
90 return testFunc('a'-'A', c);
91 }
92
93
94 void
96 {
97 typedef void (Sig1) (int,char);
98 typedef void (Sig2) (int);
99 typedef void (Sig3) (char);
100 typedef int (Sig4) ();
101
102 _sum_ = 0;
103 f1.getFun<Sig1>() (-11,'M'); // invoke stored std::function...
104 CHECK (_sum_ == 'M'-11);
105
106 _sum_ = 0;
107 f2.getFun<Sig1>() (-22,'M');
108 CHECK (_sum_ == 'M'-22);
109
110 _sum_ = 0;
111 f3.getFun<Sig2>() (-33);
112 CHECK (_sum_ == 'x'-33);
113
114 _sum_ = 0;
115 f4.getFun<Sig3>() ('U');
116 CHECK (_sum_ == 'u');
117
118 CHECK ( 'u' == f5.getFun<Sig4>() () );
119 CHECK (INSTANCEOF (function<Sig4>, &f5.getFun<Sig4>()));
120
121
122#if false
123 VERIFY_ERROR (ASSERTION, f1.getFun<Sig2>() );
124 VERIFY_ERROR (ASSERTION, f1.getFun<Sig3>() );
125 VERIFY_ERROR (ASSERTION, f1.getFun<Sig4>() );
126
127 VERIFY_ERROR (ASSERTION, f2.getFun<Sig2>() );
128 VERIFY_ERROR (ASSERTION, f3.getFun<Sig3>() );
129 VERIFY_ERROR (ASSERTION, f2.getFun<Sig4>() );
130
131 VERIFY_ERROR (ASSERTION, f3.getFun<Sig1>() );
132 VERIFY_ERROR (ASSERTION, f3.getFun<Sig3>() );
133 VERIFY_ERROR (ASSERTION, f3.getFun<Sig4>() );
134
135 VERIFY_ERROR (ASSERTION, f4.getFun<Sig1>() );
136 VERIFY_ERROR (ASSERTION, f4.getFun<Sig2>() );
137 VERIFY_ERROR (ASSERTION, f4.getFun<Sig4>() );
138
139 VERIFY_ERROR (ASSERTION, f5.getFun<Sig1>() );
140 VERIFY_ERROR (ASSERTION, f5.getFun<Sig2>() );
141 VERIFY_ERROR (ASSERTION, f5.getFun<Sig3>() );
142#endif
143 }
144
145
146 void
148 {
149 typedef void (*FP)(int,char);
150 typedef void (&FR)(int,char);
151
152 FP fun1 = &f1.getFun<void(int,char)>();
153 FP fun2 = &f2.getFun<void(int,char)>();
154 FR fun2r = f2.getFun<void(int,char)>();
155
156 _sum_ = 0;
157 (*fun1) (10, 'a'); // invoke retrieved function pointer
158 CHECK (_sum_ == 10+'a');
159
160 (*fun2) (20, 'b');
161 CHECK (_sum_ == 10+'a'+20+'b');
162
163 fun2r (30, 'c');
164 CHECK (_sum_ == 10+'a'+20+'b'+30+'c');
165
166 CHECK (_sum_ == (f3.getFun<int(void)>()) () );
167 }
168
169
170 void
172 {
173 typedef void (*FP)(int,char);
174 typedef void (&FR)(int,char);
175
176 FP fun1 = &f1.getFun<void(int,char)>();
177 FP fun2 = &f2.getFun<void(int,char)>();
178 FR fun2r = f2.getFun<void(int,char)>();
179
180 _sum_ = 0;
181 (*fun1) (10, 'a');
182 CHECK (_sum_ == 10+'a');
183
184 (*fun2) (20, 'b');
185 CHECK (_sum_ == 10+'a'+20+'b');
186
187 fun2r (30, 'c');
188 CHECK (_sum_ == 10+'a'+20+'b'+30+'c');
189
190 CHECK (_sum_ == (f3.getFun<int(void)>()) () );
191
192 FP bad_fun = &f3.getFun<void(int,char)>();
193 CHECK ((void*)bad_fun == &returnIt); // got wrong function!
194
195 //(*bad_fun) (11, 'x'); // The compiler would accept this line!
196 } // likely to result in heap corruption or SEGV
197
198
199 template<class HOL>
200 void
202 {
203 // fabricate a suitable, unbound functor to wrap...
206
207 // wrap this (actually empty) functor into the holder type
209
210 // verify the older detects that the wrapped functor is empty
212
213 // cross-verify that non-empty functors are not flagged as empty
214 CHECK ( h1 );
215 CHECK ( h2 );
216 CHECK ( h3 );
217 }
218
219
220 };
221
222
225
226
227
228}}} // namespace lib::meta::test
void check_VoidPtrHolder(Evoid f1, Evoid f2, Evoid f3)
void check_FunctPtrHolder(Efp f1, Efp f2, Efp f3)
void check_FunctorContainer(Efun f1, Efun f2, Efun f3, Efun f4, Efun f5)
void detect_unboundFunctor(HOL h1, HOL h2, HOL h3)
dummy functions to support unit testing of function metaprogramming helpers
Lumiera error handling (C++ interface).
Generic holder for functor objects, concealing the concrete function type.
FunErasure< StoreFunction > Efun
FunErasure< StoreUncheckedFunPtr > Evoid
FunErasure< StoreFunPtr > Efp
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A collection of frequently used helper functions to support unit testing.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition util.hpp:514