dune-common  2.2.0
tupleutility.hh
Go to the documentation of this file.
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set ts=8 sw=2 et sts=2:
3 
4 #ifndef DUNE_TUPLE_UTILITY_HH
5 #define DUNE_TUPLE_UTILITY_HH
6 
7 #include <cstddef>
8 
11 
12 #include "tuples.hh"
13 
14 namespace Dune {
15 
33  template <class Tuple>
35  dune_static_assert(AlwaysFalse<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  dune_static_assert(AlwaysFalse<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>
631  typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
632  genericTransformTuple(Tuple& t, Functor& f) {
633  return genericTransformTupleBackend(t, f);
634  }
635 #ifndef DOXYGEN
636  template<class Tuple, class Functor>
637  typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
638  genericTransformTuple(const Tuple& t, Functor& f) {
639  return genericTransformTupleBackend(t, f);
640  }
641  template<class Tuple, class Functor>
642  typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
643  genericTransformTuple(Tuple& t, const Functor& f) {
644  return genericTransformTupleBackend(t, f);
645  }
646  template<class Tuple, class Functor>
647  typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
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& func, T1& 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& func, T1& t1, T2& 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
1453  get(Tuple& t)
1454  {
1455  return Dune::get<tuple_size<Tuple>::value - N - 1>(t);
1456  }
1457 
1458  template<typename Tuple>
1459  static
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 SelectType<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  dune_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  dune_static_assert(AlwaysFalse<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 
1587  template< class Tuple, class T>
1589  {
1590  dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
1591  "unspecialized version of PushBackTuple. "
1592  "PushBackTuple needs to be specialized for "
1593  "each possible tuple size. Naturally the number of "
1594  "pre-defined specializations is limited arbitrarily. "
1595  "Maybe you need to raise this limit by defining some "
1596  "more specializations?");
1597 
1604  typedef Tuple type;
1605  };
1606 
1607 
1608 #ifndef DOXYGEN
1609 
1610  template<class T>
1611  struct PushBackTuple< Dune::tuple<>, T>
1612  {
1613  typedef typename Dune::tuple<T> type;
1614  };
1615 
1616  template< class T1, class T>
1617  struct PushBackTuple< Dune::tuple<T1>, T>
1618  {
1619  typedef typename Dune::tuple<T1, T> type;
1620  };
1621 
1622  template< class T1, class T2, class T>
1623  struct PushBackTuple< Dune::tuple<T1, T2>, T>
1624  {
1625  typedef typename Dune::tuple<T1, T2, T> type;
1626  };
1627 
1628  template< class T1, class T2, class T3, class T>
1629  struct PushBackTuple< Dune::tuple<T1, T2, T3>, T>
1630  {
1631  typedef typename Dune::tuple<T1, T2, T3, T> type;
1632  };
1633 
1634  template< class T1, class T2, class T3, class T4, class T>
1635  struct PushBackTuple< Dune::tuple<T1, T2, T3, T4>, T>
1636  {
1637  typedef typename Dune::tuple<T1, T2, T3, T4, T> type;
1638  };
1639 
1640  template< class T1, class T2, class T3, class T4, class T5, class T>
1641  struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5>, T>
1642  {
1643  typedef typename Dune::tuple<T1, T2, T3, T4, T5, T> type;
1644  };
1645 
1646  template< class T1, class T2, class T3, class T4, class T5, class T6, class T>
1647  struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6>, T>
1648  {
1650  };
1651 
1652  template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T>
1653  struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7>, T>
1654  {
1656  };
1657 
1658  template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T>
1659  struct PushBackTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, T>
1660  {
1662  };
1663 
1664 #endif
1665 
1666 
1667 
1685  template< class Tuple, class T>
1687  {
1688  dune_static_assert(AlwaysFalse<Tuple>::value, "Attempt to use the "
1689  "unspecialized version of PushFrontTuple. "
1690  "PushFrontTuple needs to be specialized for "
1691  "each possible tuple size. Naturally the number of "
1692  "pre-defined specializations is limited arbitrarily. "
1693  "Maybe you need to raise this limit by defining some "
1694  "more specializations?");
1695 
1702  typedef Tuple type;
1703  };
1704 
1705 
1706 #ifndef DOXYGEN
1707 
1708  template<class T>
1709  struct PushFrontTuple< Dune::tuple<>, T>
1710  {
1711  typedef typename Dune::tuple<T> type;
1712  };
1713 
1714  template< class T1, class T>
1715  struct PushFrontTuple< Dune::tuple<T1>, T>
1716  {
1717  typedef typename Dune::tuple<T, T1> type;
1718  };
1719 
1720  template< class T1, class T2, class T>
1721  struct PushFrontTuple< Dune::tuple<T1, T2>, T>
1722  {
1723  typedef typename Dune::tuple<T, T1, T2> type;
1724  };
1725 
1726  template< class T1, class T2, class T3, class T>
1727  struct PushFrontTuple< Dune::tuple<T1, T2, T3>, T>
1728  {
1729  typedef typename Dune::tuple<T, T1, T2, T3> type;
1730  };
1731 
1732  template< class T1, class T2, class T3, class T4, class T>
1733  struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4>, T>
1734  {
1735  typedef typename Dune::tuple<T, T1, T2, T3, T4> type;
1736  };
1737 
1738  template< class T1, class T2, class T3, class T4, class T5, class T>
1739  struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5>, T>
1740  {
1741  typedef typename Dune::tuple<T, T1, T2, T3, T4, T5> type;
1742  };
1743 
1744  template< class T1, class T2, class T3, class T4, class T5, class T6, class T>
1745  struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6>, T>
1746  {
1748  };
1749 
1750  template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T>
1751  struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7>, T>
1752  {
1754  };
1755 
1756  template< class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T>
1757  struct PushFrontTuple< Dune::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, T>
1758  {
1760  };
1761 
1762 #endif
1763 
1764 
1765 
1778  template<
1779  template <class, class> class F,
1780  class Tuple,
1781  class Seed=tuple<>,
1782  int N=tuple_size<Tuple>::value>
1784  {
1785  typedef typename ReduceTuple<F, Tuple, Seed, N-1>::type Accumulated;
1786  typedef typename tuple_element<N-1, Tuple>::type Value;
1787 
1789  typedef typename F<Accumulated, Value>::type type;
1790  };
1791 
1802  template<
1803  template <class, class> class F,
1804  class Tuple,
1805  class Seed>
1806  struct ReduceTuple<F, Tuple, Seed, 0>
1807  {
1809  typedef Seed type;
1810  };
1811 
1812 
1813 
1823  template<class Head, class Tail>
1824  struct JoinTuples
1825  {
1828  };
1829 
1830 
1831 
1840  template<class TupleTuple>
1842  {
1845  };
1846 
1847 }
1848 
1849 #endif