Lumiera  0.pre.03
»edit your freedom«
config-flags-test.cpp
Go to the documentation of this file.
1 /*
2  ConfigFlags(Test) - generating a configuration type defined by flags
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 
31 #include "lib/test/run.hpp"
32 #include "lib/format-string.hpp"
33 #include "lib/meta/generator.hpp"
35 #include "lib/meta/configflags.hpp"
38 #include "lib/format-cout.hpp"
39 #include "lib/util.hpp"
40 
41 
42 using ::test::Test;
43 using util::_Fmt;
44 using std::string;
45 
46 
47 namespace lib {
48 namespace meta {
49 namespace test {
50 
52 
53  namespace { // internal definitions
54 
55  enum Cases
56  { ONE = 1
57  , TWO
58  , THR
59  , FOU
60  , NUM_Cases = FOU
61 
62  , NOT_SET = 0
63  };
64 
65 
66 
67  /* === Test data === */
68  typedef Config<> Conf0;
69  typedef Config<ONE> Conf1;
70  typedef Config<TWO> Conf2;
71  typedef Config<THR> Conf3;
72  typedef Config<TWO,FOU> Conf4;
73 
77 
80 
81 
82 
89  template<class CONF> struct Maybe;
90 
91  struct Indeed { typedef Yes_t is_defined; };
92  template<> struct Maybe<Conf1> : Indeed { enum{ CODE = 10 }; };
93  template<> struct Maybe<Conf3> : Indeed { enum{ CODE = 30 }; };
94 
95  template<uint Fl>
96  struct Maybe<Config<TWO,Fl>>
97  {
98  typedef Yes_t is_defined;
99 
100  enum{ CODE = 20 + Fl };
101  };
102 
103 
104  } // (End) internal defs
105 
106 #define PRINT_DELIMITER(TITLE) \
107 cout << "__________________________\n" \
108  "__________________________ " \
109  << STRINGIFY(TITLE) << "\n";
110 
111 
112 
113 
114 
115  /**********************************************************************/
124  class ConfigFlags_test : public Test
125  {
126  virtual void run(Arg)
127  {
128  check_testdata ();
129  check_flags();
130  check_instantiation ();
131  check_filter ();
132  check_FlagInfo ();
133  check_ConfigSelector ();
134  }
135 
136 
137  void check_testdata ()
138  {
139  DISPLAY (Conf0);
140  DISPLAY (Conf1);
141  DISPLAY (Conf2);
142  DISPLAY (Conf3);
143  DISPLAY (Conf4);
144 
145  DISPLAY (AllFlags);
146  }
147 
148 
150  void check_flags ()
151  {
152  PRINT_DELIMITER (check_flags());
153 
154  typedef Config<TWO,FOU> Flags1;
155  typedef Flags<TWO,FOU> Flags2;
156  DISPLAY (Flags1);
157  DISPLAY (Flags2);
158  // should denote the same type
159  Flags1::Flags flags1 = Flags2::Tuple();
160  Flags2::Tuple flags2 = flags1;
161  CHECK (1==sizeof(flags1)); // pure marker-type without content
162  CHECK (1==sizeof(flags2));
163 
164  typedef DefineConfigByFlags<Node<Flag<ONE>,NullType>>::Config SimpleConfig_defined_by_Typelist;
165  DISPLAY (SimpleConfig_defined_by_Typelist);
166 
167  typedef DefineConfigByFlags<AllFlags>::Config AnotherConfig_defined_by_Typelist;
168  DISPLAY (AnotherConfig_defined_by_Typelist);
169  }
170 
171 
176  {
177  #define CAN_INSTANTIATE(NAME) \
178  cout << "defined " \
179  << STRINGIFY(NAME) \
180  << "? ---> " \
181  << Instantiation<Maybe>::Test<NAME>::value << "\n";
182 
183  PRINT_DELIMITER (check_instantiation());
184 
185  CAN_INSTANTIATE (Conf0);
186  CAN_INSTANTIATE (Conf1);
187  CAN_INSTANTIATE (Conf2);
188  CAN_INSTANTIATE (Conf3);
189  CAN_INSTANTIATE (Conf4);
190 
191  typedef Config<THR,THR> Trash;
192  CAN_INSTANTIATE (Trash);
193  }
194 
195 
199  void check_filter ()
200  {
201  PRINT_DELIMITER (check_filter());
202 
203  DISPLAY (SomeFlagsets);
204 
205  typedef Apply<SomeFlagsets::List, DefineConfigByFlags> Configs_defined_by_Flagsets;
206  DISPLAY (Configs_defined_by_Flagsets);
207 
209  DISPLAY (Filter_possible_Configs);
210 
211 
212  DISPLAY (AllFlagCombinations);
213  typedef Apply<AllFlagCombinations::List, DefineConfigByFlags> ListAllConfigs;
214  DISPLAY (ListAllConfigs);
215 
216  typedef Filter<ListAllConfigs::List,Instantiation<Maybe>::Test> Filter_all_possible_Configs;
217  DISPLAY (Filter_all_possible_Configs);
218  }
219 
220 
221 
222  struct TestVisitor
223  {
224  string result;
225 
226  TestVisitor() : result ("TestVisitor application:\n") {}
227 
228  /* === visitation interface === */
229  typedef string Ret;
230 
231  Ret done() {return result; }
232 
233  template<class CONF>
234  void
235  visit (ulong code)
236  {
237  result += string (_Fmt ("visit(code=%u) -->%s\n")
238  % code % Printer<CONF>::print() );
239  }
240  };
241 
247  {
248  PRINT_DELIMITER (check_FlagInfo());
249 
250  DISPLAY (Flags1);
251  cout << "max bit : " << FlagInfo<Flags1>::BITS <<"\n";
252  cout << "binary code: " << FlagInfo<Flags1>::CODE <<"\n";
253 
254  typedef Apply<SomeFlagsets::List, DefineConfigByFlags> SomeConfigs;
255  DISPLAY (SomeConfigs);
256  cout << "max bit in [SomeConfigs] : " << FlagInfo<SomeConfigs::List>::BITS <<"\n";
257 
258  TestVisitor visitor;
259  cout << FlagInfo<SomeConfigs::List>::accept (visitor);
260  }
261 
262 
263  template<class CONF>
264  struct TestFactory
265  {
266  uint operator() () { return offset_ + Maybe<CONF>::CODE; }
267  TestFactory(long o) : offset_(o) {}
268 
269  private:
270  long offset_;
271  };
272 
273 
279  {
280  PRINT_DELIMITER (check_ConfigSelector());
281 
282  typedef Apply<AllFlagCombinations::List, DefineConfigByFlags> ListAllConfigs;
284  DISPLAY (Possible_Configs);
285 
287  typedef ConfigSelector< TestFactory // Factory template
288  , uint(void) // Factory function type
289  , long // common ctor argument
290  > TestFactorySelector;
291 
292  const long offset = 1000; // parameter fed to all TestFactory ctors
293  TestFactorySelector testConfigSelector (Possible_Configs::List(), offset);
294 
295 
296  #define INVOKE_CONFIG_SELECTOR(CODE) \
297  cout << " Flag-code = " << CODE \
298  << " ConfigSelector() ---> " \
299  << testConfigSelector[CODE] () << "\n";
300 
301  INVOKE_CONFIG_SELECTOR (2);
302  INVOKE_CONFIG_SELECTOR (12);
303  INVOKE_CONFIG_SELECTOR (20);
304  INVOKE_CONFIG_SELECTOR (4);
305  INVOKE_CONFIG_SELECTOR (8);
306 
307  try
308  {
309  INVOKE_CONFIG_SELECTOR (23);
310  NOTREACHED ();
311  }
313  {
314  cout << err.what() << "\n";
315  lumiera_error (); // reset error flag
316  }
317  }
318 
319 
320  };
321 
322 
324  LAUNCHER (ConfigFlags_test, "unit common");
325 
326 
327 
328 }}} // namespace lib::meta::test
Automatically use custom string conversion in C++ stream output.
Helper template for semi-automatic detection if instantiation is possible.
factory::MultiFact< Num(int), prodID, factory::BuildRefcountPtr > TestFactory
the factory instantiation used for this test
a type which is only partially defined, for some configs.
Helper for calculating values and for invoking runtime code based on a given FlagTuple.
Under some circumstances it is necessary to assemble functionality out of elementary building blocks...
Definition: run.hpp:40
Front-end for printf-style string template interpolation.
Helpers for working with lib::meta::Types (i.e.
A front-end for using printf-style formatting.
Implementation namespace for support and library code.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:115
char Yes_t
helper types to detect the overload resolution chosen by the compiler
Definition: meta/util.hpp:95
generate all possible on-off combinations of the given flags
Helper for fabricating ProcNode Wiring configurations.
filter away those types which don&#39;t fulfil a predicate metafunction
Support for writing metaprogramming unit-tests dealing with typelists and flags.
Metaprogramming: Helpers for manipulating lists-of-types.
< distinct type representing a configuration
Definition: configflags.hpp:81
create a configuration type for the given list-of-flags
Sometimes we need to choose a different implementation for dealing with some special cases...