[Dune] [PATCH] [FirstTypeIndex, FirstPredicateIndex] Classes to find the index of a particular type in a tuple.
Christian Engwer
christi at uni-hd.de
Wed Dec 1 10:09:17 CET 2010
Sure!
Why do you bother? ;-)
On Tue, Nov 30, 2010 at 06:24:20PM +0100, Jö Fahlke wrote:
> Hi!
>
> I would like to add the two attached classes to dune-common. They can be used
> to search for the index of a type within a tuple.
>
> * FirstTypeIndex looks for the exact type,
> * FirstPredicateIndex looks for a type for which some predicate returns true.
>
> Since this is strictly speaking an interface addition, I thought I better ask
> first. Are there any objecttions? Suggestions for improvements?
>
> Bye,
> Jö.
>
> ---
> dune/common/test/Makefile.am | 3 +
> dune/common/test/tupleutilitytest.cc | 30 ++++++++++++
> dune/common/tupleutility.hh | 83 ++++++++++++++++++++++++++++++++++
> 3 files changed, 116 insertions(+), 0 deletions(-)
> create mode 100644 dune/common/test/tupleutilitytest.cc
>
> diff --git a/dune/common/test/Makefile.am b/dune/common/test/Makefile.am
> index d0b12c0..c14d9e5 100644
> --- a/dune/common/test/Makefile.am
> +++ b/dune/common/test/Makefile.am
> @@ -44,6 +44,7 @@ TESTPROGS = \
> testfassign_fail5 \
> testfassign_fail6 \
> tuplestest \
> + tupleutilitytest \
> utilitytest
>
> # which tests to run
> @@ -104,6 +105,8 @@ shared_ptrtest_SOURCES = shared_ptrtest.cc
>
> tuplestest_SOURCES = tuplestest.cc
>
> +tupleutilitytest_SOURCES = tupleutilitytest.cc
> +
> deprtuplestest_SOURCES = deprtuplestest.cc
>
> streamtest_SOURCES = streamtest.cc
> diff --git a/dune/common/test/tupleutilitytest.cc b/dune/common/test/tupleutilitytest.cc
> new file mode 100644
> index 0000000..d422d74
> --- /dev/null
> +++ b/dune/common/test/tupleutilitytest.cc
> @@ -0,0 +1,30 @@
> +// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
> +// vi: set ts=8 sw=2 et sts=2:
> +
> +#if HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <cstddef>
> +
> +#include <dune/common/static_assert.hh>
> +#include <dune/common/tuples.hh>
> +#include <dune/common/tupleutility.hh>
> +
> +//////////////////////////////////////////////////////////////////////
> +//
> +// check FirstTypeIndex
> +//
> +typedef Dune::tuple<int, unsigned, double> MyTuple;
> +dune_static_assert((Dune::FirstTypeIndex<MyTuple, int>::value == 0),
> + "FirstTypeIndex finds the wrong index for double in "
> + "MyTuple!");
> +dune_static_assert((Dune::FirstTypeIndex<MyTuple, unsigned>::value == 1),
> + "FirstTypeIndex finds the wrong index for double in "
> + "MyTuple!");
> +dune_static_assert((Dune::FirstTypeIndex<MyTuple, double>::value == 2),
> + "FirstTypeIndex finds the wrong index for double in "
> + "MyTuple!");
> +
> +int main() {
> +}
> diff --git a/dune/common/tupleutility.hh b/dune/common/tupleutility.hh
> index 96b5ec4..e840026 100644
> --- a/dune/common/tupleutility.hh
> +++ b/dune/common/tupleutility.hh
> @@ -4,7 +4,10 @@
> #ifndef DUNE_TUPLE_UTILITY_HH
> #define DUNE_TUPLE_UTILITY_HH
>
> +#include <cstddef>
> +
> #include <dune/common/static_assert.hh>
> +#include <dune/common/typetraits.hh>
>
> #include "tuples.hh"
>
> @@ -1492,6 +1495,86 @@ struct TypeEvaluator {
> }
> };
>
> +
> + /**
> + * @brief Finding the index of a certain in a tuple
> + *
> + * \tparam Tuple The tuple type to search in.
> + * \tparam Predicate Predicate which tells FirstPredicateIndex which types
> + * in Tuple to accept. This should be a class template
> + * taking a single type template argument. When
> + * instanciated, it should contain a static member
> + * constant \c value which should be convertible to bool.
> + * A type is accepted if \c value is \c true, otherwise it
> + * is rejected and the next type is tried. Look at IsType
> + * for a sample implementation.
> + * \tparam start First index to try. This can be adjusted to skip
> + * leading tuple elements.
> + * \tparam size This parameter is an implementation detail and should
> + * not be adjusted by the users of this class. It should
> + * always be equal to the size of the tuple.
> + *
> + * This class can search for a type in tuple. It will apply the predicate
> + * to each type in tuple in turn, and set its member constant \c value to
> + * the index of the first type that was accepted by the predicate. If none
> + * of the types are accepted by the predicate, a static_assert is triggered.
> + */
> + template<class Tuple, template<class> class Predicate, std::size_t start = 0,
> + std::size_t size = tuple_size<Tuple>::value>
> + class FirstPredicateIndex :
> + public SelectType<Predicate<typename tuple_element<start,
> + Tuple>::type>::value,
> + integral_constant<std::size_t, start>,
> + FirstPredicateIndex<Tuple, Predicate, start+1> >::Type
> + {
> + dune_static_assert(tuple_size<Tuple>::value == size, "The \"size\" "
> + "template parameter of FirstPredicateIndex is an "
> + "implementation detail and should never be set "
> + "explicitly!");
> + };
> +
> +#ifndef DOXYGEN
> + template<class Tuple, template<class> class Predicate, std::size_t size>
> + class FirstPredicateIndex<Tuple, Predicate, size, size>
> + {
> + dune_static_assert(AlwaysFalse<Tuple>::value, "None of the tuple element "
> + "types matches the predicate!");
> + };
> +#endif // !DOXYGEN
> +
> + /**
> + * @brief Generator for predicates accepting one particular type
> + *
> + * \tparam T The type to accept.
> + *
> + * The generated predicate class is useful together with
> + * FirstPredicateIndex. It will accept exactly the type that is given as
> + * the \c T template parameter.
> + */
> + template<class T>
> + struct IsType {
> + //! @brief The actual predicate
> + template<class U>
> + struct Predicate : public is_same<T, U> {};
> + };
> +
> + /**
> + * @brief Find the first occurance of a type in a tuple
> + *
> + * \tparam Tuple The tuple type to search in.
> + * \tparam T Type to search for.
> + * \tparam start First index to try. This can be adjusted to skip leading
> + * tuple elements.
> + *
> + * This class can search for a particular type in tuple. It will check each
> + * type in the tuple in turn, and set its member constant \c value to the
> + * index of the first occurance of type was found. If the type was not
> + * found, a static_assert is triggered.
> + */
> + template<class Tuple, class T, std::size_t start = 0>
> + struct FirstTypeIndex :
> + public FirstPredicateIndex<Tuple, IsType<T>::template Predicate, start>
> + { };
> }
>
> #endif
> --
> 1.7.2.3
>
> _______________________________________________
> Dune mailing list
> Dune at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune
>
More information about the Dune
mailing list