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) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program 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 this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
41 #include "lib/test/run.hpp"
42 #include "lib/meta/generator.hpp"
45 
46 #include <type_traits>
47 #include <iostream>
48 
49 using ::test::Test;
50 using std::is_same;
51 using std::cout;
52 using std::endl;
53 
54 
55 namespace lib {
56 namespace meta {
57 namespace test {
58 
59 
60  namespace { // test data
61 
62 
63 
64  typedef Types< Num<1>
65  , Num<2>
66  , Num<3>
67  >::List List1;
68  typedef Types< Num<5>
69  , Num<6>
70  , Num<7>
71  >::List List2;
72 
73 
74  // see also the CountDown template in typelist-diagnostics.hpp...
75 
76  } // (End) test data
77 
78 
79 
80 
81 
82 
83  /*********************************************************************/
94  class TypeListManip_test : public Test
95  {
96  virtual void
97  run (Arg)
98  {
99  check_diagnostics ();
100  check_pick_elm ();
101  check_apply ();
102  check_filter ();
103  check_append ();
104  check_splice ();
105  check_s_last ();
106  check_dissect();
107  check_prefix ();
108  check_distribute();
109  check_combine();
110  }
111 
112 
113  void
114  check_diagnostics ()
115  {
116  // Explanation: the DISPLAY macro results in the following definition....
118  cout << "List1" << "\t:" << Contents_List1::print() << endl;
119 
120  // That is: we instantiate the "Printer" template for each of the types in List1,
121  // forming an inheritance chain. I.e. the defined Type "Contents_List1" inherits
122  // from each instantiation (single inheritance).
123  // The print() function is defined to create a string showing each.
124 
125  DISPLAY (List2);
126  }
127 
128 
129  void
130  check_pick_elm ()
131  {
135 
136  typedef Pick<List2,3>::Type E3;
137  typedef Pick<NullType,23>::Type Nil;
138  typedef Pick<void*,456>::Type Irrelevant;
139 
140  CHECK (5 == e0);
141  CHECK (6 == e1);
142  CHECK (7 == e2);
143 
144  CHECK ((is_same<NullType, E3> ::value));
145  CHECK ((is_same<NullType, Nil> ::value));
146  CHECK ((is_same<NullType, Irrelevant>::value));
147  }
148 
149 
150  void
151  check_append ()
152  {
153  typedef Append<NullType, NullType> Append1;
154  DISPLAY (Append1);
155 
156  typedef Append<Num<11>,Num<22>> Append2;
157  DISPLAY (Append2);
158 
159  typedef Append<Num<111>,NullType> Append3;
160  DISPLAY (Append3);
161 
162  typedef Append<NullType,Num<222>> Append4;
163  DISPLAY (Append4);
164 
165  typedef Append<List1,NullType> Append5;
166  DISPLAY (Append5);
167 
168  typedef Append<NullType,List2> Append6;
169  DISPLAY (Append6);
170 
171  typedef Append<Num<111>,List2> Append7;
172  DISPLAY (Append7);
173 
174  typedef Append<List1,Num<222>> Append8;
175  DISPLAY (Append8);
176 
177  typedef Append<List1,List2> Append9;
178  DISPLAY (Append9);
179  }
180 
181 
182  void
183  check_splice ()
184  {
185  typedef Types<Num<9>,Num<8>>::List OLi;
186  // will "paste" the list OLi "on top" of another Typelist...
187 
188  typedef Splice<NullType, NullType> Overl01;
189  DISPLAY (Overl01);
190 
191  typedef Splice<NullType, OLi> Overl02;
192  DISPLAY (Overl02);
193 
194  typedef Splice<NullType, OLi, 5> Overl03;
195  DISPLAY (Overl03);
196 
197  typedef Splice<List1, OLi> Overl04;
198  DISPLAY (Overl04);
199 
200  typedef Splice<List1, OLi, 1> Overl05;
201  DISPLAY (Overl05);
202 
203  typedef Splice<List1, OLi, 2> Overl06;
204  DISPLAY (Overl06);
205 
206  typedef Splice<List1, OLi, 3> Overl07;
207  DISPLAY (Overl07);
208 
209  typedef Splice<List1, OLi, 5> Overl08;
210  DISPLAY (Overl08);
211 
212  typedef Splice<List1, List1> Overl09;
213  DISPLAY (Overl09);
214 
215  typedef Splice<List1, List1, 1> Overl10;
216  DISPLAY (Overl10);
217 
218  typedef Splice<List1, NullType> Overl11;
219  DISPLAY (Overl11);
220 
221  typedef Splice<List1, NullType, 1> Overl12;
222  DISPLAY (Overl12);
223 
224  typedef Splice<List1, NullType, 5> Overl13;
225  DISPLAY (Overl13);
226 
227 
228  typedef Types<Num<99>>::List OLi2;
229  typedef Splice<List1, OLi2, 0>::Front Front1;
230  typedef Splice<List1, OLi2, 1>::Front Front2;
231  typedef Splice<List1, OLi2, 5>::Front Front3;
232  DISPLAY (Front1);
233  DISPLAY (Front2);
234  DISPLAY (Front3);
235  typedef Splice<List1, OLi2, 0>::Back Back1;
236  typedef Splice<List1, OLi2, 1>::Back Back2;
237  typedef Splice<List1, OLi2, 5>::Back Back3;
238  DISPLAY (Back1);
239  DISPLAY (Back2);
240  DISPLAY (Back3);
241 
242  // Note: with a Null-Overlay, this can be used to extract arbitrary sublists:
243  typedef Splice<List1, NullType, 1>::Front Front4;
244  typedef Splice<List1, NullType, 1>::Back Back4;
245  DISPLAY (Front4);
246  DISPLAY (Back4);
247  }
248 
249 
250  void
251  check_s_last()
252  {
253  typedef SplitLast<List1>::Type Elm;
254  typedef SplitLast<List1>::List Prefix;
255 
256  typedef Types<Elm>::List ElmL;
257 
258  DISPLAY (Prefix);
259  DISPLAY (ElmL);
260 
261  typedef SplitLast<ElmL>::Type Elm1;
262  typedef SplitLast<ElmL>::List NPrefix;
263 
264  DISPLAY (NPrefix);
265  DISPLAY (Types<Elm1>);
266 
267  typedef SplitLast<NullType>::Type Nil;
268  typedef SplitLast<NullType>::List NList;
269 
270  DISPLAY (NList);
271  DISPLAY (Types<Nil>);
272  }
273 
274 
275  void
276  check_dissect()
277  {
278  typedef Append<List1,List2>::List LL;
279  DISPLAY (LL);
280 
281  typedef Dissect<LL>::List List; DISPLAY(List);
282  typedef Dissect<LL>::First First; DISPLAY(First);
283  typedef Dissect<LL>::Tail Tail; DISPLAY(Tail);
284  typedef Dissect<LL>::Prefix Prefix; DISPLAY(Prefix);
285  typedef Dissect<LL>::Last Last; DISPLAY(Last);
286 
287  typedef Dissect<LL>::Head Head;
288  typedef Dissect<LL>::End End;
289 
290  typedef Types<Head,End> HeadEnd; DISPLAY(HeadEnd);
291  }
292 
293 
294 
295 
296  template<class X> struct AddConst2 { typedef X Type; };
297  template<int I> struct AddConst2<Num<I>> { typedef Num<I+2> Type; };
298 
299  void
300  check_apply ()
301  {
302  typedef Apply<List1, AddConst2> Added2;
303  DISPLAY (Added2);
304  }
305 
306 
307  template<class X> struct IsEven { enum {value = false }; };
308  template<int I> struct IsEven<Num<I>> { enum {value = (0 == I % 2) }; };
309 
310  void
311  check_filter ()
312  {
313  typedef Filter<Append<List1,List2>::List, IsEven > FilterEven;
314  DISPLAY (FilterEven);
315  }
316 
317 
318  void
319  check_prefix ()
320  {
321  typedef PrefixAll<Num<11>,Num<22>> Prefix1;
322  DISPLAY (Prefix1);
323 
324  typedef PrefixAll<Num<101>,List1> Prefix2;
325  DISPLAY (Prefix2);
326 
327  typedef PrefixAll<NullType,List1> Prefix3;
328  DISPLAY (Prefix3);
329 
330  typedef Types<List1::List,Num<0>,List2::List>::List List_of_Lists;
331  typedef PrefixAll<Num<111>,List_of_Lists> Prefix4;
332  DISPLAY (Prefix4);
333 
334  typedef PrefixAll<List1,List2> Prefix5;
335  DISPLAY (Prefix5);
336 
337  typedef PrefixAll<List1,List_of_Lists> Prefix6;
338  DISPLAY (Prefix6);
339  }
340 
341 
342  void
343  check_distribute()
344  {
345  typedef Distribute<Num<11>, List1> Dist1;
346  DISPLAY (Dist1);
347 
348  typedef Types<Num<11>,Num<22>,Num<33>>::List Prefixes;
349  typedef Distribute<Prefixes, Num<0>> Dist2;
350  DISPLAY (Dist2);
351 
352  typedef Distribute<Prefixes, List1> Dist3;
353  DISPLAY (Dist3);
354 
356  DISPLAY (Dist4);
357  }
358 
359 
360  void
361  check_combine()
362  {
363  typedef CountDown<Num<11>> Down;
364  DISPLAY (Down);
365 
366  typedef Combine<List1::List, CountDown> Combi;
367  DISPLAY (Combi);
368 
369  typedef CombineFlags<List1::List> OnOff;
370  DISPLAY (OnOff);
371  }
372 
373 
374  };
375 
376 
378  LAUNCHER (TypeListManip_test, "unit common");
379 
380 
381 
382 }}} // namespace lib::meta::test
Definition: run.hpp:49
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.
Simple 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:129
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 ...