From d7d28bafc6dbec60c7e4c99aa4610d8b15eddc59 Mon Sep 17 00:00:00 2001
From: Philip Trettner <Philip.Trettner@rwth-aachen.de>
Date: Wed, 30 Jan 2019 11:23:42 +0100
Subject: [PATCH] more basic mat

---
 src/tg/detail/functions.hh      |  1 +
 src/tg/detail/functions/diag.hh | 29 +++++++++++++
 src/tg/detail/special_values.hh | 73 +++++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 src/tg/detail/functions/diag.hh

diff --git a/src/tg/detail/functions.hh b/src/tg/detail/functions.hh
index a6517cc..570750c 100644
--- a/src/tg/detail/functions.hh
+++ b/src/tg/detail/functions.hh
@@ -9,6 +9,7 @@
 #include "functions/coordinates.hh"
 #include "functions/cross.hh"
 #include "functions/data_ptr.hh"
+#include "functions/diag.hh"
 #include "functions/direction.hh"
 #include "functions/distance.hh"
 #include "functions/dot.hh"
diff --git a/src/tg/detail/functions/diag.hh b/src/tg/detail/functions/diag.hh
new file mode 100644
index 0000000..7f02a46
--- /dev/null
+++ b/src/tg/detail/functions/diag.hh
@@ -0,0 +1,29 @@
+#pragma once
+
+#include "../../types/mat.hh"
+#include "../scalars/scalar_math.hh"
+#include "../utility.hh"
+
+namespace tg
+{
+template <int C, int R, class ScalarT, class = enable_if<min(C, R) == 1>>
+constexpr vec<1, ScalarT> diag(mat<C, R, ScalarT> const& m)
+{
+    return {m[0][0]};
+}
+template <int C, int R, class ScalarT, class = enable_if<min(C, R) == 2>>
+constexpr vec<2, ScalarT> diag(mat<C, R, ScalarT> const& m)
+{
+    return {m[0][0], m[1][1]};
+}
+template <int C, int R, class ScalarT, class = enable_if<min(C, R) == 3>>
+constexpr vec<3, ScalarT> diag(mat<C, R, ScalarT> const& m)
+{
+    return {m[0][0], m[1][1], m[2][2]};
+}
+template <int C, int R, class ScalarT, class = enable_if<min(C, R) == 4>>
+constexpr vec<4, ScalarT> diag(mat<C, R, ScalarT> const& m)
+{
+    return {m[0][0], m[1][1], m[2][2], m[3][3]};
+}
+} // namespace tg
diff --git a/src/tg/detail/special_values.hh b/src/tg/detail/special_values.hh
index 8ab2f5e..17e159c 100644
--- a/src/tg/detail/special_values.hh
+++ b/src/tg/detail/special_values.hh
@@ -4,6 +4,7 @@
 #include "../types/pos.hh"
 #include "../types/size.hh"
 #include "../types/vec.hh"
+#include "scalars/scalar_math.hh"
 
 /*
  * Special values of certain types:
@@ -124,6 +125,78 @@ template <int C, int R, class ScalarT>
 struct special_values<mat<C, R, ScalarT>>
 {
     static constexpr mat<C, R, ScalarT> ones() { return mat<C, R, ScalarT>() + ScalarT(1); }
+    static constexpr mat<C, R, ScalarT> identity()
+    {
+        mat<C, R, ScalarT> m;
+        mat_set_00(m, ScalarT(1));
+        mat_set_11(m, ScalarT(1));
+        mat_set_22(m, ScalarT(1));
+        mat_set_33(m, ScalarT(1));
+        return m;
+    }
+    static constexpr mat<C, R, ScalarT> diag(ScalarT v)
+    {
+        mat<C, R, ScalarT> m;
+        mat_set_00(m, v);
+        mat_set_11(m, v);
+        mat_set_22(m, v);
+        mat_set_33(m, v);
+        return m;
+    }
+    static constexpr mat<C, R, ScalarT> diag(vec<min(C, R), ScalarT> const& v)
+    {
+        mat<C, R, ScalarT> m;
+        mat_set_00(m, ScalarT(v));
+        mat_set_11(m, ScalarT(v));
+        mat_set_22(m, ScalarT(v));
+        mat_set_33(m, ScalarT(v));
+        return m;
+    }
+
+    static constexpr void mat_set_00(mat<C, R, ScalarT>& m, ScalarT v) { m[0][0] = v; }
+    static constexpr void mat_set_00(mat<C, R, ScalarT>& m, vec<min(C, R), ScalarT> const& v) { m[0][0] = v.x; }
+
+    template <int CC, class = enable_if<CC >= 2 && R >= 2>>
+    static constexpr void mat_set_11(mat<CC, R, ScalarT>& m, ScalarT v)
+    {
+        m[1][1] = v;
+    }
+    template <int CC, class = enable_if<CC >= 2 && R >= 2>>
+    static constexpr void mat_set_11(mat<CC, R, ScalarT>& m, vec<min(C, R), ScalarT> const& v)
+    {
+        m[1][1] = v.y;
+    }
+    static constexpr void mat_set_11(...)
+    { /* nothing */
+    }
+
+    template <int CC, class = enable_if<CC >= 3 && R >= 3>>
+    static constexpr void mat_set_22(mat<CC, R, ScalarT>& m, ScalarT v)
+    {
+        m[2][2] = v;
+    }
+    template <int CC, class = enable_if<CC >= 3 && R >= 3>>
+    static constexpr void mat_set_22(mat<CC, R, ScalarT>& m, vec<min(C, R), ScalarT> const& v)
+    {
+        m[2][2] = v.z;
+    }
+    static constexpr void mat_set_22(...)
+    { /* nothing */
+    }
+
+    template <int CC, class = enable_if<CC >= 4 && R >= 4>>
+    static constexpr void mat_set_33(mat<CC, R, ScalarT>& m, ScalarT v)
+    {
+        m[3][3] = v;
+    }
+    template <int CC, class = enable_if<CC >= 4 && R >= 4>>
+    static constexpr void mat_set_33(mat<CC, R, ScalarT>& m, vec<min(C, R), ScalarT> const& v)
+    {
+        m[3][3] = v.w;
+    }
+    static constexpr void mat_set_33(...)
+    { /* nothing */
+    }
 };
 } // namespace detail
 
-- 
GitLab