Dune Core Modules (2.4.2)

tupleutility.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_TUPLE_UTILITY_HH
5 #define DUNE_TUPLE_UTILITY_HH
6 
7 #include <cstddef>
8 
10 #include <dune/common/std/type_traits.hh>
11 
12 #include "tuples.hh"
13 
14 namespace Dune {
15 
33  template <class Tuple>
35  static_assert(Std::to_false_type<Tuple>::value, "Attempt to use the "
36  "unspecialized version of NullPointerInitialiser. "
37  "NullPointerInitialiser needs to be specialized for "
38  "each possible tuple size. Naturally the number of "
39  "pre-defined specializations is limited arbitrarily. "
40  "Maybe you need to raise this limit by defining some "
41  "more specializations? Also check that the tuple this "
42  "is applied to really is a tuple of pointers only.");
43  public:
45  typedef Tuple ResultType;
47  static ResultType apply();
48  };
49 
50 #ifndef DOXYGEN
51  template<class Tuple>
52  struct NullPointerInitialiser<const Tuple>
53  : public NullPointerInitialiser<Tuple>
54  {
55  typedef const Tuple ResultType;
56  };
57 
58  template<>
59  struct NullPointerInitialiser<tuple<> > {
60  typedef tuple<> ResultType;
61  static ResultType apply() {
62  return ResultType();
63  }
64  };
65 
66  template<class T0>
67  struct NullPointerInitialiser<tuple<T0*> > {
68  typedef tuple<T0*> ResultType;
69  static ResultType apply() {
70  return ResultType(static_cast<T0*>(0));
71  }
72  };
73 
74  template<class T0, class T1>
75  struct NullPointerInitialiser<tuple<T0*, T1*> > {
76  typedef tuple<T0*, T1*> ResultType;
77  static ResultType apply() {
78  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0));
79  }
80  };
81 
82  template<class T0, class T1, class T2>
83  struct NullPointerInitialiser<tuple<T0*, T1*, T2*> > {
84  typedef tuple<T0*, T1*, T2*> ResultType;
85  static ResultType apply() {
86  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
87  static_cast<T2*>(0));
88  }
89  };
90 
91  template<class T0, class T1, class T2, class T3>
92  struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*> > {
93  typedef tuple<T0*, T1*, T2*, T3*> ResultType;
94  static ResultType apply() {
95  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
96  static_cast<T2*>(0), static_cast<T3*>(0));
97  }
98  };
99 
100  template<class T0, class T1, class T2, class T3, class T4>
101  struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*> > {
102  typedef tuple<T0*, T1*, T2*, T3*, T4*> ResultType;
103  static ResultType apply() {
104  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
105  static_cast<T2*>(0), static_cast<T3*>(0),
106  static_cast<T4*>(0));
107  }
108  };
109 
110  template<class T0, class T1, class T2, class T3, class T4, class T5>
111  struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*> > {
112  typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*> ResultType;
113  static ResultType apply() {
114  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
115  static_cast<T2*>(0), static_cast<T3*>(0),
116  static_cast<T4*>(0), static_cast<T5*>(0));
117  }
118  };
119 
120  template<class T0, class T1, class T2, class T3, class T4, class T5,
121  class T6>
122  struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*> > {
123  typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*> ResultType;
124  static ResultType apply() {
125  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
126  static_cast<T2*>(0), static_cast<T3*>(0),
127  static_cast<T4*>(0), static_cast<T5*>(0),
128  static_cast<T6*>(0));
129  }
130  };
131 
132  template<class T0, class T1, class T2, class T3, class T4, class T5,
133  class T6, class T7>
134  struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*,
135  T7*> > {
136  typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*, T7*> ResultType;
137  static ResultType apply() {
138  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
139  static_cast<T2*>(0), static_cast<T3*>(0),
140  static_cast<T4*>(0), static_cast<T5*>(0),
141  static_cast<T6*>(0), static_cast<T7*>(0));
142  }
143  };
144 
145  template<class T0, class T1, class T2, class T3, class T4, class T5,
146  class T6, class T7, class T8>
147  struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*,
148  T7*, T8*> > {
149  typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*, T7*, T8*> ResultType;
150  static ResultType apply() {
151  return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
152  static_cast<T2*>(0), static_cast<T3*>(0),
153  static_cast<T4*>(0), static_cast<T5*>(0),
154  static_cast<T6*>(0), static_cast<T7*>(0),
155  static_cast<T8*>(0));
156  }
157  };
158 
159  // template<class T0, class T1, class T2, class T3, class T4, class T5,
160  // class T6, class T7, class T8, class T9>
161  // struct NullPointerInitialiser<tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*,
162  // T7*, T8*, T9*> > {
163  // typedef tuple<T0*, T1*, T2*, T3*, T4*, T5*, T6*, T7*, T8*, T9*> ResultType;
164  // static ResultType apply() {
165  // return ResultType(static_cast<T0*>(0), static_cast<T1*>(0),
166  // static_cast<T2*>(0), static_cast<T3*>(0),
167  // static_cast<T4*>(0), static_cast<T5*>(0),
168  // static_cast<T6*>(0), static_cast<T7*>(0),
169  // static_cast<T8*>(0), static_cast<T9*>(0));
170  // }
171  // };
172 #endif // !defined(DOXYGEN)
173 
195  template <template <class> class TypeEvaluator, class TupleType>
196  class ForEachType {
197  static_assert(Std::to_false_type<TupleType>::value, "Attempt to use the "
198  "unspecialized version of ForEachType. ForEachType "
199  "needs to be specialized for each possible tuple "
200  "size. Naturally the number of pre-defined "
201  "specializations is limited arbitrarily. Maybe you "
202  "need to raise this limit by defining some more "
203  "specializations?");
204  struct ImplementationDefined {};
205  public:
207  typedef ImplementationDefined Type;
208  };
209 
210 #ifndef DOXYGEN
211  template <template <class> class TE, class Tuple>
212  struct ForEachType<TE, const Tuple> {
213  typedef const typename ForEachType<TE, Tuple>::Type Type;
214  };
215 
216  template <template <class> class TE>
217  struct ForEachType<TE, tuple<> > {
218  typedef tuple<> Type;
219  };
220 
221  template <template <class> class TE, class T0>
222  struct ForEachType<TE, tuple<T0> > {
223  typedef tuple<typename TE<T0>::Type> Type;
224  };
225 
226  template <template <class> class TE, class T0, class T1>
227  struct ForEachType<TE, tuple<T0, T1> > {
228  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type> Type;
229  };
230 
231  template <template <class> class TE, class T0, class T1, class T2>
232  struct ForEachType<TE, tuple<T0, T1, T2> > {
233  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
234  typename TE<T2>::Type> Type;
235  };
236 
237  template <template <class> class TE, class T0, class T1, class T2, class T3>
238  struct ForEachType<TE, tuple<T0, T1, T2, T3> > {
239  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
240  typename TE<T2>::Type, typename TE<T3>::Type> Type;
241  };
242 
243  template <template <class> class TE, class T0, class T1, class T2, class T3,
244  class T4>
245  struct ForEachType<TE, tuple<T0, T1, T2, T3, T4> > {
246  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
247  typename TE<T2>::Type, typename TE<T3>::Type,
248  typename TE<T4>::Type> Type;
249  };
250 
251  template <template <class> class TE, class T0, class T1, class T2, class T3,
252  class T4, class T5>
253  struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5> > {
254  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
255  typename TE<T2>::Type, typename TE<T3>::Type,
256  typename TE<T4>::Type, typename TE<T5>::Type> Type;
257  };
258 
259  template <template <class> class TE, class T0, class T1, class T2, class T3,
260  class T4, class T5, class T6>
261  struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6> > {
262  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
263  typename TE<T2>::Type, typename TE<T3>::Type,
264  typename TE<T4>::Type, typename TE<T5>::Type,
265  typename TE<T6>::Type> Type;
266  };
267 
268  template <template <class> class TE, class T0, class T1, class T2, class T3,
269  class T4, class T5, class T6, class T7>
270  struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7> > {
271  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
272  typename TE<T2>::Type, typename TE<T3>::Type,
273  typename TE<T4>::Type, typename TE<T5>::Type,
274  typename TE<T6>::Type, typename TE<T7>::Type> Type;
275  };
276 
277  template <template <class> class TE, class T0, class T1, class T2, class T3,
278  class T4, class T5, class T6, class T7, class T8>
279  struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> > {
280  typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
281  typename TE<T2>::Type, typename TE<T3>::Type,
282  typename TE<T4>::Type, typename TE<T5>::Type,
283  typename TE<T6>::Type, typename TE<T7>::Type,
284  typename TE<T8>::Type> Type;
285  };
286 
287  // template <template <class> class TE, class T0, class T1, class T2, class T3,
288  // class T4, class T5, class T6, class T7, class T8, class T9>
289  // struct ForEachType<TE, tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > {
290  // typedef tuple<typename TE<T0>::Type, typename TE<T1>::Type,
291  // typename TE<T2>::Type, typename TE<T3>::Type,
292  // typename TE<T4>::Type, typename TE<T5>::Type,
293  // typename TE<T6>::Type, typename TE<T7>::Type,
294  // typename TE<T8>::Type, typename TE<T9>::Type> Type;
295  // };
296 #endif // !defined(DOXYGEN)
297 
299  //
300  // genericTransformTuple stuff
301  //
302 
303  // genericTransformTuple() needs to be overloaded for each tuple size (we
304  // limit ourselves to tuple_size <= 10 here). For a given tuple size it
305  // needs to be overloaded for all combinations of const and non-const
306  // argument references. (On the one hand, we want to allow modifyable
307  // arguments, so const references alone are not sufficient. On the other
308  // hand, we also want to allow rvalues (literals) as argument, which do not
309  // bind to non-const references.)
310  //
311  // We can half the number of specializations required by introducing a
312  // function genericTransformTupleBackend(), which is overloaded for each
313  // tuple size and for const and non-const tuple arguments; the functor
314  // argument is always given as as (non-const) reference. When
315  // genericTransformTupleBackend() is called, the type of the Functor template
316  // parameter is the deduced as either "SomeType" or "const SomeType",
317  // depending on whether the function argument is a non-const or a const
318  // lvalue of type "SomeType". As explained above, this does not work for
319  // rvalues (i.e. literals).
320  //
321  // To make it work for literals of functors as well, we wrap the call to
322  // genericTransformTupleBackend() in a function genericTransformTuple().
323  // genericTransformTuple() needs to be overloaded for non-const and const
324  // tuples and functors -- 4 overloads only. Inside genericTransformTuple()
325  // the functor is an lvalue no matter whether the argument was an lvalue or
326  // an rvalue. There is no need need to overload genericTransformTuple() for
327  // all tuple sizes -- this is done by the underlying
328  // genericTransformTupleBackend().
329 
330  // genericTransformTupleBackend() is an implementation detail -- hide it
331  // from Doxygen
332 #ifndef DOXYGEN
333  // 0-element tuple
334  // This is a special case: we touch neither the tuple nor the functor, so
335  // const references are sufficient and we don't need to overload
336  template<class Functor>
337  typename ForEachType<Functor::template TypeEvaluator,
338  tuple<> >::Type
339  genericTransformTupleBackend
340  (const tuple<>& t, const Functor& f)
341  {
342  return typename ForEachType<Functor::template TypeEvaluator,
343  tuple<> >::Type
344  ();
345  }
346 
347  // 1-element tuple
348  template<class T0, class Functor>
349  typename ForEachType<Functor::template TypeEvaluator,
350  tuple<T0> >::Type
351  genericTransformTupleBackend
352  (tuple<T0>& t, Functor& f)
353  {
354  return typename ForEachType<Functor::template TypeEvaluator,
355  tuple<T0> >::Type
356  (f(get<0>(t)));
357  }
358  template<class T0, class Functor>
359  typename ForEachType<Functor::template TypeEvaluator,
360  tuple<T0> >::Type
361  genericTransformTupleBackend
362  (const tuple<T0>& t, Functor& f)
363  {
364  return typename ForEachType<Functor::template TypeEvaluator,
365  tuple<T0> >::Type
366  (f(get<0>(t)));
367  }
368 
369  // 2-element tuple
370  template<class T0, class T1, class Functor>
371  typename ForEachType<Functor::template TypeEvaluator,
372  tuple<T0, T1> >::Type
373  genericTransformTupleBackend
374  (tuple<T0, T1>& t, Functor& f)
375  {
376  return typename ForEachType<Functor::template TypeEvaluator,
377  tuple<T0, T1> >::Type
378  (f(get<0>(t)), f(get<1>(t)));
379  }
380  template<class T0, class T1, class Functor>
381  typename ForEachType<Functor::template TypeEvaluator,
382  tuple<T0, T1> >::Type
383  genericTransformTupleBackend
384  (const tuple<T0, T1>& t, Functor& f)
385  {
386  return typename ForEachType<Functor::template TypeEvaluator,
387  tuple<T0, T1> >::Type
388  (f(get<0>(t)), f(get<1>(t)));
389  }
390 
391  // 3-element tuple
392  template<class T0, class T1, class T2, class Functor>
393  typename ForEachType<Functor::template TypeEvaluator,
394  tuple<T0, T1, T2> >::Type
395  genericTransformTupleBackend
396  (tuple<T0, T1, T2>& t, Functor& f)
397  {
398  return typename ForEachType<Functor::template TypeEvaluator,
399  tuple<T0, T1, T2> >::Type
400  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
401  }
402  template<class T0, class T1, class T2, class Functor>
403  typename ForEachType<Functor::template TypeEvaluator,
404  tuple<T0, T1, T2> >::Type
405  genericTransformTupleBackend
406  (const tuple<T0, T1, T2>& t, Functor& f)
407  {
408  return typename ForEachType<Functor::template TypeEvaluator,
409  tuple<T0, T1, T2> >::Type
410  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
411  }
412 
413  // 4-element tuple
414  template<class T0, class T1, class T2, class T3, class Functor>
415  typename ForEachType<Functor::template TypeEvaluator,
416  tuple<T0, T1, T2, T3> >::Type
417  genericTransformTupleBackend
418  (tuple<T0, T1, T2, T3>& t, Functor& f)
419  {
420  return typename ForEachType<Functor::template TypeEvaluator,
421  tuple<T0, T1, T2, T3> >::Type
422  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
423  }
424  template<class T0, class T1, class T2, class T3, class Functor>
425  typename ForEachType<Functor::template TypeEvaluator,
426  tuple<T0, T1, T2, T3> >::Type
427  genericTransformTupleBackend
428  (const tuple<T0, T1, T2, T3>& t, Functor& f)
429  {
430  return typename ForEachType<Functor::template TypeEvaluator,
431  tuple<T0, T1, T2, T3> >::Type
432  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
433  }
434 
435  // 5-element tuple
436  template<class T0, class T1, class T2, class T3, class T4, class Functor>
437  typename ForEachType<Functor::template TypeEvaluator,
438  tuple<T0, T1, T2, T3, T4> >::Type
439  genericTransformTupleBackend
440  (tuple<T0, T1, T2, T3, T4>& t, Functor& f)
441  {
442  return typename ForEachType<Functor::template TypeEvaluator,
443  tuple<T0, T1, T2, T3, T4> >::Type
444  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
445  }
446  template<class T0, class T1, class T2, class T3, class T4, class Functor>
447  typename ForEachType<Functor::template TypeEvaluator,
448  tuple<T0, T1, T2, T3, T4> >::Type
449  genericTransformTupleBackend
450  (const tuple<T0, T1, T2, T3, T4>& t, Functor& f)
451  {
452  return typename ForEachType<Functor::template TypeEvaluator,
453  tuple<T0, T1, T2, T3, T4> >::Type
454  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
455  }
456 
457  // 6-element tuple
458  template<class T0, class T1, class T2, class T3, class T4, class T5,
459  class Functor>
460  typename ForEachType<Functor::template TypeEvaluator,
461  tuple<T0, T1, T2, T3, T4, T5> >::Type
462  genericTransformTupleBackend
463  (tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
464  {
465  return typename ForEachType<Functor::template TypeEvaluator,
466  tuple<T0, T1, T2, T3, T4, T5> >::Type
467  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
468  f(get<5>(t)));
469  }
470  template<class T0, class T1, class T2, class T3, class T4, class T5,
471  class Functor>
472  typename ForEachType<Functor::template TypeEvaluator,
473  tuple<T0, T1, T2, T3, T4, T5> >::Type
474  genericTransformTupleBackend
475  (const tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
476  {
477  return typename ForEachType<Functor::template TypeEvaluator,
478  tuple<T0, T1, T2, T3, T4, T5> >::Type
479  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
480  f(get<5>(t)));
481  }
482 
483  // 7-element tuple
484  template<class T0, class T1, class T2, class T3, class T4, class T5,
485  class T6, class Functor>
486  typename ForEachType<Functor::template TypeEvaluator,
487  tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
488  genericTransformTupleBackend
489  (tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
490  {
491  return typename ForEachType<Functor::template TypeEvaluator,
492  tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
493  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
494  f(get<5>(t)), f(get<6>(t)));
495  }
496  template<class T0, class T1, class T2, class T3, class T4, class T5,
497  class T6, class Functor>
498  typename ForEachType<Functor::template TypeEvaluator,
499  tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
500  genericTransformTupleBackend
501  (const tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
502  {
503  return typename ForEachType<Functor::template TypeEvaluator,
504  tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
505  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
506  f(get<5>(t)), f(get<6>(t)));
507  }
508 
509  // 8-element tuple
510  template<class T0, class T1, class T2, class T3, class T4, class T5,
511  class T6, class T7, class Functor>
512  typename ForEachType<Functor::template TypeEvaluator,
513  tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
514  genericTransformTupleBackend
515  (tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
516  {
517  return typename ForEachType<Functor::template TypeEvaluator,
518  tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
519  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
520  f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
521  }
522  template<class T0, class T1, class T2, class T3, class T4, class T5,
523  class T6, class T7, class Functor>
524  typename ForEachType<Functor::template TypeEvaluator,
525  tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
526  genericTransformTupleBackend
527  (const tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
528  {
529  return typename ForEachType<Functor::template TypeEvaluator,
530  tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
531  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
532  f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
533  }
534 
535  // 9-element tuple
536  template<class T0, class T1, class T2, class T3, class T4, class T5,
537  class T6, class T7, class T8, class Functor>
538  typename ForEachType<Functor::template TypeEvaluator,
539  tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
540  genericTransformTupleBackend
541  (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
542  {
543  return typename ForEachType<Functor::template TypeEvaluator,
544  tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
545  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
546  f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
547  }
548  template<class T0, class T1, class T2, class T3, class T4, class T5,
549  class T6, class T7, class T8, class Functor>
550  typename ForEachType<Functor::template TypeEvaluator,
551  tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
552  genericTransformTupleBackend
553  (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
554  {
555  return typename ForEachType<Functor::template TypeEvaluator,
556  tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
557  (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
558  f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
559  }
560 
561  // // 10-element tuple
562  // template<class T0, class T1, class T2, class T3, class T4, class T5,
563  // class T6, class T7, class T8, class T9, class Functor>
564  // typename ForEachType<Functor::template TypeEvaluator,
565  // tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
566  // genericTransformTupleBackend
567  // (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
568  // {
569  // return typename ForEachType<Functor::template TypeEvaluator,
570  // tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
571  // (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
572  // f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
573  // }
574  // template<class T0, class T1, class T2, class T3, class T4, class T5,
575  // class T6, class T7, class T8, class T9, class Functor>
576  // typename ForEachType<Functor::template TypeEvaluator,
577  // tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
578  // genericTransformTupleBackend
579  // (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
580  // {
581  // return typename ForEachType<Functor::template TypeEvaluator,
582  // tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
583  // (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
584  // f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
585  // }
586 #endif // ! defined(DOXYGEN)
587 
589 
630  template<class Tuple, class Functor>
632  genericTransformTuple(Tuple& t, Functor& f) {
633  return genericTransformTupleBackend(t, f);
634  }
635 #ifndef DOXYGEN
636  template<class Tuple, class Functor>
638  genericTransformTuple(const Tuple& t, Functor& f) {
639  return genericTransformTupleBackend(t, f);
640  }
641  template<class Tuple, class Functor>
643  genericTransformTuple(Tuple& t, const Functor& f) {
644  return genericTransformTupleBackend(t, f);
645  }
646  template<class Tuple, class Functor>
648  genericTransformTuple(const Tuple& t, const Functor& f) {
649  return genericTransformTupleBackend(t, f);
650  }
651 #endif // ! defined(DOXYGEN)
652 
654  //
655  // transformTuple() related stuff
656  //
657 
659 
690  template<template<class> class TE, class A0 = void, class A1 = void,
691  class A2 = void, class A3 = void, class A4 = void, class A5 = void,
692  class A6 = void, class A7 = void, class A8 = void, class A9 = void>
694  A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7; A8& a8;
695  A9& a9;
696 
697  public:
699  template<class T> struct TypeEvaluator : public TE<T> {};
700 
702 
707  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
708  A6& a6_, A7& a7_, A8& a8_, A9& a9_)
709  : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_),
710  a8(a8_), a9(a9_)
711  { }
712 
714 
722  template<class T>
723  typename TE<T>::Type operator()(T& t) const {
724  return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
725  }
726  };
727 
729 
781  template<template<class> class TE, class A0, class A1, class A2, class A3,
782  class A4, class A5, class A6, class A7, class A8, class A9>
783  TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
784  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
785  A6& a6, A7& a7, A8& a8, A9& a9) {
787  (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
788  }
789 
790 #ifndef DOXYGEN
791  // 0 argument
792  template<template<class> class TE>
793  struct TransformTupleFunctor<TE>
794  {
795  template<class T> struct TypeEvaluator : public TE<T> {};
796 
797  template<class T>
798  typename TE<T>::Type operator()(T& t) const {
799  return TE<T>::apply(t);
800  }
801  };
802  template<template<class> class TE>
803  TransformTupleFunctor<TE>
805  return TransformTupleFunctor<TE>
806  ();
807  }
808 
809  // 1 argument
810  template<template<class> class TE, class A0>
811  class TransformTupleFunctor<TE, A0>
812  {
813  A0& a0;
814 
815  public:
816  template<class T> struct TypeEvaluator : public TE<T> {};
817 
818  TransformTupleFunctor(A0& a0_)
819  : a0(a0_)
820  { }
821 
822  template<class T>
823  typename TE<T>::Type operator()(T& t) const {
824  return TE<T>::apply(t, a0);
825  }
826  };
827  template<template<class> class TE, class A0>
828  TransformTupleFunctor<TE, A0>
829  makeTransformTupleFunctor(A0& a0) {
830  return TransformTupleFunctor<TE, A0>
831  (a0);
832  }
833 
834  // 2 argument
835  template<template<class> class TE, class A0, class A1>
836  class TransformTupleFunctor<TE, A0, A1>
837  {
838  A0& a0; A1& a1;
839 
840  public:
841  template<class T> struct TypeEvaluator : public TE<T> {};
842 
843  TransformTupleFunctor(A0& a0_, A1& a1_)
844  : a0(a0_), a1(a1_)
845  { }
846 
847  template<class T>
848  typename TE<T>::Type operator()(T& t) const {
849  return TE<T>::apply(t, a0, a1);
850  }
851  };
852  template<template<class> class TE, class A0, class A1>
853  TransformTupleFunctor<TE, A0, A1>
854  makeTransformTupleFunctor(A0& a0, A1& a1) {
855  return TransformTupleFunctor<TE, A0, A1>
856  (a0, a1);
857  }
858 
859  // 3 arguments
860  template<template<class> class TE, class A0, class A1, class A2>
861  class TransformTupleFunctor<TE, A0, A1, A2>
862  {
863  A0& a0; A1& a1; A2& a2;
864 
865  public:
866  template<class T> struct TypeEvaluator : public TE<T> {};
867 
868  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_)
869  : a0(a0_), a1(a1_), a2(a2_)
870  { }
871 
872  template<class T>
873  typename TE<T>::Type operator()(T& t) const {
874  return TE<T>::apply(t, a0, a1, a2);
875  }
876  };
877  template<template<class> class TE, class A0, class A1, class A2>
878  TransformTupleFunctor<TE, A0, A1, A2>
879  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2) {
880  return TransformTupleFunctor<TE, A0, A1, A2>
881  (a0, a1, a2);
882  }
883 
884  // 4 arguments
885  template<template<class> class TE, class A0, class A1, class A2, class A3>
886  class TransformTupleFunctor<TE, A0, A1, A2, A3>
887  {
888  A0& a0; A1& a1; A2& a2; A3& a3;
889 
890  public:
891  template<class T> struct TypeEvaluator : public TE<T> {};
892 
893  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_)
894  : a0(a0_), a1(a1_), a2(a2_), a3(a3_)
895  { }
896 
897  template<class T>
898  typename TE<T>::Type operator()(T& t) const {
899  return TE<T>::apply(t, a0, a1, a2, a3);
900  }
901  };
902  template<template<class> class TE, class A0, class A1, class A2, class A3>
903  TransformTupleFunctor<TE, A0, A1, A2, A3>
904  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3) {
905  return TransformTupleFunctor<TE, A0, A1, A2, A3>
906  (a0, a1, a2, a3);
907  }
908 
909  // 5 arguments
910  template<template<class> class TE, class A0, class A1, class A2, class A3,
911  class A4>
912  class TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
913  {
914  A0& a0; A1& a1; A2& a2; A3& a3; A4& a4;
915 
916  public:
917  template<class T> struct TypeEvaluator : public TE<T> {};
918 
919  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_)
920  : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_)
921  { }
922 
923  template<class T>
924  typename TE<T>::Type operator()(T& t) const {
925  return TE<T>::apply(t, a0, a1, a2, a3, a4);
926  }
927  };
928  template<template<class> class TE, class A0, class A1, class A2, class A3,
929  class A4>
930  TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
931  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) {
932  return TransformTupleFunctor<TE, A0, A1, A2, A3, A4>
933  (a0, a1, a2, a3, a4);
934  }
935 
936  // 6 arguments
937  template<template<class> class TE, class A0, class A1, class A2, class A3,
938  class A4, class A5>
939  class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
940  {
941  A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5;
942 
943  public:
944  template<class T> struct TypeEvaluator : public TE<T> {};
945 
946  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_)
947  : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_)
948  { }
949 
950  template<class T>
951  typename TE<T>::Type operator()(T& t) const {
952  return TE<T>::apply(t, a0, a1, a2, a3, a4, a5);
953  }
954  };
955  template<template<class> class TE, class A0, class A1, class A2, class A3,
956  class A4, class A5>
957  TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
958  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
959  return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5>
960  (a0, a1, a2, a3, a4, a5);
961  }
962 
963  // 7 arguments
964  template<template<class> class TE, class A0, class A1, class A2, class A3,
965  class A4, class A5, class A6>
966  class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
967  {
968  A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6;
969 
970  public:
971  template<class T> struct TypeEvaluator : public TE<T> {};
972 
973  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
974  A6& a6_)
975  : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_)
976  { }
977 
978  template<class T>
979  typename TE<T>::Type operator()(T& t) const {
980  return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6);
981  }
982  };
983  template<template<class> class TE, class A0, class A1, class A2, class A3,
984  class A4, class A5, class A6>
985  TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
986  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
987  A6& a6) {
988  return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6>
989  (a0, a1, a2, a3, a4, a5, a6);
990  }
991 
992  // 8 arguments
993  template<template<class> class TE, class A0, class A1, class A2, class A3,
994  class A4, class A5, class A6, class A7>
995  class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
996  {
997  A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7;
998 
999  public:
1000  template<class T> struct TypeEvaluator : public TE<T> {};
1001 
1002  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
1003  A6& a6_, A7& a7_)
1004  : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_)
1005  { }
1006 
1007  template<class T>
1008  typename TE<T>::Type operator()(T& t) const {
1009  return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7);
1010  }
1011  };
1012  template<template<class> class TE, class A0, class A1, class A2, class A3,
1013  class A4, class A5, class A6, class A7>
1014  TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
1015  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
1016  A6& a6, A7& a7) {
1017  return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7>
1018  (a0, a1, a2, a3, a4, a5, a6, a7);
1019  }
1020 
1021  // 9 arguments
1022  template<template<class> class TE, class A0, class A1, class A2, class A3,
1023  class A4, class A5, class A6, class A7, class A8>
1024  class TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
1025  {
1026  A0& a0; A1& a1; A2& a2; A3& a3; A4& a4; A5& a5; A6& a6; A7& a7; A8& a8;
1027 
1028  public:
1029  template<class T> struct TypeEvaluator : public TE<T> {};
1030 
1031  TransformTupleFunctor(A0& a0_, A1& a1_, A2& a2_, A3& a3_, A4& a4_, A5& a5_,
1032  A6& a6_, A7& a7_, A8& a8_)
1033  : a0(a0_), a1(a1_), a2(a2_), a3(a3_), a4(a4_), a5(a5_), a6(a6_), a7(a7_),
1034  a8(a8_)
1035  { }
1036 
1037  template<class T>
1038  typename TE<T>::Type operator()(T& t) const {
1039  return TE<T>::apply(t, a0, a1, a2, a3, a4, a5, a6, a7, a8);
1040  }
1041  };
1042  template<template<class> class TE, class A0, class A1, class A2, class A3,
1043  class A4, class A5, class A6, class A7, class A8>
1044  TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
1045  makeTransformTupleFunctor(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
1046  A6& a6, A7& a7, A8& a8) {
1047  return TransformTupleFunctor<TE, A0, A1, A2, A3, A4, A5, A6, A7, A8>
1048  (a0, a1, a2, a3, a4, a5, a6, a7, a8);
1049  }
1050 #endif // ! defined(DOXYGEN)
1051 
1053 
1147  template<template<class> class TypeEvaluator, class Tuple, class A0,
1148  class A1, class A2, class A3, class A4, class A5, class A6,
1149  class A7, class A8, class A9>
1150  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1151  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
1152  A6& a6, A7& a7, A8& a8, A9& a9) {
1153  return genericTransformTuple
1154  ( orig,
1155  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
1156  a7, a8, a9));
1157  }
1158 
1159 #ifndef DOXYGEN
1160  // 0 extra arguments
1161  template<template<class> class TypeEvaluator, class Tuple>
1162  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1163  transformTuple(Tuple& orig) {
1164  return genericTransformTuple
1165  ( orig,
1166  makeTransformTupleFunctor<TypeEvaluator>());
1167  }
1168 
1169  // 1 extra argument
1170  template<template<class> class TypeEvaluator, class Tuple, class A0>
1171  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1172  transformTuple(Tuple& orig, A0& a0) {
1173  return genericTransformTuple
1174  ( orig,
1175  makeTransformTupleFunctor<TypeEvaluator>(a0));
1176  }
1177 
1178  // 2 extra arguments
1179  template<template<class> class TypeEvaluator, class Tuple, class A0,
1180  class A1>
1181  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1182  transformTuple(Tuple& orig, A0& a0, A1& a1) {
1183  return genericTransformTuple
1184  ( orig,
1185  makeTransformTupleFunctor<TypeEvaluator>(a0, a1));
1186  }
1187 
1188  // 3 extra arguments
1189  template<template<class> class TypeEvaluator, class Tuple, class A0,
1190  class A1, class A2>
1191  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1192  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2) {
1193  return genericTransformTuple
1194  ( orig,
1195  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2));
1196  }
1197 
1198  // 4 extra arguments
1199  template<template<class> class TypeEvaluator, class Tuple, class A0,
1200  class A1, class A2, class A3>
1201  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1202  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3) {
1203  return genericTransformTuple
1204  ( orig,
1205  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3));
1206  }
1207 
1208  // 5 extra arguments
1209  template<template<class> class TypeEvaluator, class Tuple, class A0,
1210  class A1, class A2, class A3, class A4>
1211  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1212  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) {
1213  return genericTransformTuple
1214  ( orig,
1215  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4));
1216  }
1217 
1218  // 6 extra arguments
1219  template<template<class> class TypeEvaluator, class Tuple, class A0,
1220  class A1, class A2, class A3, class A4, class A5>
1221  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1222  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) {
1223  return genericTransformTuple
1224  ( orig,
1225  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5));
1226  }
1227 
1228  // 7 extra arguments
1229  template<template<class> class TypeEvaluator, class Tuple, class A0,
1230  class A1, class A2, class A3, class A4, class A5, class A6>
1231  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1232  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
1233  A6& a6) {
1234  return genericTransformTuple
1235  ( orig,
1236  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6));
1237  }
1238 
1239  // 8 extra arguments
1240  template<template<class> class TypeEvaluator, class Tuple, class A0,
1241  class A1, class A2, class A3, class A4, class A5, class A6,
1242  class A7>
1243  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1244  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
1245  A6& a6, A7& a7) {
1246  return genericTransformTuple
1247  ( orig,
1248  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
1249  a7));
1250  }
1251 
1252  // 9 extra arguments
1253  template<template<class> class TypeEvaluator, class Tuple, class A0,
1254  class A1, class A2, class A3, class A4, class A5, class A6,
1255  class A7, class A8>
1256  typename remove_const<typename ForEachType<TypeEvaluator, Tuple>::Type>::type
1257  transformTuple(Tuple& orig, A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
1258  A6& a6, A7& a7, A8& a8) {
1259  return genericTransformTuple
1260  ( orig,
1261  makeTransformTupleFunctor<TypeEvaluator>(a0, a1, a2, a3, a4, a5, a6,
1262  a7, a8));
1263  }
1264 #endif // not defined(DOXYGEN)
1265 
1267  //
1268  // Sample TypeEvaluators
1269  //
1270 
1272 
1276  template<class T>
1278  typedef T& Type;
1279  static Type apply(T& t) { return t; }
1280  };
1281 
1283 
1287  template<class T>
1289  typedef typename remove_reference<T>::type* Type;
1290  static Type apply(T& t) { return &t; }
1291  };
1292 
1293  // Specialization, in case the type is already a reference
1294  template<class T>
1295  struct AddPtrTypeEvaluator<T&> {
1296  typedef typename remove_reference<T>::type* Type;
1297  static Type apply(T& t) { return &t; }
1298  };
1299 
1300  namespace
1301  {
1302  template<int i, typename T1,typename F>
1303  struct Visitor
1304  {
1305  static inline void visit(F& func, T1& t1)
1306  {
1307  func.visit(get<tuple_size<T1>::value-i>(t1));
1308  Visitor<i-1,T1,F>::visit(func, t1);
1309  }
1310  };
1311 
1312  template<typename T1,typename F>
1313  struct Visitor<0,T1,F>
1314  {
1315  static inline void visit(F&, T1&)
1316  {}
1317  };
1318 
1319  template<int i, typename T1, typename T2,typename F>
1320  struct PairVisitor
1321  {
1322  static inline void visit(F& func, T1& t1, T2& t2)
1323  {
1324  func.visit(get<tuple_size<T1>::value-i>(t1), get<tuple_size<T2>::value-i>(t2));
1325  PairVisitor<i-1,T1,T2,F>::visit(func, t1, t2);
1326  }
1327  };
1328 
1329  template<typename T1, typename T2, typename F>
1330  struct PairVisitor<0,T1,T2,F>
1331  {
1332  static inline void visit(F&, T1&, T2&)
1333  {}
1334  };
1335  }
1336 
1371  template <class TupleType>
1373  public:
1376  ForEachValue(TupleType& tuple) : tuple_(tuple) {}
1377 
1380  template <class Functor>
1381  void apply(Functor& f) const {
1382  Visitor<tuple_size<TupleType>::value,TupleType,Functor>::visit(f, tuple_);
1383  }
1384  private:
1385  TupleType& tuple_;
1386  };
1387 
1388  //- Definition ForEachValuePair class
1389  // Assertion: both tuples have the same length and the contained types are
1390  // compatible in the sense of the applied function object
1404  template <class TupleType1, class TupleType2>
1406  public:
1410  ForEachValuePair(TupleType1& t1, TupleType2& t2) :
1411  tuple1_(t1),
1412  tuple2_(t2)
1413  {}
1414 
1417  template <class Functor>
1418  void apply(Functor& f) {
1419  PairVisitor<tuple_size<TupleType1>::value,TupleType1,TupleType2,Functor>
1420  ::visit(f, tuple1_, tuple2_);
1421  }
1422  private:
1423  TupleType1& tuple1_;
1424  TupleType2& tuple2_;
1425  };
1426 
1427  //- Reverse element access
1433  template <int N, class Tuple>
1434  struct AtType {
1435  typedef typename tuple_element<tuple_size<Tuple>::value - N - 1,
1436  Tuple>::type Type;
1437  };
1438 
1446  template <int N>
1447  struct At
1448  {
1449 
1450  template<typename Tuple>
1451  static
1452  typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::NonConstType
1453  get(Tuple& t)
1454  {
1455  return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
1456  }
1457 
1458  template<typename Tuple>
1459  static
1460  typename TupleAccessTraits<typename AtType<N, Tuple>::Type>::ConstType
1461  get(const Tuple& t)
1462  {
1463  return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
1464  }
1465  };
1466 
1473  template <class Tuple>
1475  {
1476  struct Deletor {
1477  template<typename P> void visit(const P& p) { delete p; }
1478  };
1479 
1480  public:
1481  static void apply(Tuple& t) {
1482  static Deletor deletor;
1483  ForEachValue<Tuple>(t).apply(deletor);
1484  }
1485  };
1486 
1487 
1511  template<class Tuple, template<class> class Predicate, std::size_t start = 0,
1512  std::size_t size = tuple_size<Tuple>::value>
1514  public conditional<Predicate<typename tuple_element<start,
1515  Tuple>::type>::value,
1516  integral_constant<std::size_t, start>,
1517  FirstPredicateIndex<Tuple, Predicate, start+1> >::type
1518  {
1519  static_assert(tuple_size<Tuple>::value == size, "The \"size\" "
1520  "template parameter of FirstPredicateIndex is an "
1521  "implementation detail and should never be set "
1522  "explicitly!");
1523  };
1524 
1525 #ifndef DOXYGEN
1526  template<class Tuple, template<class> class Predicate, std::size_t size>
1527  class FirstPredicateIndex<Tuple, Predicate, size, size>
1528  {
1529  static_assert(Std::to_false_type<Tuple>::value, "None of the tuple element "
1530  "types matches the predicate!");
1531  };
1532 #endif // !DOXYGEN
1533 
1543  template<class T>
1544  struct IsType {
1546  template<class U>
1547  struct Predicate : public is_same<T, U> {};
1548  };
1549 
1563  template<class Tuple, class T, std::size_t start = 0>
1565  public FirstPredicateIndex<Tuple, IsType<T>::template Predicate, start>
1566  { };
1567 
1568 
1569 
1576  template< class Tuple, class T>
1578  {
1579  static_assert(Std::to_false_type<Tuple>::value, "Attempt to use the "
1580  "unspecialized version of PushBackTuple. "
1581  "PushBackTuple needs to be specialized for "
1582  "each possible tuple size. Naturally the number of "
1583  "pre-defined specializations is limited arbitrarily. "
1584  "Maybe you need to raise this limit by defining some "
1585  "more specializations?");
1586 
1593  typedef Tuple type;
1594  };
1595 
1596 
1597 #ifndef DOXYGEN
1598 
1599  template<class... TupleArgs, class T>
1600  struct PushBackTuple<typename Dune::tuple<TupleArgs...>, T>
1601  {
1602  typedef typename Dune::tuple<TupleArgs..., T> type;
1603  };
1604 
1605 #endif
1606 
1607 
1608 
1615  template< class Tuple, class T>
1617  {
1618  static_assert(Std::to_false_type<Tuple>::value, "Attempt to use the "
1619  "unspecialized version of PushFrontTuple. "
1620  "PushFrontTuple needs to be specialized for "
1621  "each possible tuple size. Naturally the number of "
1622  "pre-defined specializations is limited arbitrarily. "
1623  "Maybe you need to raise this limit by defining some "
1624  "more specializations?");
1625 
1632  typedef Tuple type;
1633  };
1634 
1635 
1636 #ifndef DOXYGEN
1637 
1638  template<class... TupleArgs, class T>
1639  struct PushFrontTuple<typename Dune::tuple<TupleArgs...>, T>
1640  {
1641  typedef typename Dune::tuple<T, TupleArgs...> type;
1642  };
1643 
1644 #endif
1645 
1646 
1647 
1660  template<
1661  template <class, class> class F,
1662  class Tuple,
1663  class Seed=tuple<>,
1664  int N=tuple_size<Tuple>::value>
1666  {
1667  typedef typename ReduceTuple<F, Tuple, Seed, N-1>::type Accumulated;
1668  typedef typename tuple_element<N-1, Tuple>::type Value;
1669 
1671  typedef typename F<Accumulated, Value>::type type;
1672  };
1673 
1684  template<
1685  template <class, class> class F,
1686  class Tuple,
1687  class Seed>
1688  struct ReduceTuple<F, Tuple, Seed, 0>
1689  {
1691  typedef Seed type;
1692  };
1693 
1694 
1695 
1705  template<class Head, class Tail>
1706  struct JoinTuples
1707  {
1710  };
1711 
1712 
1713 
1722  template<class TupleTuple>
1724  {
1727  };
1728 
1729 }
1730 
1731 #endif
Finding the index of a certain type in a tuple.
Definition: tupleutility.hh:1518
Helper template to clone the type definition of a tuple with the storage types replaced by a user-def...
Definition: tupleutility.hh:196
ImplementationDefined Type
type of the transformed tuple
Definition: tupleutility.hh:207
Extension of ForEachValue to two tuples...
Definition: tupleutility.hh:1405
void apply(Functor &f)
Definition: tupleutility.hh:1418
ForEachValuePair(TupleType1 &t1, TupleType2 &t2)
Definition: tupleutility.hh:1410
Helper template which implements iteration over all storage elements in a tuple.
Definition: tupleutility.hh:1372
ForEachValue(TupleType &tuple)
Constructor.
Definition: tupleutility.hh:1376
void apply(Functor &f) const
Applies a function object to each storage element of the tuple.
Definition: tupleutility.hh:1381
A helper template that initializes a tuple consisting of pointers to NULL.
Definition: tupleutility.hh:34
static ResultType apply()
generate a zero-initialized tuple
Tuple ResultType
export the type of the tuples
Definition: tupleutility.hh:42
Deletes all objects pointed to in a tuple of pointers.
Definition: tupleutility.hh:1475
helper class to implement transformTuple()
Definition: tupleutility.hh:693
TE< T >::Type operator()(T &t) const
call TE<T>::apply(t,args...)
Definition: tupleutility.hh:723
TransformTupleFunctor(A0 &a0_, A1 &a1_, A2 &a2_, A3 &a3_, A4 &a4_, A5 &a5_, A6 &a6_, A7 &a7_, A8 &a8_, A9 &a9_)
constructor
Definition: tupleutility.hh:707
Dune namespace.
Definition: alignment.hh:10
TransformTupleFunctor< TE, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9 > makeTransformTupleFunctor(A0 &a0, A1 &a1, A2 &a2, A3 &a3, A4 &a4, A5 &a5, A6 &a6, A7 &a7, A8 &a8, A9 &a9)
syntactic sugar for creation of TransformTupleFunctor objects
Definition: tupleutility.hh:784
ForEachType< Functor::template TypeEvaluator, Tuple >::Type genericTransformTuple(Tuple &t, Functor &f)
transform a tuple object into another tuple object
Definition: tupleutility.hh:632
remove_const< typename ForEachType< TypeEvaluator, Tuple >::Type >::type transformTuple(Tuple &orig, A0 &a0, A1 &a1, A2 &a2, A3 &a3, A4 &a4, A5 &a5, A6 &a6, A7 &a7, A8 &a8, A9 &a9)
transform a tuple's value according to a user-supplied policy
Definition: tupleutility.hh:1151
TypeEvaluator to turn a type T into a pointer to T
Definition: tupleutility.hh:1288
TypeEvaluator to turn a type T into a reference to T
Definition: tupleutility.hh:1277
Type for reverse element access.
Definition: tupleutility.hh:1434
Reverse element access.
Definition: tupleutility.hh:1448
Find the first occurance of a type in a tuple.
Definition: tupleutility.hh:1566
Flatten a tuple of tuples.
Definition: tupleutility.hh:1724
ReduceTuple< JoinTuples, TupleTuple >::type type
Result of the flatten operation.
Definition: tupleutility.hh:1726
The actual predicate.
Definition: tupleutility.hh:1547
Generator for predicates accepting one particular type.
Definition: tupleutility.hh:1544
Join two tuples.
Definition: tupleutility.hh:1707
ReduceTuple< PushBackTuple, Tail, Head >::type type
Result of the join operation.
Definition: tupleutility.hh:1709
Helper template to append a type to a tuple.
Definition: tupleutility.hh:1578
Tuple type
For all specializations this is the type of a tuple with T appended.
Definition: tupleutility.hh:1585
Helper template to prepend a type to a tuple.
Definition: tupleutility.hh:1617
Tuple type
For all specializations this is the type of a tuple with T prepended.
Definition: tupleutility.hh:1624
Seed type
Result of the reduce operation.
Definition: tupleutility.hh:1691
Apply reduce with meta binary function to template.
Definition: tupleutility.hh:1666
F< Accumulated, Value >::type type
Result of the reduce operation.
Definition: tupleutility.hh:1671
template mapping a type to std::false_type
Definition: type_traits.hh:59
export the TypeEvaluator template class for genericTransformTuple()
Definition: tupleutility.hh:699
Fallback implementation of the std::tuple class.
Traits for type conversions and type information.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)