From 3c2d0b9a5b922bdaaaa11e4f1aec265b428ae00b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@dune-project.org>
Date: Tue, 23 Aug 2016 19:59:04 +0200
Subject: [PATCH] Add a wrapper storing either a copy or reference

---
 dune/solvers/common/CMakeLists.txt     |   1 +
 dune/solvers/common/copyorreference.hh | 122 +++++++++++++++++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 dune/solvers/common/copyorreference.hh

diff --git a/dune/solvers/common/CMakeLists.txt b/dune/solvers/common/CMakeLists.txt
index fe07b065..3fe13a08 100644
--- a/dune/solvers/common/CMakeLists.txt
+++ b/dune/solvers/common/CMakeLists.txt
@@ -3,6 +3,7 @@ install(FILES
     arithmetic.hh
     boxconstraint.hh
     canignore.hh
+    copyorreference.hh
     defaultbitvector.hh
     genericvectortools.hh
     interval.hh
diff --git a/dune/solvers/common/copyorreference.hh b/dune/solvers/common/copyorreference.hh
new file mode 100644
index 00000000..c130c567
--- /dev/null
+++ b/dune/solvers/common/copyorreference.hh
@@ -0,0 +1,122 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_SOLVERS_COMMON_COPYORREFERENCE_HH
+#define DUNE_SOLVERS_COMMON_COPYORREFERENCE_HH
+
+#include <dune/common/indices.hh>
+#include <dune/common/concept.hh>
+
+#include <dune/solvers/common/defaultbitvector.hh>
+
+
+
+namespace Dune {
+namespace Solvers {
+
+
+/**
+ * \brief A wrapper storing either a copy or reference
+ *
+ * \tparam T Type to be refered to
+ *
+ * If T is of reference type, the wrapper stores a reference
+ * to the passed object. Otherwise it stores a copy.
+ */
+template<class T>
+class CopyOrReference
+{
+public:
+  using Type = std::decay_t<T>;
+
+  constexpr CopyOrReference(const Type& other) :
+    t_(other)
+  {}
+
+  constexpr CopyOrReference(Type&& other) :
+    t_(std::move(other))
+  {}
+
+  constexpr const Type& get() const
+  {
+    return t_;
+  }
+
+  constexpr Type& get()
+  {
+    return t_;
+  }
+
+  constexpr std::true_type hasCopy() const
+  {
+    return {};
+  }
+
+private:
+  Type t_;
+};
+
+
+
+template<class T>
+class CopyOrReference<T&>
+{
+public:
+  using Type = std::decay_t<T>;
+
+  constexpr CopyOrReference(Type& other) :
+    t_(&other)
+  {}
+
+  constexpr const Type& get() const
+  {
+    return *t_;
+  }
+
+  constexpr Type& get()
+  {
+    return *t_;
+  }
+
+  constexpr std::false_type hasCopy() const
+  {
+    return {};
+  }
+
+private:
+  Type* t_;
+};
+
+
+
+template<class T>
+class CopyOrReference<const T&>
+{
+public:
+  using Type = std::decay_t<T>;
+
+  constexpr CopyOrReference(const Type& other) :
+    t_(&other)
+  {}
+
+  constexpr const Type& get() const
+  {
+    return *t_;
+  }
+
+  constexpr std::false_type hasCopy() const
+  {
+    return {};
+  }
+
+private:
+  const Type* t_;
+};
+
+
+
+} // end namespace Solvers
+} // end namespace Dune
+
+
+
+#endif // DUNE_SOLVERS_COMMON_COPYORREFERENCE_HH
-- 
GitLab