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

Jö Fahlke jorrit at jorrit.de
Tue Nov 30 18:24:20 CET 2010


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




More information about the Dune mailing list