Lumiera  0.pre.03
»edit your freedom«
function-closure-test.cpp
Go to the documentation of this file.
1 /*
2  FunctionClosure(Test) - appending, mixing and filtering typelists
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 
14 
29 #include "lib/test/run.hpp"
30 #include "lib/test/test-helper.hpp"
31 #include "lib/meta/typelist.hpp"
33 #include "lib/meta/function.hpp"
37 
38 #include <iostream>
39 
40 using ::test::Test;
41 using std::string;
42 using std::cout;
43 using std::endl;
44 
45 
46 namespace lib {
47 namespace meta {
48 namespace test {
49 
50 
51  namespace { // test data
52 
53 
54 
55  typedef Types< Num<1>
56  , Num<2>
57  , Num<3>
58  >::List List1;
59  typedef Types< Num<5>
60  , Num<6>
61  , Num<7>
62  >::List List2;
63 
64 
67  template<char i,char ii, char iii>
68  int
70  {
71  return one.o_ + two.o_ + three.o_;
72  }
73 
74 
75  int fun0 () { return -1; }
76  int fun1 (int i1) { return i1; }
77  int fun2 (int i1, int i2) { return i1+i2; }
78  int fun3 (int i1, int i2, int i3) { return i1+i2+i3; }
79 
80  } // (End) test data
81 
82 
83 
84 
85  using func::Apply;
88  using func::closure;
89  using func::apply;
90 
91 
92  /*********************************************************************/
102  class FunctionClosure_test : public Test
103  {
104  virtual void
105  run (Arg)
106  {
108  check_signatureTypeManip ();
109  check_applyFree ();
110  check_applyFunc ();
111  check_bindFree ();
112  check_bindFunc ();
113  build_closure ();
114  }
115 
116 
121  void
123  {
124  DISPLAY (List1);
125  DISPLAY (List2);
126  ;
127  CHECK (6 == (getNumberz<1,2,3> (Num<1>(), Num<2>(), Num<3>())));
128  CHECK (6 == (getNumberz<1,1,1> (Num<1>(), Num<1>(2), Num<1>(3))));
129  }
130 
131 
132  void
133  check_signatureTypeManip ()
134  {
135  typedef int someFunc(Num<5>,Num<9>);
136  typedef _Fun<someFunc>::Ret RetType; // should be int
137  typedef _Fun<someFunc>::Args Args;
138  DISPLAY (Args);
139 
140  typedef Prepend<Num<1>, Args>::Seq NewArgs; // manipulate the argument type(s)
141  DISPLAY (NewArgs);
142 
143  typedef BuildFunType<RetType,NewArgs>::Sig NewSig; // re-build a new function signature
144 
145  NewSig& fun = getNumberz<1,5,9>; //...which is compatible to an existing real function signature!
146 
147  CHECK (1+5+9 == fun(Num<1>(), Num<5>(), Num<9>()));
148  }
149 
150 
151  void
152  check_applyFree ()
153  {
154  cout << "\t:\n\t: ---Apply---\n";
155 
156  Tuple<Types<>> tup0 ;
157  Tuple<Types<int>> tup1 (11);
158  Tuple<Types<int,int>> tup2 (11,12);
159  Tuple<Types<int,int,int>> tup3 (11,12,13);
160  DUMPVAL (tup0);
161  DUMPVAL (tup1);
162  DUMPVAL (tup2);
163  DUMPVAL (tup3);
164 
165  CHECK (-1 == Apply<0>::invoke<int> (fun0, tup0) );
166  CHECK (11 == Apply<1>::invoke<int> (fun1, tup1) );
167  CHECK (11+12 == Apply<2>::invoke<int> (fun2, tup2) );
168  CHECK (11+12+13 == Apply<3>::invoke<int> (fun3, tup3) );
169 
170  CHECK (-1 == TupleApplicator<int()> (tup0) (fun0) );
171  CHECK (11 == TupleApplicator<int(int)> (tup1) (fun1) );
172  CHECK (11+12 == TupleApplicator<int(int,int)> (tup2) (fun2) );
173  CHECK (11+12+13 == TupleApplicator<int(int,int,int)> (tup3) (fun3) );
174 
175  CHECK (-1 == apply(fun0, tup0) );
176  CHECK (11 == apply(fun1, tup1) );
177  CHECK (11+12 == apply(fun2, tup2) );
178  CHECK (11+12+13 == apply(fun3, tup3) );
179 
180  }
181 
182 
183  void
184  check_applyFunc ()
185  {
186  Tuple<Types<>> tup0 ;
187  Tuple<Types<int>> tup1 (11);
188  Tuple<Types<int,int>> tup2 (11,12);
189  Tuple<Types<int,int,int>> tup3 (11,12,13);
190  function<int()> functor0 (fun0);
191  function<int(int)> functor1 (fun1);
192  function<int(int,int)> functor2 (fun2);
193  function<int(int,int,int)> functor3 (fun3);
194 
195  CHECK (-1 == Apply<0>::invoke<int> (functor0, tup0) );
196  CHECK (11 == Apply<1>::invoke<int> (functor1, tup1) );
197  CHECK (11+12 == Apply<2>::invoke<int> (functor2, tup2) );
198  CHECK (11+12+13 == Apply<3>::invoke<int> (functor3, tup3) );
199 
200  CHECK (-1 == TupleApplicator<int()> (tup0) (functor0) );
201  CHECK (11 == TupleApplicator<int(int)> (tup1) (functor1) );
202  CHECK (11+12 == TupleApplicator<int(int,int)> (tup2) (functor2) );
203  CHECK (11+12+13 == TupleApplicator<int(int,int,int)> (tup3) (functor3) );
204 
205  CHECK (-1 == apply(functor0, tup0) );
206  CHECK (11 == apply(functor1, tup1) );
207  CHECK (11+12 == apply(functor2, tup2) );
208  CHECK (11+12+13 == apply(functor3, tup3) );
209 
210  }
211 
212 
213  void
214  check_bindFree ()
215  {
216  cout << "\t:\n\t: ---Bind----\n";
217 
218  Tuple<Types<>> tup0 ;
219  Tuple<Types<int>> tup1 (11);
220  Tuple<Types<int,int>> tup2 (11,12);
221  Tuple<Types<int,int,int>> tup3 (11,12,13);
222 
223  typedef function<int()> BoundFun;
224 
225  BoundFun functor0 = Apply<0>::bind<BoundFun> (fun0, tup0);
226  BoundFun functor1 = Apply<1>::bind<BoundFun> (fun1, tup1);
227  BoundFun functor2 = Apply<2>::bind<BoundFun> (fun2, tup3);
228  BoundFun functor3 = Apply<3>::bind<BoundFun> (fun3, tup3);
229 
230  CHECK (-1 == functor0() );
231  CHECK (11 == functor1() );
232  CHECK (11+12 == functor2() );
233  CHECK (11+12+13 == functor3() );
234 
235  functor0 = TupleApplicator<int()> (tup0).bind (fun0);
236  functor1 = TupleApplicator<int(int)> (tup1).bind (fun1);
237  functor2 = TupleApplicator<int(int,int)> (tup2).bind (fun2);
238  functor3 = TupleApplicator<int(int,int,int)> (tup3).bind (fun3);
239 
240  CHECK (-1 == functor0() );
241  CHECK (11 == functor1() );
242  CHECK (11+12 == functor2() );
243  CHECK (11+12+13 == functor3() );
244 
245  }
246 
247 
248  void
249  check_bindFunc ()
250  {
251  Tuple<Types<>> tup0 ;
252  Tuple<Types<int>> tup1 (11);
253  Tuple<Types<int,int>> tup2 (11,12);
254  Tuple<Types<int,int,int>> tup3 (11,12,13);
255  function<int()> unbound_functor0 (fun0);
256  function<int(int)> unbound_functor1 (fun1);
257  function<int(int,int)> unbound_functor2 (fun2);
258  function<int(int,int,int)> unbound_functor3 (fun3);
259 
260  typedef function<int()> BoundFun;
261 
262  BoundFun functor0 = Apply<0>::bind<BoundFun> (unbound_functor0, tup0);
263  BoundFun functor1 = Apply<1>::bind<BoundFun> (unbound_functor1, tup1);
264  BoundFun functor2 = Apply<2>::bind<BoundFun> (unbound_functor2, tup3);
265  BoundFun functor3 = Apply<3>::bind<BoundFun> (unbound_functor3, tup3);
266 
267  CHECK (-1 == functor0() );
268  CHECK (11 == functor1() );
269  CHECK (11+12 == functor2() );
270  CHECK (11+12+13 == functor3() );
271 
272  functor0 = TupleApplicator<int()> (tup0).bind (unbound_functor0);
273  functor1 = TupleApplicator<int(int)> (tup1).bind (unbound_functor1);
274  functor2 = TupleApplicator<int(int,int)> (tup2).bind (unbound_functor2);
275  functor3 = TupleApplicator<int(int,int,int)> (tup3).bind (unbound_functor3);
276 
277  CHECK (-1 == functor0() );
278  CHECK (11 == functor1() );
279  CHECK (11+12 == functor2() );
280  CHECK (11+12+13 == functor3() );
281 
282  }
283 
284 
285  void
286  build_closure ()
287  {
288  Tuple<Types<>> tup0 ;
289  Tuple<Types<int>> tup1 (11);
290  Tuple<Types<int,int>> tup2 (11,12);
291  Tuple<Types<int,int,int>> tup3 (11,12,13);
292 
293  FunctionClosure<int()> clo0 (fun0,tup0);
294  FunctionClosure<int(int)> clo1 (fun1,tup1);
295  FunctionClosure<int(int,int)> clo2 (fun2,tup2);
296  FunctionClosure<int(int,int,int)> clo3 (fun3,tup3);
297 
298  CHECK (-1 == clo0() );
299  CHECK (11 == clo1() );
300  CHECK (11+12 == clo2() );
301  CHECK (11+12+13 == clo3() );
302 
303  function<int()> unbound_functor0 (fun0);
304  function<int(int)> unbound_functor1 (fun1);
305  function<int(int,int)> unbound_functor2 (fun2);
306  function<int(int,int,int)> unbound_functor3 (fun3);
307 
308  clo0 = FunctionClosure<int()> (unbound_functor0,tup0);
309  clo1 = FunctionClosure<int(int)> (unbound_functor1,tup1);
310  clo2 = FunctionClosure<int(int,int)> (unbound_functor2,tup2);
311  clo3 = FunctionClosure<int(int,int,int)> (unbound_functor3,tup3);
312 
313  CHECK (-1 == clo0() );
314  CHECK (11 == clo1() );
315  CHECK (11+12 == clo2() );
316  CHECK (11+12+13 == clo3() );
317 
318  CHECK (-1 == closure(fun0,tup0) () );
319  CHECK (11 == closure(fun1,tup1) () );
320  CHECK (11+12 == closure(fun2,tup2) () );
321  CHECK (11+12+13 == closure(fun3,tup3) () );
322 
323  CHECK (-1 == closure(unbound_functor0,tup0) () );
324  CHECK (11 == closure(unbound_functor1,tup1) () );
325  CHECK (11+12 == closure(unbound_functor2,tup2) () );
326  CHECK (11+12+13 == closure(unbound_functor3,tup3) () );
327 
328 
329  // finally combine all techniques....
330  using NumberzArg = Types<List2>::Seq;
331  using NumberzSig = BuildFunType<int,NumberzArg>::Sig;
332 
333  Tuple<NumberzArg> numberzTup (Num<5>(22), Num<6>(33), Num<7>(44));
334 
335  FunctionClosure<NumberzSig> numClo (getNumberz<5,6,7>, numberzTup );
336 
337  CHECK (22+33+44 == numClo() );
338  }
339  };
340 
341 
343  LAUNCHER (FunctionClosure_test, "unit common");
344 
345 
346 
347 }}} // namespace lib::meta::test
Build function types from given Argument types.
Definition: function.hpp:341
A template metaprogramming technique for manipulating collections of types.
typename BuildTupleType< TYPES >::Type Tuple
Build a std::tuple from types given as type sequence.
Definition: run.hpp:40
Helper for uniform access to function signature types.
Definition: function.hpp:99
Partial function application and building a complete function closure.
Helper: prepend a type to an existing type sequence, thus shifting all elements within the sequence t...
int getNumberz(Num< i > one, Num< ii > two, Num< iii > three)
special test fun accepting the terrific Num types
void check_diagnostics()
verify the test input data
Implementation namespace for support and library code.
Metaprogramming tools for transforming functor types.
Simplistic test class runner.
Closing a function over its arguments.
A collection of frequently used helper functions to support unit testing.
an extension to typelist-diagnostics.hpp, allowing to dump the contents of a Tuple datatype...
ExampleStrategy::Qualifier two(string additionalArg)
definition of another qualifier two(arg), accepting an additional argument
Closure-creating template.
ExampleStrategy::Qualifier one()
definition of a qualifier one()
Support for writing metaprogramming unit-tests dealing with typelists and flags.
Metaprogramming: Helpers for manipulating lists-of-types.
constant-wrapper type for debugging purposes, usable for generating lists of distinguishable types ...