From 715039282993058cb5819f69357a7fa0ff9c2749 Mon Sep 17 00:00:00 2001
From: Max Kahnt <max.kahnt@fu-berlin.de>
Date: Mon, 9 Oct 2017 12:13:42 +0200
Subject: [PATCH] Add isQuadratic compile-time check for static matrices (and
 scalars).

---
 dune/matrix-vector/traits/CMakeLists.txt |  1 +
 dune/matrix-vector/traits/isquadratic.hh | 41 ++++++++++++++++++++++++
 dune/matrix-vector/traits/utilities.hh   | 17 ++++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 dune/matrix-vector/traits/isquadratic.hh

diff --git a/dune/matrix-vector/traits/CMakeLists.txt b/dune/matrix-vector/traits/CMakeLists.txt
index fceabef..3914b32 100644
--- a/dune/matrix-vector/traits/CMakeLists.txt
+++ b/dune/matrix-vector/traits/CMakeLists.txt
@@ -1,6 +1,7 @@
 #install headers
 install(FILES
   fieldtraits.hh
+  isquadratic.hh
   matrixtraits.hh
   scalartraits.hh
   utilities.hh
diff --git a/dune/matrix-vector/traits/isquadratic.hh b/dune/matrix-vector/traits/isquadratic.hh
new file mode 100644
index 0000000..77d9a80
--- /dev/null
+++ b/dune/matrix-vector/traits/isquadratic.hh
@@ -0,0 +1,41 @@
+#ifndef DUNE_MATRIX_VECTOR_TRAITS_ISQUADRATIC_HH
+#define DUNE_MATRIX_VECTOR_TRAITS_ISQUADRATIC_HH
+
+#include <dune/matrix-vector/traits/utilities.hh>
+
+/**
+ * \file
+ * \brief This may yield incorrect results for types whose ScalarTraits or
+ * MatrixTraits specializations are incomplete. Will report the dimension > 0
+ * in case the type is detected to be symmetric.
+ */
+
+namespace Dune {
+namespace MatrixVector {
+namespace Traits {
+
+template <class, class Enable = void>
+struct IsQuadratic {
+  constexpr static int dimension = 0;
+};
+
+template <class T>
+struct IsQuadratic<T, EnableScalar<T>> {
+  constexpr static int dimension = 1;
+};
+
+template <class T>
+using EnableNonScalarQuadraticMatrix =
+    std::enable_if_t<isMatrix<T>() and (MatrixTraits<T>::rows > 1) and
+                     MatrixTraits<T>::rows == MatrixTraits<T>::cols>;
+
+template <class T>
+struct IsQuadratic<T, EnableNonScalarQuadraticMatrix<T>> {
+  constexpr static int dimension = MatrixTraits<T>::rows;
+};
+
+} // end namespace Traits
+} // end namespace MatrixVector
+} // end namespace Dune
+
+#endif // DUNE_MATRIX_VECTOR_TRAITS_ISQUADRATIC_HH
diff --git a/dune/matrix-vector/traits/utilities.hh b/dune/matrix-vector/traits/utilities.hh
index ecc17b5..1ae672e 100644
--- a/dune/matrix-vector/traits/utilities.hh
+++ b/dune/matrix-vector/traits/utilities.hh
@@ -11,6 +11,9 @@
 #include <dune/matrix-vector/traits/matrixtraits.hh>
 #include <dune/matrix-vector/traits/vectortraits.hh>
 
+// coming below to avoid circular dependency:
+// #include <dune/matrix-vector/traits/isquadratic.hh>
+
 namespace Dune {
 namespace MatrixVector {
 
@@ -82,4 +85,18 @@ constexpr auto isSparseRangeIterable() {
 } // end namespace MatrixVector
 } // end namespace Dune
 
+#include <dune/matrix-vector/traits/isquadratic.hh>
+
+namespace Dune {
+namespace MatrixVector {
+
+template <class T>
+constexpr auto isQuadratic() {
+  return Std::bool_constant<Traits::IsQuadratic<std::decay_t<T>>::dimension>();
+}
+
+} // end namespace MatrixVector
+} // end namespace Dune
+
+
 #endif // DUNE_MATRIX_VECTOR_TRAITS_UTILITIES_HH
-- 
GitLab