[Dune] [Dune-Commit] dune-common r6075 - trunk/dune/common
Oliver Sander
sander at mi.fu-berlin.de
Mon Aug 9 11:41:00 CEST 2010
Hi Jö!
Thanks for all the cleanup. Maybe the file can get a more
meaningful name? I find 'utility.hh' a bit too generic.
best,
Oliver
Am 2010-08-04 17:15, schrieb joe at dune-project.org:
> Author: joe
> Date: 2010-08-04 17:15:35 +0200 (Wed, 04 Aug 2010)
> New Revision: 6075
>
> Modified:
> trunk/dune/common/utility.hh
> Log:
> [genericTransformTuple()] Transform tuple values ?\195?\160 la ForEachType.
>
> Modified: trunk/dune/common/utility.hh
> ===================================================================
> --- trunk/dune/common/utility.hh 2010-08-04 15:15:33 UTC (rev 6074)
> +++ trunk/dune/common/utility.hh 2010-08-04 15:15:35 UTC (rev 6075)
> @@ -196,6 +196,8 @@
> \endcode
> * Here, MyEvaluator is a helper struct that extracts the correct type from
> * the storage types of the tuple defined by the tuple ATuple.
> + *
> + * \sa genericTransformTuple().
> */
> template<template<class> class TypeEvaluator, class TupleType>
> class ForEachType {
> @@ -295,6 +297,361 @@
> };
> #endif // !defined(DOXYGEN)
>
> + //////////////////////////////////////////////////////////////////////
> + //
> + // genericTranformTuple stuff
> + //
> +
> + // genericTranformTuple() needs to be overloaded for each tuple size (we
> + // limit ourselves to tuple_size<= 10 here). For a given tuple size it
> + // needs to be overloaded for all combinations of const and non-const
> + // argument references. (On the one hand, we want to allow modifyable
> + // arguments, so const references alone are not sufficient. On the other
> + // hand, we also want to allow rvalues (literals) as argument, which do not
> + // bind to non-const references.)
> + //
> + // We can half the number of specializations required by introducing a
> + // function genericTransformTupleBackend(), which is overloaded for each
> + // tuple size and for const and non-const tuple arguments; the functor
> + // argument is always given as as (non-const) reference. When
> + // genericTranformTupleBackend() is called, the type of the Functor template
> + // parameter is the deduced as either "SomeType" or "const SomeType",
> + // depending on whether the function argument is a non-const or a const
> + // lvalue of type "SomeType". As explained above, this does not work for
> + // rvalues (i.e. literals).
> + //
> + // To make it work for literals of functors as well, we wrap the call to
> + // genericTransformTupleBackend() in a function genericTransformTuple().
> + // genericTransformTuple() needs to be overloaded for non-const and const
> + // tuples and functors -- 4 overloads only. Inside genericTransformTuple()
> + // the functor is an lvalue no matter whether the argument was an lvalue or
> + // an rvalue. There is no need need to overload genericTransformTuple() for
> + // all tuple sizes -- this is done by the underlying
> + // genericTransformTupleBackend().
> +
> + // genericTransformTupleBackend() is an implementation detail -- hide it
> + // from Doxygen
> +#ifndef DOXYGEN
> + // 0-element tuple
> + // This is a special case: we touch neither the tuple nor the functor, so
> + // const references are sufficient and we don't need to overload
> + template<class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<> >::Type
> + genericTransformTupleBackend
> + (const tuple<>& t, const Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<> >::Type
> + ();
> + }
> +
> + // 1-element tuple
> + template<class T0, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0> >::Type
> + genericTransformTupleBackend
> + (tuple<T0>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0> >::Type
> + (f(get<0>(t)));
> + }
> + template<class T0, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0> >::Type
> + (f(get<0>(t)));
> + }
> +
> + // 2-element tuple
> + template<class T0, class T1, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1> >::Type
> + (f(get<0>(t)), f(get<1>(t)));
> + }
> + template<class T0, class T1, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1> >::Type
> + (f(get<0>(t)), f(get<1>(t)));
> + }
> +
> + // 3-element tuple
> + template<class T0, class T1, class T2, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
> + }
> + template<class T0, class T1, class T2, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)));
> + }
> +
> + // 4-element tuple
> + template<class T0, class T1, class T2, class T3, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)));
> + }
> +
> + // 5-element tuple
> + template<class T0, class T1, class T2, class T3, class T4, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3, T4>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class T4, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3, T4>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)));
> + }
> +
> + // 6-element tuple
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3, T4, T5>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)));
> + }
> +
> + // 7-element tuple
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3, T4, T5, T6>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)));
> + }
> +
> + // 8-element tuple
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class T7, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class T7, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3, T4, T5, T6, T7>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)), f(get<7>(t)));
> + }
> +
> + // 9-element tuple
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class T7, class T8, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class T7, class T8, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)));
> + }
> +
> + // 10-element tuple
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class T7, class T8, class T9, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
> + genericTransformTupleBackend
> + (tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
> + }
> + template<class T0, class T1, class T2, class T3, class T4, class T5,
> + class T6, class T7, class T8, class T9, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
> + genericTransformTupleBackend
> + (const tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, Functor& f)
> + {
> + return typename ForEachType<Functor::template TypeEvaluator,
> + tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::Type
> + (f(get<0>(t)), f(get<1>(t)), f(get<2>(t)), f(get<3>(t)), f(get<4>(t)),
> + f(get<5>(t)), f(get<6>(t)), f(get<7>(t)), f(get<8>(t)), f(get<9>(t)));
> + }
> +#endif // ! defined(DOXYGEN)
> +
> + //! transform a tuple object into another tuple object
> + /**
> + * \code
> +#include<dune/common/utility.hh>
> + * \endcode
> + * This function does for the value of a tuple what ForEachType does for the
> + * type of a tuple: it transforms the value using a user-provided policy
> + * functor.
> + *
> + * \param t The tuple value to transform.
> + * \param f The functor to use to transform the values.
> + *
> + * The functor should have the following form:
> + * \code
> +struct Functor {
> + template<class> struct TypeEvaluator {
> + typedef user-defined Type;
> + };
> +
> + template<class T>
> + typename TypeEvaluator<T>::Type operator()(T& val);
> +
> + template<class T>
> + typename TypeEvaluator<T>::Type operator()(T& val) const;
> +
> + template<class T>
> + typename TypeEvaluator<T>::Type operator()(const T& val);
> +
> + template<class T>
> + typename TypeEvaluator<T>::Type operator()(const T& val) const;
> +};
> + * \endcode
> + * The member class template \c TypeEvaluator should be a class template
> + * suitable as the \c TypeEvaluator template parameter for ForEachType. The
> + * function call operator \c operator() is used to transform the value; only
> + * the signatures of \c operator() which are actually used must be present.
> + *
> + * There are overloaded definitions of genericTransformTuple() wich take
> + * constant tuple and functor arguments so rvalues are permissible as
> + * arguments here. These overloaded definitions are not documented
> + * seperately.
> + */
> + template<class Tuple, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
> + genericTransformTuple(Tuple& t, Functor& f) {
> + return genericTransformTupleBackend(t, f);
> + }
> +#ifndef DOXYGEN
> + template<class Tuple, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
> + genericTransformTuple(const Tuple& t, Functor& f) {
> + return genericTransformTupleBackend(t, f);
> + }
> + template<class Tuple, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
> + genericTransformTuple(Tuple& t, const Functor& f) {
> + return genericTransformTupleBackend(t, f);
> + }
> + template<class Tuple, class Functor>
> + typename ForEachType<Functor::template TypeEvaluator, Tuple>::Type
> + genericTransformTuple(const Tuple& t, const Functor& f) {
> + return genericTransformTupleBackend(t, f);
> + }
> +#endif // ! defined(DOXYGEN)
> +
> namespace
> {
> template<int i, typename T1,typename F>
>
>
> _______________________________________________
> Dune-Commit mailing list
> Dune-Commit at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune-commit
>
--
************************************************************************
* Oliver Sander ** email: sander at mi.fu-berlin.de *
* Freie Universität Berlin ** phone: + 49 (30) 838 75348 *
* Institut für Mathematik ** URL : page.mi.fu-berlin.de/~sander *
* Arnimallee 6 ** -------------------------------------*
* 14195 Berlin, Germany ** Member of MATHEON (www.matheon.de) *
************************************************************************
More information about the Dune
mailing list