From 3019af0087f6dd647ef03d915dfb5351c1059361 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 5 Apr 2018 19:25:40 +0200
Subject: [PATCH] Improvements to TinyVector One can write for instance
 TinyVector<3> x = zero; TinyVector<2> y(1,0);

Added Types.hpp which defines
- zero
- identity
---
 algebra/TinyVector.hpp | 44 +++++++++++++++++++++++++++++++-----------
 main.cpp               |  6 ++++--
 utils/Types.hpp        | 10 ++++++++++
 3 files changed, 47 insertions(+), 13 deletions(-)
 create mode 100644 utils/Types.hpp

diff --git a/algebra/TinyVector.hpp b/algebra/TinyVector.hpp
index 4dec9f1a8..d2a30abf1 100644
--- a/algebra/TinyVector.hpp
+++ b/algebra/TinyVector.hpp
@@ -4,6 +4,8 @@
 #include <cassert>
 #include <iostream>
 
+#include <Types.hpp>
+
 template <size_t N, typename T=double>
 class TinyVector
 {
@@ -11,6 +13,18 @@ private:
   T m_values[N];
   static_assert((N>0),"TinyVector size must be strictly positive");
 
+  void _unpackVariadicInput(const T& t)
+  {
+    m_values[N-1] = t;
+  }
+
+  template <typename... Args>
+  void _unpackVariadicInput(const T& t, Args&&... args)
+  {
+    m_values[N-1-sizeof...(args)] = t;
+    this->_unpackVariadicInput(args...);
+  }
+
 public:
   KOKKOS_INLINE_FUNCTION
   T operator,(const TinyVector& v)
@@ -81,15 +95,6 @@ public:
     return *this;
   }
 
-  KOKKOS_INLINE_FUNCTION
-  TinyVector& operator=(const T& t)
-  {
-    for (size_t i=0; i<N; ++i) {
-      m_values[i] = t;
-    }
-    return *this;
-  }
-
   KOKKOS_INLINE_FUNCTION
   T& operator[](const size_t& i)
   {
@@ -104,6 +109,15 @@ public:
     return m_values[i];
   }
 
+  KOKKOS_INLINE_FUNCTION
+  TinyVector& operator=(const ZeroType& z)
+  {
+    for (size_t i=0; i<N; ++i) {
+      m_values[i] = 0;
+    }
+    return *this;
+  }
+
   KOKKOS_INLINE_FUNCTION
   const TinyVector& operator=(const TinyVector& v)
   {
@@ -116,6 +130,14 @@ public:
   KOKKOS_INLINE_FUNCTION
   TinyVector& operator=(TinyVector&& v) = default;
 
+  template <typename... Args>
+  KOKKOS_INLINE_FUNCTION
+  TinyVector(const T& t, Args&&... args)
+  {
+    static_assert(sizeof...(args)==N-1, "wrong number of parameters");
+    this->_unpackVariadicInput(t, args...);
+  }
+
   KOKKOS_INLINE_FUNCTION
   TinyVector()
   {
@@ -123,10 +145,10 @@ public:
   }
 
   KOKKOS_INLINE_FUNCTION
-  TinyVector(const T& t)
+  TinyVector(const ZeroType& z)
   {
     for (size_t i=0; i<N; ++i) {
-      m_values[i] = t;
+      m_values[i] = 0;
     }
   }
 
diff --git a/main.cpp b/main.cpp
index f2a8f173c..8db2c2a5f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -133,9 +133,11 @@ int main(int argc, char *argv[])
 	      << rang::style::reset << '\n';
   }
 
-  TinyVector<2> x=1;
-  TinyVector<2> y=2;
+  TinyVector<2> x=zero;
+  TinyVector<2> y{1,2};
 
+  x=TinyVector<2>{3,2};
+  
   std::cout << x << "-" << y << "=" << x-y << std::endl;
   std::cout << x << "+" << y << "=" << x+y << std::endl;
   std::cout << "3*" << x << '=' << 3*x << std::endl;
diff --git a/utils/Types.hpp b/utils/Types.hpp
new file mode 100644
index 000000000..2be426083
--- /dev/null
+++ b/utils/Types.hpp
@@ -0,0 +1,10 @@
+#ifndef TYPES_HPP
+#define TYPES_HPP
+
+enum class ZeroType { zero };
+constexpr ZeroType zero=zero;
+
+enum class IdentityType { identity };
+constexpr IdentityType identity=identity;
+
+#endif // TYPES_HPP
-- 
GitLab