From c99d82f6b40d9fc216f8efb15e6ac50694c6d160 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz>
Date: Fri, 9 Aug 2019 14:46:17 +0200
Subject: [PATCH] Revised asserts in expression templates

---
 .../Containers/Algorithms/VectorAssignment.h  |  4 ++--
 .../DistributedExpressionTemplates.h          |  8 +++++---
 .../Expressions/ExpressionTemplates.h         | 12 ++++++++---
 .../Expressions/StaticExpressionTemplates.h   | 20 +++++++++----------
 4 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/TNL/Containers/Algorithms/VectorAssignment.h b/src/TNL/Containers/Algorithms/VectorAssignment.h
index 26df5059f4..36829be82a 100644
--- a/src/TNL/Containers/Algorithms/VectorAssignment.h
+++ b/src/TNL/Containers/Algorithms/VectorAssignment.h
@@ -24,7 +24,7 @@ namespace Algorithms {
 template< typename Vector,
           typename T,
           bool hasSubscriptOperator = HasSubscriptOperator< T >::value >
-struct VectorAssignment{};
+struct VectorAssignment;
 
 /**
  * \brief Vector assignment with an operation: +=, -=, *=, /=
@@ -33,7 +33,7 @@ template< typename Vector,
           typename T,
           bool hasSubscriptOperator = HasSubscriptOperator< T >::value,
           bool hasSetSizeMethod = HasSetSizeMethod< T >::value >
-struct VectorAssignmentWithOperation{};
+struct VectorAssignmentWithOperation;
 
 /**
  * \brief Specialization of ASSIGNEMENT with subscript operator
diff --git a/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h b/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h
index 8530874e46..ab53338436 100644
--- a/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h
+++ b/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h
@@ -69,14 +69,16 @@ struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionV
                                                         typename T2::ConstLocalViewType,
                                                         Operation >;
 
-   static_assert( std::is_same< typename T1::DeviceType, typename T2::DeviceType >::value, "Attempt to mix operands allocated on different device types." );
-   static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value, "Attempt to mix static and non-static operands in binary expression templates." );
+   static_assert( std::is_same< typename T1::DeviceType, typename T2::DeviceType >::value,
+                  "Attempt to mix operands which have different DeviceType." );
+   static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value,
+                  "Attempt to mix static and non-static operands in binary expression templates." );
 
    DistributedBinaryExpressionTemplate( const T1& a, const T2& b )
    : op1( a ), op2( b )
    {
       TNL_ASSERT_EQ( op1.getSize(), op2.getSize(),
-                     "Sizes of both operands must be equal." );
+                     "Attempt to mix operands with different sizes." );
       TNL_ASSERT_EQ( op1.getLocalRange(), op2.getLocalRange(),
                      "Distributed expressions are supported only on vectors which are distributed the same way." );
       TNL_ASSERT_EQ( op1.getCommunicationGroup(), op2.getCommunicationGroup(),
diff --git a/src/TNL/Containers/Expressions/ExpressionTemplates.h b/src/TNL/Containers/Expressions/ExpressionTemplates.h
index 110cd4155a..bb8c78e926 100644
--- a/src/TNL/Containers/Expressions/ExpressionTemplates.h
+++ b/src/TNL/Containers/Expressions/ExpressionTemplates.h
@@ -68,11 +68,17 @@ struct BinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, Ve
    using DeviceType = typename T1::DeviceType;
    using IndexType = typename T1::IndexType;
 
-   static_assert( std::is_same< typename T1::DeviceType, typename T2::DeviceType >::value, "Attempt to mix operands allocated on different device types." );
-   static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value, "Attempt to mix static and non-static operands in binary expression templates." );
+   static_assert( std::is_same< typename T1::DeviceType, typename T2::DeviceType >::value,
+                  "Attempt to mix operands which have different DeviceType." );
+   static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value,
+                  "Attempt to mix static and non-static operands in binary expression templates." );
 
    BinaryExpressionTemplate( const T1& a, const T2& b )
-   : op1( a ), op2( b ) {}
+   : op1( a ), op2( b )
+   {
+      TNL_ASSERT_EQ( op1.getSize(), op2.getSize(),
+                     "Attempt to mix operands with different sizes." );
+   }
 
    RealType getElement( const IndexType i ) const
    {
diff --git a/src/TNL/Containers/Expressions/StaticExpressionTemplates.h b/src/TNL/Containers/Expressions/StaticExpressionTemplates.h
index 7d2cd35a64..874dc1a01d 100644
--- a/src/TNL/Containers/Expressions/StaticExpressionTemplates.h
+++ b/src/TNL/Containers/Expressions/StaticExpressionTemplates.h
@@ -62,13 +62,15 @@ template< typename T1,
           template< typename, typename > class Operation >
 struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, VectorExpressionVariable >
 {
-   static_assert( IsStaticArrayType< T1 >::value, "Left-hand side operand of static expression is not static, i.e. based on static vector." );
-   static_assert( IsStaticArrayType< T2 >::value, "Right-hand side operand of static expression is not static, i.e. based on static vector." );
    using RealType = decltype( Operation< typename T1::RealType, typename T2::RealType >::
                               evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) );
 
-   static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value, "Attempt to mix static and non-static operands in binary expression templates" );
-   static_assert( T1::getSize() == T2::getSize(), "Attempt to mix static operands with different sizes." );
+   static_assert( IsStaticArrayType< T1 >::value,
+                  "Left-hand side operand of static expression is not static, i.e. based on static vector." );
+   static_assert( IsStaticArrayType< T2 >::value,
+                  "Right-hand side operand of static expression is not static, i.e. based on static vector." );
+   static_assert( T1::getSize() == T2::getSize(),
+                  "Attempt to mix static operands with different sizes." );
 
    static constexpr int getSize() { return T1::getSize(); };
 
@@ -79,7 +81,6 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariab
    __cuda_callable__
    RealType operator[]( const int i ) const
    {
-      TNL_ASSERT_LT( i, this->getSize(), "Asking for element with index larger than expression size." );
       return Operation< typename T1::RealType, typename T2::RealType >::evaluate( op1[ i ], op2[ i ] );
    }
 
@@ -111,7 +112,8 @@ template< typename T1,
           template< typename, typename > class Operation >
 struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, ArithmeticVariable  >
 {
-   static_assert( IsStaticArrayType< T1 >::value, "Left-hand side operand of static expression is not static, i.e. based on static vector." );
+   static_assert( IsStaticArrayType< T1 >::value,
+                  "Left-hand side operand of static expression is not static, i.e. based on static vector." );
 
    using RealType = decltype( Operation< typename T1::RealType, T2 >::
                               evaluate( std::declval<T1>()[0], std::declval<T2>() ) );
@@ -125,7 +127,6 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariab
    __cuda_callable__
    RealType operator[]( const int i ) const
    {
-      TNL_ASSERT_LT( i, this->getSize(), "Asking for element with index larger than expression size." );
       return Operation< typename T1::RealType, T2 >::evaluate( op1[ i ], op2 );
    }
 
@@ -157,7 +158,8 @@ template< typename T1,
           template< typename, typename > class Operation >
 struct StaticBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, VectorExpressionVariable  >
 {
-   static_assert( IsStaticArrayType< T2 >::value, "Right-hand side operand of static expression is not static, i.e. based on static vector." );
+   static_assert( IsStaticArrayType< T2 >::value,
+                  "Right-hand side operand of static expression is not static, i.e. based on static vector." );
 
    using RealType = decltype( Operation< T1, typename T2::RealType >::
                               evaluate( std::declval<T1>(), std::declval<T2>()[0] ) );
@@ -171,7 +173,6 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, Ve
    __cuda_callable__
    RealType operator[]( const int i ) const
    {
-      TNL_ASSERT_LT( i, this->getSize(), "Asking for element with index larger than expression size." );
       return Operation< T1, typename T2::RealType >::evaluate( op1, op2[ i ] );
    }
 
@@ -216,7 +217,6 @@ struct StaticUnaryExpressionTemplate< T1, Operation, VectorExpressionVariable >
    __cuda_callable__
    RealType operator[]( const int i ) const
    {
-      TNL_ASSERT_LT( i, this->getSize(), "Asking for element with index larger than expression size." );
       return Operation< typename T1::RealType >::evaluate( operand[ i ] );
    }
 
-- 
GitLab