[Dune] [PATCH] [FirstTypeIndex, FirstPredicateIndex] Classes to find the index of a particular type in a tuple.

Andreas Dedner dedner at mathematik.uni-freiburg.de
Wed Dec 1 10:46:55 CET 2010


Go ahead

On 11/30/2010 05:24 PM, 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
>    





More information about the Dune mailing list