[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