From b91b41d83d9c63b6cfc5d72b11afdd362417c5a3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com>
Date: Sun, 1 Sep 2019 20:52:28 +0200
Subject: [PATCH] Implemented StaticArray::operator= accepting both arrays and
 single StaticArray:::ValueType compatible type.

---
 .../Algorithms/StaticArrayAssignment.h           |  8 +++++---
 src/TNL/Containers/StaticArray.h                 | 16 +++++++++++-----
 src/TNL/Containers/StaticArray.hpp               |  7 ++++---
 src/UnitTests/Containers/StaticArrayTest.cpp     |  9 +++++++++
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/src/TNL/Containers/Algorithms/StaticArrayAssignment.h b/src/TNL/Containers/Algorithms/StaticArrayAssignment.h
index 27077eda2c..3c0e59ce69 100644
--- a/src/TNL/Containers/Algorithms/StaticArrayAssignment.h
+++ b/src/TNL/Containers/Algorithms/StaticArrayAssignment.h
@@ -24,7 +24,7 @@ namespace Algorithms {
       template< typename LeftValue, typename RightValue = LeftValue >
       struct assignArrayFunctor
       {
-         __cuda_callable__ void operator()( int i, LeftValue* data, const RightValue* v ) const
+         __cuda_callable__ void operator()( int i, LeftValue* data, const RightValue& v ) const
          {
             data[ i ] = v[ i ];
          }
@@ -33,7 +33,7 @@ namespace Algorithms {
       template< typename LeftValue, typename RightValue = LeftValue >
       struct assignValueFunctor
       {
-         __cuda_callable__ void operator()( int i, LeftValue* data, const RightValue v ) const
+         __cuda_callable__ void operator()( int i, LeftValue& data, const RightValue& v ) const
          {
             data[ i ] = v;
          }
@@ -52,10 +52,11 @@ template< typename StaticArray,
           typename T >
 struct StaticArrayAssignment< StaticArray, T, true >
 {
+   __cuda_callable__
    static void assign( StaticArray& a, const T& t )
    {
       static_assert( StaticArray::getSize() == T::getSize(), "Cannot assign static arrays with different size." );
-      StaticFor< 0, StaticArray::getSize() >::exec( detail::assignArrayFunctor< StaticArray, T >{}, a, t );
+      StaticFor< 0, StaticArray::getSize() >::exec( detail::assignArrayFunctor< typename StaticArray::ValueType, T >{}, a.getData(), t );
    }
 };
 
@@ -67,6 +68,7 @@ template< typename StaticArray,
           typename T >
 struct StaticArrayAssignment< StaticArray, T, false >
 {
+   __cuda_callable__
    static void assign( StaticArray& a, const T& t )
    {
       StaticFor< 0, StaticArray::getSize() >::exec( detail::assignValueFunctor< StaticArray, T >{}, a, t );
diff --git a/src/TNL/Containers/StaticArray.h b/src/TNL/Containers/StaticArray.h
index d8ed311fc5..94a6a56203 100644
--- a/src/TNL/Containers/StaticArray.h
+++ b/src/TNL/Containers/StaticArray.h
@@ -103,7 +103,6 @@ public:
     */
    static String getType();
 
-
    /**
     * \brief Gets all data of this static array.
     */
@@ -157,17 +156,24 @@ public:
    const Value& z() const;
 
    /**
-    * \brief Assigns another static \e array to this array, replacing its current contents.
+    * \brief Assigns another static \e array to this array.
     */
    __cuda_callable__
    StaticArray< Size, Value >& operator=( const StaticArray< Size, Value >& array );
 
    /**
-    * \brief Assigns another static \e array to this array, replacing its current contents.
+    * \brief Assigns an object \e t of type \e T.
+    * 
+    * T can be:
+    * 
+    * 1. Static linear container implementing operator[] and having the same size.
+    * In this case, \e t is copied to this array elementwise.
+    * 2. An object that can be converted to \e Value type. In this case all elements
+    * are set to \e t.
     */
-   template< typename Array >
+   template< typename T >
    __cuda_callable__
-   StaticArray< Size, Value >& operator=( const Array& array );
+   StaticArray< Size, Value >& operator=( const T& t );
 
    /**
     * \brief This function checks whether this static array is equal to another \e array.
diff --git a/src/TNL/Containers/StaticArray.hpp b/src/TNL/Containers/StaticArray.hpp
index 3b4316d685..b94264a736 100644
--- a/src/TNL/Containers/StaticArray.hpp
+++ b/src/TNL/Containers/StaticArray.hpp
@@ -13,6 +13,7 @@
 #include <TNL/param-types.h>
 #include <TNL/Math.h>
 #include <TNL/Containers/StaticArray.h>
+#include <TNL/Containers/Algorithms/StaticArrayAssignment.h>
 #include <TNL/StaticFor.h>
 
 namespace TNL {
@@ -263,11 +264,11 @@ StaticArray< Size, Value >& StaticArray< Size, Value >::operator=( const StaticA
 }
 
 template< int Size, typename Value >
-   template< typename Array >
+   template< typename T >
 __cuda_callable__
-StaticArray< Size, Value >& StaticArray< Size, Value >::operator=( const Array& array )
+StaticArray< Size, Value >& StaticArray< Size, Value >::operator=( const T& v )
 {
-   StaticFor< 0, Size >::exec( detail::assignArrayFunctor< Value, typename Array::ValueType >{}, data, array.getData() );
+   Algorithms::StaticArrayAssignment< StaticArray, T >::assign( *this, v );
    return *this;
 }
 
diff --git a/src/UnitTests/Containers/StaticArrayTest.cpp b/src/UnitTests/Containers/StaticArrayTest.cpp
index bed2d60ce2..4114b9ce16 100644
--- a/src/UnitTests/Containers/StaticArrayTest.cpp
+++ b/src/UnitTests/Containers/StaticArrayTest.cpp
@@ -216,6 +216,15 @@ TYPED_TEST( StaticArrayTest, AssignmentOperator )
    StaticArray< size, char > u4( 127 );
    u3 = u4;
    EXPECT_TRUE( u3 == u4 );
+
+   // assignment of number
+   u3 = 0.0;
+   for( int i = 0; i < size; i++ )
+      u3[ i ] == 0.0;
+   u3 = 1.0;
+   for( int i = 0; i < size; i++ )
+      u3[ i ] == 1.0;
+
 }
 
 TYPED_TEST( StaticArrayTest, setValue )
-- 
GitLab