Lumiera  0.pre.03
»edit your freedom«
typelist-manip-test.cpp
Go to the documentation of this file.
1 /*
2  TypeListManip(Test) - appending, mixing and filtering typelists
3 
4  Copyright (C)
5  2008, 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 
32 #include "lib/test/run.hpp"
33 #include "lib/meta/generator.hpp"
36 
37 #include <type_traits>
38 #include <iostream>
39 
40 using ::test::Test;
41 using std::is_same;
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 
65  // see also the CountDown template in typelist-diagnostics.hpp...
66 
67  } // (End) test data
68 
69 
70 
71 
72 
73 
74  /*********************************************************************/
85  class TypeListManip_test : public Test
86  {
87  virtual void
88  run (Arg)
89  {
90  check_diagnostics ();
91  check_pick_elm ();
92  check_apply ();
93  check_filter ();
94  check_append ();
95  check_splice ();
96  check_s_last ();
97  check_dissect();
98  check_prefix ();
99  check_distribute();
100  check_combine();
101  }
102 
103 
104  void
105  check_diagnostics ()
106  {
107  // Explanation: the DISPLAY macro results in the following definition....
109  cout << "List1" << "\t:" << Contents_List1::print() << endl;
110 
111  // That is: we instantiate the "Printer" template for each of the types in List1,
112  // forming an inheritance chain. I.e. the defined Type "Contents_List1" inherits
113  // from each instantiation (single inheritance).
114  // The print() function is defined to create a string showing each.
115 
116  DISPLAY (List2);
117  }
118 
119 
120  void
121  check_pick_elm ()
122  {
126 
127  typedef Pick<List2,3>::Type E3;
128  typedef Pick<NullType,23>::Type Nil;
129  typedef Pick<void*,456>::Type Irrelevant;
130 
131  CHECK (5 == e0);
132  CHECK (6 == e1);
133  CHECK (7 == e2);
134 
135  CHECK ((is_same<NullType, E3> ::value));
136  CHECK ((is_same<NullType, Nil> ::value));
137  CHECK ((is_same<NullType, Irrelevant>::value));
138  }
139 
140 
141  void
142  check_append ()
143  {
144  typedef Append<NullType, NullType> Append1;
145  DISPLAY (Append1);
146 
147  typedef Append<Num<11>,Num<22>> Append2;
148  DISPLAY (Append2);
149 
150  typedef Append<Num<111>,NullType> Append3;
151  DISPLAY (Append3);
152 
153  typedef Append<NullType,Num<222>> Append4;
154  DISPLAY (Append4);
155 
156  typedef Append<List1,NullType> Append5;
157  DISPLAY (Append5);
158 
159  typedef Append<NullType,List2> Append6;
160  DISPLAY (Append6);
161 
162  typedef Append<Num<111>,List2> Append7;
163  DISPLAY (Append7);
164 
165  typedef Append<List1,Num<222>> Append8;
166  DISPLAY (Append8);
167 
168  typedef Append<List1,List2> Append9;
169  DISPLAY (Append9);
170  }
171 
172 
173  void
174  check_splice ()
175  {
176  typedef Types<Num<9>,Num<8>>::List OLi;
177  // will "paste" the list OLi "on top" of another Typelist...
178 
179  typedef Splice<NullType, NullType> Overl01;
180  DISPLAY (Overl01);
181 
182  typedef Splice<NullType, OLi> Overl02;
183  DISPLAY (Overl02);
184 
185  typedef Splice<NullType, OLi, 5> Overl03;
186  DISPLAY (Overl03);
187 
188  typedef Splice<List1, OLi> Overl04;
189  DISPLAY (Overl04);
190 
191  typedef Splice<List1, OLi, 1> Overl05;
192  DISPLAY (Overl05);
193 
194  typedef Splice<List1, OLi, 2> Overl06;
195  DISPLAY (Overl06);
196 
197  typedef Splice<List1, OLi, 3> Overl07;
198  DISPLAY (Overl07);
199 
200  typedef Splice<List1, OLi, 5> Overl08;
201  DISPLAY (Overl08);
202 
203  typedef Splice<List1, List1> Overl09;
204  DISPLAY (Overl09);
205 
206  typedef Splice<List1, List1, 1> Overl10;
207  DISPLAY (Overl10);
208 
209  typedef Splice<List1, NullType> Overl11;
210  DISPLAY (Overl11);
211 
212  typedef Splice<List1, NullType, 1> Overl12;
213  DISPLAY (Overl12);
214 
215  typedef Splice<List1, NullType, 5> Overl13;
216  DISPLAY (Overl13);
217 
218 
219  typedef Types<Num<99>>::List OLi2;
220  typedef Splice<List1, OLi2, 0>::Front Front1;
221  typedef Splice<List1, OLi2, 1>::Front Front2;
222  typedef Splice<List1, OLi2, 5>::Front Front3;
223  DISPLAY (Front1);
224  DISPLAY (Front2);
225  DISPLAY (Front3);
226  typedef Splice<List1, OLi2, 0>::Back Back1;
227  typedef Splice<List1, OLi2, 1>::Back Back2;
228  typedef Splice<List1, OLi2, 5>::Back Back3;
229  DISPLAY (Back1);
230  DISPLAY (Back2);
231  DISPLAY (Back3);
232 
233  // Note: with a Null-Overlay, this can be used to extract arbitrary sublists:
234  typedef Splice<List1, NullType, 1>::Front Front4;
235  typedef Splice<List1, NullType, 1>::Back Back4;
236  DISPLAY (Front4);
237  DISPLAY (Back4);
238  }
239 
240 
241  void
242  check_s_last()
243  {
244  typedef SplitLast<List1>::Type Elm;
245  typedef SplitLast<List1>::List Prefix;
246 
247  typedef Types<Elm>::List ElmL;
248 
249  DISPLAY (Prefix);
250  DISPLAY (ElmL);
251 
252  typedef SplitLast<ElmL>::Type Elm1;
253  typedef SplitLast<ElmL>::List NPrefix;
254 
255  DISPLAY (NPrefix);
256  DISPLAY (Types<Elm1>);
257 
258  typedef SplitLast<NullType>::Type Nil;
259  typedef SplitLast<NullType>::List NList;
260 
261  DISPLAY (NList);
262  DISPLAY (Types<Nil>);
263  }
264 
265 
266  void
267  check_dissect()
268  {
269  typedef Append<List1,List2>::List LL;
270  DISPLAY (LL);
271 
272  typedef Dissect<LL>::List List; DISPLAY(List);
273  typedef Dissect<LL>::First First; DISPLAY(First);
274  typedef Dissect<LL>::Tail Tail; DISPLAY(Tail);
275  typedef Dissect<LL>::Prefix Prefix; DISPLAY(Prefix);
276  typedef Dissect<LL>::Last Last; DISPLAY(Last);
277 
278  typedef Dissect<LL>::Head Head;
279  typedef Dissect<LL>::End End;
280 
281  typedef Types<Head,End> HeadEnd; DISPLAY(HeadEnd);
282  }
283 
284 
285 
286 
287  template<class X> struct AddConst2 { typedef X Type; };
288  template<int I> struct AddConst2<Num<I>> { typedef Num<I+2> Type; };
289 
290  void
291  check_apply ()
292  {
293  typedef Apply<List1, AddConst2> Added2;
294  DISPLAY (Added2);
295  }
296 
297 
298  template<class X> struct IsEven { enum {value = false }; };
299  template<int I> struct IsEven<Num<I>> { enum {value = (0 == I % 2) }; };
300 
301  void
302  check_filter ()
303  {
304  typedef Filter<Append<List1,List2>::List, IsEven > FilterEven;
305  DISPLAY (FilterEven);
306  }
307 
308 
309  void
310  check_prefix ()
311  {
312  typedef PrefixAll<Num<11>,Num<22>> Prefix1;
313  DISPLAY (Prefix1);
314 
315  typedef PrefixAll<Num<101>,List1> Prefix2;
316  DISPLAY (Prefix2);
317 
318  typedef PrefixAll<NullType,List1> Prefix3;
319  DISPLAY (Prefix3);
320 
321  typedef Types<List1::List,Num<0>,List2::List>::List List_of_Lists;
322  typedef PrefixAll<Num<111>,List_of_Lists> Prefix4;
323  DISPLAY (Prefix4);
324 
325  typedef PrefixAll<List1,List2> Prefix5;
326  DISPLAY (Prefix5);
327 
328  typedef PrefixAll<List1,List_of_Lists> Prefix6;
329  DISPLAY (Prefix6);
330  }
331 
332 
333  void
334  check_distribute()
335  {
336  typedef Distribute<Num<11>, List1> Dist1;
337  DISPLAY (Dist1);
338 
339  typedef Types<Num<11>,Num<22>,Num<33>>::List Prefixes;
340  typedef Distribute<Prefixes, Num<0>> Dist2;
341  DISPLAY (Dist2);
342 
343  typedef Distribute<Prefixes, List1> Dist3;
344  DISPLAY (Dist3);
345 
347  DISPLAY (Dist4);
348  }
349 
350 
351  void
352  check_combine()
353  {
354  typedef CountDown<Num<11>> Down;
355  DISPLAY (Down);
356 
357  typedef Combine<List1::List, CountDown> Combi;
358  DISPLAY (Combi);
359 
360  typedef CombineFlags<List1::List> OnOff;
361  DISPLAY (OnOff);
362  }
363 
364 
365  };
366 
367 
369  LAUNCHER (TypeListManip_test, "unit common");
370 
371 
372 
373 }}} // namespace lib::meta::test
Definition: run.hpp:40
Helpers for working with lib::meta::Types (i.e.
build all possible combinations, based on a enumeration of the basic cases.
Implementation namespace for support and library code.
Simplistic test class runner.
append lists-of-types
splice a typelist like an overlay into an base typelist, starting at given index. ...
Build a single inheritance chain of template instantiations.
Definition: generator.hpp:120
generate all possible on-off combinations of the given flags
prefix each of the elements, yielding a list-of lists-of-types
access the last list element
filter away those types which don&#39;t fulfil a predicate metafunction
helper for generating test lists
build a list-of lists, where each element of the first arg list gets in turn prepended to all element...
Support for writing metaprogramming unit-tests dealing with typelists and flags.
Allows to access various parts of a given typelist: Start and End, Prefix and Tail...
Metaprogramming: Helpers for manipulating lists-of-types.
constant-wrapper type for debugging purposes, usable for generating lists of distinguishable types ...