From 65e5d0f8d65bef39480bbf9e4b621ee4eb0aca6d Mon Sep 17 00:00:00 2001
From: Philip Trettner <Philip.Trettner@rwth-aachen.de>
Date: Mon, 28 Jan 2019 07:53:24 +0100
Subject: [PATCH] assignment ops

---
 README.md                           |  1 +
 src/tg/detail/macros.hh             | 16 ++++++++++++++++
 src/tg/detail/operators/ops_pos.hh  | 11 +++++++++++
 src/tg/detail/operators/ops_size.hh | 11 +++++++++++
 src/tg/detail/operators/ops_vec.hh  | 12 ++++++++++++
 5 files changed, 51 insertions(+)

diff --git a/README.md b/README.md
index fde6435..5b9e9e5 100644
--- a/README.md
+++ b/README.md
@@ -78,3 +78,4 @@ None.
 
 * Benchmark how compile times are affected by includes / templates
 * Add tests that verify optimal assembly generated
+* Fractional and bigint data types
diff --git a/src/tg/detail/macros.hh b/src/tg/detail/macros.hh
index 6bba9d3..cd9d727 100644
--- a/src/tg/detail/macros.hh
+++ b/src/tg/detail/macros.hh
@@ -215,3 +215,19 @@
         return ((a.TG_IMPL_MEMBER(TYPE_A, 0) OP b.TG_IMPL_MEMBER(TYPE_B, 0))REDUCE(a.TG_IMPL_MEMBER(TYPE_A, 1) OP b.TG_IMPL_MEMBER(TYPE_B, 1)))REDUCE( \
             (a.TG_IMPL_MEMBER(TYPE_A, 2) OP b.TG_IMPL_MEMBER(TYPE_B, 2))REDUCE(a.TG_IMPL_MEMBER(TYPE_A, 3) OP b.TG_IMPL_MEMBER(TYPE_B, 3)));           \
     }
+
+#define TG_IMPL_DEFINE_ASSIGNMENT_OP(TYPE_THIS, TYPE_THAT, OP)                                                                                    \
+    template <int D, class ScalarA, class ScalarB>                                                                                                \
+    constexpr auto operator OP##=(TYPE_THIS<D, ScalarA>& lhs, TYPE_THAT<D, ScalarB> const& rhs)->decltype(TYPE_THIS<D, ScalarA>(lhs OP rhs), lhs) \
+    {                                                                                                                                             \
+        lhs = TYPE_THIS<D, ScalarA>(lhs OP rhs);                                                                                                  \
+        return lhs;                                                                                                                               \
+    }
+
+#define TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(TYPE_THIS, OP)                                                                          \
+    template <int D, class ScalarA, class ScalarB>                                                                                  \
+    constexpr auto operator OP##=(TYPE_THIS<D, ScalarA>& lhs, ScalarB const& rhs)->decltype(TYPE_THIS<D, ScalarA>(lhs OP rhs), lhs) \
+    {                                                                                                                               \
+        lhs = TYPE_THIS<D, ScalarA>(lhs OP rhs);                                                                                    \
+        return lhs;                                                                                                                 \
+    }
diff --git a/src/tg/detail/operators/ops_pos.hh b/src/tg/detail/operators/ops_pos.hh
index a8cb465..d11b019 100644
--- a/src/tg/detail/operators/ops_pos.hh
+++ b/src/tg/detail/operators/ops_pos.hh
@@ -29,4 +29,15 @@ TG_IMPL_DEFINE_BINARY_OP_SCALAR(pos, +);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR(pos, *);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR_DIV(pos);
 
+// assignment ops
+TG_IMPL_DEFINE_ASSIGNMENT_OP(pos, vec, +);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(pos, vec, -);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(pos, size, *);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(pos, size, /);
+
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(pos, +);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(pos, -);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(pos, *);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(pos, /);
+
 } // namespace tg
diff --git a/src/tg/detail/operators/ops_size.hh b/src/tg/detail/operators/ops_size.hh
index b78e44b..5b71a65 100644
--- a/src/tg/detail/operators/ops_size.hh
+++ b/src/tg/detail/operators/ops_size.hh
@@ -23,4 +23,15 @@ TG_IMPL_DEFINE_BINARY_OP_SCALAR(size, -);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR(size, +);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR(size, *);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR_DIV(size);
+
+// assignment ops
+TG_IMPL_DEFINE_ASSIGNMENT_OP(size, size, +);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(size, size, -);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(size, size, *);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(size, size, /);
+
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(size, +);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(size, -);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(size, *);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(size, /);
 } // namespace tg
diff --git a/src/tg/detail/operators/ops_vec.hh b/src/tg/detail/operators/ops_vec.hh
index ff0d992..964c3dd 100644
--- a/src/tg/detail/operators/ops_vec.hh
+++ b/src/tg/detail/operators/ops_vec.hh
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "../../types/vec.hh"
+#include "../macros.hh"
 #include "../traits.hh"
 
 namespace tg
@@ -22,4 +23,15 @@ TG_IMPL_DEFINE_BINARY_OP_SCALAR(vec, -);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR(vec, +);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR(vec, *);
 TG_IMPL_DEFINE_BINARY_OP_SCALAR_DIV(vec);
+
+// assignment ops
+TG_IMPL_DEFINE_ASSIGNMENT_OP(vec, vec, +);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(vec, vec, -);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(vec, size, *);
+TG_IMPL_DEFINE_ASSIGNMENT_OP(vec, size, /);
+
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(vec, +);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(vec, -);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(vec, *);
+TG_IMPL_DEFINE_ASSIGNMENT_OP_SCALAR(vec, /);
 } // namespace tg
-- 
GitLab