From a3996f6540fa2d06dcc919d1d731a9fa68e8d89e Mon Sep 17 00:00:00 2001
From: Max Kahnt <max.kahnt@fu-berlin.de>
Date: Mon, 25 Sep 2017 14:13:55 +0200
Subject: [PATCH] Fork Generic Helper for all Scalars instead of FieldVectors.

The former recursion anchor of the Helper was hardcoded to be
FieldVectors. Now, all non-scalar types are treated hierarchically
and the actual action is only performed on scalars.
---
 dune/matrix-vector/genericvectortools.hh | 37 +++++++++++-------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/dune/matrix-vector/genericvectortools.hh b/dune/matrix-vector/genericvectortools.hh
index 4b753e5..50744db 100644
--- a/dune/matrix-vector/genericvectortools.hh
+++ b/dune/matrix-vector/genericvectortools.hh
@@ -17,7 +17,7 @@ namespace Dune {
 namespace MatrixVector {
 namespace Generic { // TODO change namespace name
 
-template <class Vector>
+template <class Vector, typename Enable = void>
 struct Helper;
 
 //! Write vector to given stream
@@ -38,8 +38,9 @@ void truncate(Vector& v, const BitVector& tr) {
   Helper<Vector>::truncate(v, tr);
 }
 
+//! recursion helper for scalars nested in iterables (vectors)
 template <class Vector>
-struct Helper {
+struct Helper<Vector, typename std::enable_if_t<not IsNumber<Vector>::value>> {
   static void writeBinary(std::ostream& s, const Vector& v) {
     Hybrid::forEach(v, [&s](auto&& vi) { Generic::writeBinary(s, vi); });
   }
@@ -50,31 +51,27 @@ struct Helper {
 
   template <class BitVector>
   static void truncate(Vector& v, const BitVector& tr) {
-    sparseRangeFor(v, [&tr](auto&& vi, auto&& i) {
-      Generic::truncate(vi, tr[i]);
-    });
+    sparseRangeFor(
+        v, [&tr](auto&& vi, auto&& i) { Generic::truncate(vi, tr[i]); });
   }
 };
 
-template <class Field, int n>
-struct Helper<FieldVector<Field, n>> {
-  using Vector = FieldVector<Field, n>;
-
-  static void writeBinary(std::ostream& s, const Vector& v) {
-    for (auto&& vi : v)
-      s.write(reinterpret_cast<const char*>(&vi), sizeof(Field));
+//! recursion anchors for scalars
+template <class Scalar>
+struct Helper<Scalar, typename std::enable_if_t<IsNumber<Scalar>::value>> {
+  static void writeBinary(std::ostream& s, const Scalar& v) {
+    s.write(reinterpret_cast<const char*>(&v), sizeof(Scalar));
   }
 
-  static void readBinary(std::ostream& s, Vector& v) {
-    for (auto&& vi : v)
-      s.write(reinterpret_cast<char*>(&vi), sizeof(Field));
+  static void readBinary(std::istream& s, Scalar& v) {
+    for(auto&& vi: v)
+      s.read(reinterpret_cast<char*>(&v), sizeof(Field));
   }
 
-  template<class BitVector>
-  static void truncate(Vector& v, const BitVector& tr) {
-    for (auto it = v.begin(), end = v.end(); it != end; ++it)
-      if(tr[it.index()])
-        *it = 0;
+  template <class BitVector>
+  static void truncate(Scalar& v, const BitVector& tr) {
+    if (tr)
+      v = 0;
   }
 };
 
-- 
GitLab