From 82b95fa5e670d362571ba36c75cf1fffdee0ef40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com>
Date: Tue, 16 Jul 2019 14:22:28 +0200
Subject: [PATCH] Added StaticFor.

---
 src/TNL/Containers/StaticArray1D_impl.h | 197 ------------------
 src/TNL/Containers/StaticArray2D_impl.h | 229 ---------------------
 src/TNL/Containers/StaticArray3D_impl.h | 257 ------------------------
 src/TNL/StaticFor.h                     |  38 ++++
 4 files changed, 38 insertions(+), 683 deletions(-)
 delete mode 100644 src/TNL/Containers/StaticArray1D_impl.h
 delete mode 100644 src/TNL/Containers/StaticArray2D_impl.h
 delete mode 100644 src/TNL/Containers/StaticArray3D_impl.h
 create mode 100644 src/TNL/StaticFor.h

diff --git a/src/TNL/Containers/StaticArray1D_impl.h b/src/TNL/Containers/StaticArray1D_impl.h
deleted file mode 100644
index 2a0a2718f8..0000000000
--- a/src/TNL/Containers/StaticArray1D_impl.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/***************************************************************************
-                          StaticArray1D_impl.h  -  description
-                             -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/param-types.h>
-#include <TNL/Containers/StaticArray.h>
-
-namespace TNL {
-namespace Containers {
-
-template< typename Value >
-__cuda_callable__
-constexpr int StaticArray< 1, Value >::getSize()
-{
-   return Size;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 1, Value >::StaticArray()
-{
-}
-
-template< typename Value >
-   template< typename _unused >
-__cuda_callable__
-inline StaticArray< 1, Value >::StaticArray( const Value v[ Size ] )
-{
-   data[ 0 ] = v[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 1, Value >::StaticArray( const Value& v )
-{
-   data[ 0 ] = v;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 1, Value >::StaticArray( const StaticArray< Size, Value >& v )
-{
-   data[ 0 ] = v[ 0 ];
-}
-
-template< typename Value >
-StaticArray< 1, Value >::StaticArray( const std::initializer_list< Value > &elems)
-{
-   auto it = elems.begin();
-   for( int i = 0; i < getSize(); i++ )
-      data[ i ] = *it++;
-}
-
-template< typename Value >
-String StaticArray< 1, Value >::getType()
-{
-   return String( "Containers::StaticArray< " ) +
-          convertToString( Size ) +
-          String( ", " ) +
-          TNL::getType< Value >() +
-          String( " >" );
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value* StaticArray< 1, Value >::getData()
-{
-   return data;
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value* StaticArray< 1, Value >::getData() const
-{
-   return data;
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 1, Value >::operator[]( int i ) const
-{
-   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
-   TNL_ASSERT_LT( i, Size, "Element index is out of bounds." );
-   return data[ i ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 1, Value >::operator[]( int i )
-{
-   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
-   TNL_ASSERT_LT( i, Size, "Element index is out of bounds." );
-   return data[ i ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 1, Value >::x()
-{
-   return data[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 1, Value >::x() const
-{
-   return data[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 1, Value >& StaticArray< 1, Value >::operator = ( const StaticArray< 1, Value >& array )
-{
-   data[ 0 ] = array[ 0 ];
-   return *this;
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-inline StaticArray< 1, Value >& StaticArray< 1, Value >::operator = ( const Array& array )
-{
-   data[ 0 ] = array[ 0 ];
-   return *this;
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-inline bool StaticArray< 1, Value >::operator == ( const Array& array ) const
-{
-   return( ( int ) Size == ( int ) Array::getSize() && data[ 0 ] == array[ 0 ] );
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-inline bool StaticArray< 1, Value >::operator != ( const Array& array ) const
-{
-   return ! this->operator == ( array );
-}
-
-template< typename Value >
-   template< typename OtherValue >
-__cuda_callable__
-StaticArray< 1, Value >::
-operator StaticArray< 1, OtherValue >() const
-{
-   StaticArray< 1, OtherValue > aux;
-   aux[ 0 ] = data[ 0 ];
-   return aux;
-}
-
-
-template< typename Value >
-__cuda_callable__
-inline void StaticArray< 1, Value >::setValue( const ValueType& val )
-{
-   data[ 0 ] = val;
-}
-
-template< typename Value >
-bool StaticArray< 1, Value >::save( File& file ) const
-{
-   file.save< Value, Value, Devices::Host >( data, Size );
-   return true;
-}
-
-template< typename Value >
-bool StaticArray< 1, Value >::load( File& file)
-{
-   file.load< Value, Value, Devices::Host >( data, Size );
-   return true;
-}
-
-template< typename Value >
-void StaticArray< 1, Value >::sort()
-{
-}
-
-template< typename Value >
-std::ostream& StaticArray< 1, Value >::write( std::ostream& str, const char* separator ) const
-{
-   str << data[ 0 ];
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/StaticArray2D_impl.h b/src/TNL/Containers/StaticArray2D_impl.h
deleted file mode 100644
index 2968bee4a7..0000000000
--- a/src/TNL/Containers/StaticArray2D_impl.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/***************************************************************************
-                          StaticArray2D_impl.h  -  description
-                             -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/param-types.h>
-#include <TNL/Math.h>
-#include <TNL/Containers/StaticArray.h>
-
-namespace TNL {
-namespace Containers {
-
-template< typename Value >
-__cuda_callable__
-constexpr int StaticArray< 2, Value >::getSize()
-{
-   return Size;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 2, Value >::StaticArray()
-{
-}
-
-template< typename Value >
-   template< typename _unused >
-__cuda_callable__
-inline StaticArray< 2, Value >::StaticArray( const Value v[ Size ] )
-{
-   data[ 0 ] = v[ 0 ];
-   data[ 1 ] = v[ 1 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 2, Value >::StaticArray( const Value& v )
-{
-   data[ 0 ] = v;
-   data[ 1 ] = v;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 2, Value >::StaticArray( const Value& v1, const Value& v2 )
-{
-   data[ 0 ] = v1;
-   data[ 1 ] = v2;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 2, Value >::StaticArray( const StaticArray< Size, Value >& v )
-{
-   data[ 0 ] = v[ 0 ];
-   data[ 1 ] = v[ 1 ];
-}
-
-template< typename Value >
-StaticArray< 2, Value >::StaticArray( const std::initializer_list< Value > &elems)
-{
-   auto it = elems.begin();
-   for( int i = 0; i < getSize(); i++ )
-      data[ i ] = *it++;
-}
-
-template< typename Value >
-String StaticArray< 2, Value >::getType()
-{
-   return String( "Containers::StaticArray< " ) +
-          convertToString( Size ) +
-          String( ", " ) +
-          TNL::getType< Value >() +
-          String( " >" );
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value* StaticArray< 2, Value >::getData()
-{
-   return data;
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value* StaticArray< 2, Value >::getData() const
-{
-   return data;
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 2, Value >::operator[]( int i ) const
-{
-   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
-   TNL_ASSERT_LT( i, Size, "Element index is out of bounds." );
-   return data[ i ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 2, Value >::operator[]( int i )
-{
-   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
-   TNL_ASSERT_LT( i, Size, "Element index is out of bounds." );
-   return data[ i ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 2, Value >::x()
-{
-   return data[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 2, Value >::x() const
-{
-   return data[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 2, Value >::y()
-{
-   return data[ 1 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 2, Value >::y() const
-{
-   return data[ 1 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 2, Value >& StaticArray< 2, Value >::operator = ( const StaticArray< 2, Value >& array )
-{
-   data[ 0 ] = array[ 0 ];
-   data[ 1 ] = array[ 1 ];
-   return *this;
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-inline StaticArray< 2, Value >& StaticArray< 2, Value >::operator = ( const Array& array )
-{
-   data[ 0 ] = array[ 0 ];
-   data[ 1 ] = array[ 1 ];
-   return *this;
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-inline bool StaticArray< 2, Value >::operator == ( const Array& array ) const
-{
-   return( ( int ) Size == ( int ) Array::getSize() &&
-           data[ 0 ] == array[ 0 ] &&
-           data[ 1 ] == array[ 1 ] );
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-inline bool StaticArray< 2, Value >::operator != ( const Array& array ) const
-{
-   return ! this->operator == ( array );
-}
-
-template< typename Value >
-   template< typename OtherValue >
-__cuda_callable__
-StaticArray< 2, Value >::
-operator StaticArray< 2, OtherValue >() const
-{
-   StaticArray< 2, OtherValue > aux;
-   aux[ 0 ] = data[ 0 ];
-   aux[ 1 ] = data[ 1 ];
-   return aux;
-}
-
-template< typename Value >
-__cuda_callable__
-inline void StaticArray< 2, Value >::setValue( const ValueType& val )
-{
-   data[ 1 ] = data[ 0 ] = val;
-}
-
-template< typename Value >
-bool StaticArray< 2, Value >::save( File& file ) const
-{
-   file.save< Value, Value, Devices::Host >( data, Size );
-   return true;
-}
-
-template< typename Value >
-bool StaticArray< 2, Value >::load( File& file)
-{
-   file.load< Value, Value, Devices::Host >( data, Size );
-   return true;
-}
-
-template< typename Value >
-void StaticArray< 2, Value >::sort()
-{
-   if( data[ 0 ] > data[ 1 ] )
-      swap( data[ 0 ], data[ 1 ] );
-}
-
-template< typename Value >
-std::ostream& StaticArray< 2, Value >::write( std::ostream& str, const char* separator ) const
-{
-   str << data[ 0 ] << separator << data[ 1 ];
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/Containers/StaticArray3D_impl.h b/src/TNL/Containers/StaticArray3D_impl.h
deleted file mode 100644
index bc00ccc8e6..0000000000
--- a/src/TNL/Containers/StaticArray3D_impl.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/***************************************************************************
-                          StaticArray3D_impl.h  -  description
-                             -------------------
-    begin                : Feb 10, 2014
-    copyright            : (C) 2014 by Tomas Oberhuber
-    email                : tomas.oberhuber@fjfi.cvut.cz
- ***************************************************************************/
-
-/* See Copyright Notice in tnl/Copyright */
-
-#pragma once
-
-#include <TNL/param-types.h>
-#include <TNL/Math.h>
-#include <TNL/Containers/StaticArray.h>
-
-namespace TNL {
-namespace Containers {
-
-template< typename Value >
-__cuda_callable__
-constexpr int StaticArray< 3, Value >::getSize()
-{
-   return Size;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 3, Value >::StaticArray()
-{
-}
-
-template< typename Value >
-   template< typename _unused >
-__cuda_callable__
-inline StaticArray< 3, Value >::StaticArray( const Value v[ Size ] )
-{
-   data[ 0 ] = v[ 0 ];
-   data[ 1 ] = v[ 1 ];
-   data[ 2 ] = v[ 2 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 3, Value >::StaticArray( const Value& v )
-{
-   data[ 0 ] = v;
-   data[ 1 ] = v;
-   data[ 2 ] = v;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 3, Value >::StaticArray( const Value& v1, const Value& v2, const Value& v3 )
-{
-   data[ 0 ] = v1;
-   data[ 1 ] = v2;
-   data[ 2 ] = v3;
-}
-
-template< typename Value >
-__cuda_callable__
-inline StaticArray< 3, Value >::StaticArray( const StaticArray< Size, Value >& v )
-{
-   data[ 0 ] = v[ 0 ];
-   data[ 1 ] = v[ 1 ];
-   data[ 2 ] = v[ 2 ];
-}
-
-template< typename Value >
-StaticArray< 3, Value >::StaticArray( const std::initializer_list< Value > &elems)
-{
-   auto it = elems.begin();
-   for( int i = 0; i < getSize(); i++ )
-      data[ i ] = *it++;
-}
-
-template< typename Value >
-String StaticArray< 3, Value >::getType()
-{
-   return String( "Containers::StaticArray< " ) +
-          convertToString( Size ) +
-          String( ", " ) +
-          TNL::getType< Value >() +
-          String( " >" );
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value* StaticArray< 3, Value >::getData()
-{
-   return data;
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value* StaticArray< 3, Value >::getData() const
-{
-   return data;
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 3, Value >::operator[]( int i ) const
-{
-   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
-   TNL_ASSERT_LT( i, Size, "Element index is out of bounds." );
-   return data[ i ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 3, Value >::operator[]( int i )
-{
-   TNL_ASSERT_GE( i, 0, "Element index must be non-negative." );
-   TNL_ASSERT_LT( i, Size, "Element index is out of bounds." );
-   return data[ i ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 3, Value >::x()
-{
-   return data[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 3, Value >::x() const
-{
-   return data[ 0 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 3, Value >::y()
-{
-   return data[ 1 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 3, Value >::y() const
-{
-   return data[ 1 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline Value& StaticArray< 3, Value >::z()
-{
-   return data[ 2 ];
-}
-
-template< typename Value >
-__cuda_callable__
-inline const Value& StaticArray< 3, Value >::z() const
-{
-   return data[ 2 ];
-}
-template< typename Value >
-__cuda_callable__
-StaticArray< 3, Value >& StaticArray< 3, Value >::operator = ( const StaticArray< 3, Value >& array )
-{
-   data[ 0 ] = array[ 0 ];
-   data[ 1 ] = array[ 1 ];
-   data[ 2 ] = array[ 2 ];
-   return *this;
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-StaticArray< 3, Value >& StaticArray< 3, Value >::operator = ( const Array& array )
-{
-   data[ 0 ] = array[ 0 ];
-   data[ 1 ] = array[ 1 ];
-   data[ 2 ] = array[ 2 ];
-   return *this;
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-bool StaticArray< 3, Value >::operator == ( const Array& array ) const
-{
-   return( ( int ) Size == ( int ) Array::getSize() &&
-           data[ 0 ] == array[ 0 ] &&
-           data[ 1 ] == array[ 1 ] &&
-           data[ 2 ] == array[ 2 ] );
-}
-
-template< typename Value >
-   template< typename Array >
-__cuda_callable__
-bool StaticArray< 3, Value >::operator != ( const Array& array ) const
-{
-   return ! this->operator == ( array );
-}
-
-template< typename Value >
-   template< typename OtherValue >
-__cuda_callable__
-StaticArray< 3, Value >::
-operator StaticArray< 3, OtherValue >() const
-{
-   StaticArray< 3, OtherValue > aux;
-   aux[ 0 ] = data[ 0 ];
-   aux[ 1 ] = data[ 1 ];
-   aux[ 2 ] = data[ 2 ];
-   return aux;
-}
-
-template< typename Value >
-__cuda_callable__
-void StaticArray< 3, Value >::setValue( const ValueType& val )
-{
-   data[ 2 ] = data[ 1 ] = data[ 0 ] = val;
-}
-
-template< typename Value >
-bool StaticArray< 3, Value >::save( File& file ) const
-{
-   file.save< Value, Value, Devices::Host >( data, Size );
-   return true;
-}
-
-template< typename Value >
-bool StaticArray< 3, Value >::load( File& file)
-{
-   file.load< Value, Value, Devices::Host >( data, Size );
-   return true;
-}
-
-template< typename Value >
-void StaticArray< 3, Value >::sort()
-{
-   /****
-    * Bubble sort on three elements
-    */
-   if( data[ 0 ] > data[ 1 ] )
-      swap( data[ 0 ], data[ 1 ] );
-   if( data[ 1 ] > data[ 2 ] )
-      swap( data[ 1 ], data[2  ] );
-   if( data[ 0 ] > data[ 1 ] )
-      swap( data[ 0 ], data[ 1 ] );
-}
-
-template< typename Value >
-std::ostream& StaticArray< 3, Value >::write( std::ostream& str, const char* separator ) const
-{
-   str << data[ 0 ] << separator << data[ 1 ] << separator << data[ 2 ];
-   return str;
-}
-
-} // namespace Containers
-} // namespace TNL
diff --git a/src/TNL/StaticFor.h b/src/TNL/StaticFor.h
new file mode 100644
index 0000000000..1539e05aa5
--- /dev/null
+++ b/src/TNL/StaticFor.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+                          StaticFor.h  -  description
+                             -------------------
+    begin                : Jul 16, 2019
+    copyright            : (C) 2019 by Tomas Oberhuber
+    email                : tomas.oberhuber@fjfi.cvut.cz
+ ***************************************************************************/
+
+/* See Copyright Notice in tnl/Copyright */
+
+#pragma once
+
+#include <TNL/Devices/Cuda.h>
+
+namespace TNL {
+
+template< int Begin, int End >
+struct StaticFor
+{
+    template< typename Function, typename... Args >
+    __cuda_callable__
+    static void exec( const Function& f, Args... args )
+    {
+        static_assert( Begin < End, "Wrong index interval for StaticFor. Being must be lower than end." );
+        f( Begin, args... );
+        StaticFor< Begin + 1, End >::exec( f, args... );
+    };
+};
+
+template< int End >
+struct StaticFor< End, End >
+{
+    template< typename Function, typename... Args >
+    __cuda_callable__
+    static void exec( const Function& f, Args... args ){};
+};
+
+} //namespace TNL
-- 
GitLab