From 38d5ba56375e36aaefaf234c2e809d47b5a3e1b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@dune-project.org>
Date: Mon, 12 Sep 2016 13:55:01 +0200
Subject: [PATCH] Add the TupleVector class

The TupleVector class is a multitype container without
algebraic operations. It relates to Dune::MultiTypeBlockVector
like std::vector relates to Dune::BlockVector. This is achived
by augmenting std::tuple by the following:
* operator[] for Dune::index_constant aruments
* static size()

You can now write code like this which will work for multitype
and classic vector like containers:

using namespace Dune::Hybrid;
forEach(integralRange(size(v)), [&](auto i) {
    v[i] = i;
});

Notice that TupleVector was already present as implementation detail
of two tests in dune-common and that dune-functions and dune-solvers
also both contained their own variants
---
 dune/common/CMakeLists.txt |  1 +
 dune/common/tuplevector.hh | 85 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)
 create mode 100644 dune/common/tuplevector.hh

diff --git a/dune/common/CMakeLists.txt b/dune/common/CMakeLists.txt
index 9c689c698..129974b79 100644
--- a/dune/common/CMakeLists.txt
+++ b/dune/common/CMakeLists.txt
@@ -97,6 +97,7 @@ install(FILES
         timer.hh
         tuples.hh
         tupleutility.hh
+        tuplevector.hh
         typelist.hh
         typetraits.hh
         typeutilities.hh
diff --git a/dune/common/tuplevector.hh b/dune/common/tuplevector.hh
new file mode 100644
index 000000000..b43fee60d
--- /dev/null
+++ b/dune/common/tuplevector.hh
@@ -0,0 +1,85 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_COMMON_TUPLEVECTOR_HH
+#define DUNE_COMMON_TUPLEVECTOR_HH
+
+#include <tuple>
+#include <utility>
+
+#include <dune/common/indices.hh>
+
+
+
+/**
+ * \file
+ * \brief Provides the TupleVector class that augments std::tuple by operator[]
+ * \author Carsten Gräser
+ */
+
+namespace Dune
+{
+
+
+
+/**
+ * \brief A class augmenting std::tuple by element access via operator[]
+ *
+ * \ingroup Utilities
+ */
+template<class... T>
+class TupleVector : public std::tuple<T...>
+{
+  using Base = std::tuple<T...>;
+
+public:
+
+  /** \brief Construct from a set of arguments
+   */
+  template<class... TT>
+  constexpr TupleVector(TT&&... tt) :
+    Base(std::forward<TT>(tt)...)
+  {}
+
+  /** \brief Default constructor
+   */
+  constexpr TupleVector()
+  {}
+
+  /** \brief Const access to the tuple elements
+   */
+  template<std::size_t i>
+  constexpr decltype(auto) operator[](const Dune::index_constant<i>&) const
+  {
+    return std::get<i>(*this);
+  }
+
+  /** \brief Non-const access to the tuple elements
+   */
+  template<std::size_t i>
+  decltype(auto) operator[](const Dune::index_constant<i>&)
+  {
+    return std::get<i>(*this);
+  }
+
+  /** \brief Number of elements of the tuple */
+  static constexpr std::size_t size()
+  {
+    return std::tuple_size<Base>::value;
+  }
+};
+
+
+
+template<class... T>
+constexpr auto makeTupleVector(T&&... t)
+{
+  // The std::decay_t<T> is is a slight simplification,
+  // because std::reference_wrapper needs special care.
+  return TupleVector<std::decay_t<T>...>(std::forward<T>(t)...);
+}
+
+
+
+}  // namespace Dune
+
+#endif // DUNE_COMMON_TUPLEVECTOR_HH
-- 
GitLab