diff --git a/src/TNL/Containers/VectorExpressions.h b/src/TNL/Containers/VectorExpressions.h index 018144d27f63dc3ffe9d762120bb5026a89ec15c..b0fce83b922fe848aded9fc3d38beea82021f450 100644 --- a/src/TNL/Containers/VectorExpressions.h +++ b/src/TNL/Containers/VectorExpressions.h @@ -691,7 +691,7 @@ template< typename Real, typename Real2 > auto lpNorm( const Containers::Vector< Real, Device, Index, Allocator >& a, const Real2& p ) --> decltype( Containers::Expressions::ExpressionLpNorm( a.getView(), p ) ) +-> decltype( Containers::Expressions::ExpressionLpNorm( a.getConstView(), p ) ) { if( p == 1.0 ) return Containers::Expressions::ExpressionLpNorm( a.getConstView(), p ); diff --git a/src/TNL/Containers/VectorViewExpressions.h b/src/TNL/Containers/VectorViewExpressions.h index 3d62112b83be2b6878136de88ff06fb778d25c2f..417948504874e30115c03ad069e9f5bc5ab58b39 100644 --- a/src/TNL/Containers/VectorViewExpressions.h +++ b/src/TNL/Containers/VectorViewExpressions.h @@ -23,118 +23,131 @@ namespace Containers { //// // Addition -template< typename Real, typename Device, typename Index, typename ET > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Addition > -operator+( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator+( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Addition >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Addition >( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Addition > -operator+( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator+( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Addition >( a, b ); + return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Addition >( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Addition > -operator+( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +auto +operator+( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Addition >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Addition >( a, b ); } //// // Subtraction -template< typename Real, typename Device, typename Index, typename ET > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Subtraction > -operator-( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator-( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Subtraction >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Subtraction >( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Subtraction > -operator-( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator-( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Subtraction >( a, b ); + return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Subtraction >( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Subtraction > -operator-( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +auto +operator-( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Subtraction >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Subtraction >( a, b ); } //// // Multiplication -template< typename Real, typename Device, typename Index, typename ET > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Multiplication > -operator*( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator*( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Multiplication >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Multiplication >( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Multiplication > -operator*( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator*( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Multiplication >( a, b ); + return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Multiplication >( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Multiplication > -operator*( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +auto +operator*( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Multiplication >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Multiplication >( a, b ); } //// // Division -template< typename Real, typename Device, typename Index, typename ET > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Division > -operator/( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator/( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Division >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Division >( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Division > -operator/( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +auto +operator/( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Division >( a, b ); + return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Division >( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Division > -operator/( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +auto +operator/( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Division >( a, b ); + return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Division >( a, b ); } //// // Comparison operations - operator == -template< typename Real, typename Device, typename Index, typename ET > -bool operator==( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator==( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real, Device, Index >, ET >::EQ( a, b ); + return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::EQ( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -bool operator==( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator==( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::Comparison< ET, Containers::VectorView< Real, Device, Index > >::EQ( a, b ); + return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::EQ( a, b ); } template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index > -bool operator==( const Containers::VectorView< Real1, Device1, Index >& a, const Containers::VectorView< Real2, Device2, Index >& b ) +bool +operator==( const VectorView< Real1, Device1, Index >& a, const VectorView< Real2, Device2, Index >& b ) { if( a.getSize() != b.getSize() ) return false; if( a.getSize() == 0 ) return true; - return Containers::Algorithms::ArrayOperations< Device1, Device2 >:: + return Algorithms::ArrayOperations< Device1, Device2 >:: compare( a.getData(), b.getData(), a.getSize() ); @@ -142,26 +155,31 @@ bool operator==( const Containers::VectorView< Real1, Device1, Index >& a, const //// // Comparison operations - operator != -template< typename Real, typename Device, typename Index, typename ET > -bool operator!=( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator!=( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real, Device, Index >, ET >::NE( a, b ); + return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::NE( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -bool operator!=( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator!=( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::Comparison< ET, Containers::VectorView< Real, Device, Index > >::NE( a, b ); + return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::NE( a, b ); } template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index > -bool operator!=( const Containers::VectorView< Real1, Device1, Index >& a, const Containers::VectorView< Real2, Device2, Index >& b ) +bool +operator!=( const VectorView< Real1, Device1, Index >& a, const VectorView< Real2, Device2, Index >& b ) { if( a.getSize() != b.getSize() ) return false; if( a.getSize() == 0 ) return true; - return !Containers::Algorithms::ArrayOperations< Device1, Device2 >:: + return !Algorithms::ArrayOperations< Device1, Device2 >:: compare( a.getData(), b.getData(), a.getSize() ); @@ -169,116 +187,134 @@ bool operator!=( const Containers::VectorView< Real1, Device1, Index >& a, const //// // Comparison operations - operator < -template< typename Real, typename Device, typename Index, typename ET > -bool operator<( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator<( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real, Device, Index >, ET >::LT( a, b ); + return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::LT( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -bool operator<( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator<( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::Comparison< ET, Containers::VectorView< Real, Device, Index > >::LT( a, b ); + return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::LT( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -bool operator<( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +bool +operator<( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index > >::LT( a, b ); + return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::LT( a, b ); } //// // Comparison operations - operator <= -template< typename Real, typename Device, typename Index, typename ET > -bool operator<=( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator<=( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real, Device, Index >, ET >::LE( a, b ); + return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::LE( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -bool operator<=( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator<=( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::Comparison< ET, Containers::VectorView< Real, Device, Index > >::LE( a, b ); + return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::LE( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -bool operator<=( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +bool +operator<=( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index > >::LE( a, b ); + return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::LE( a, b ); } //// // Comparison operations - operator > -template< typename Real, typename Device, typename Index, typename ET > -bool operator>( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator>( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real, Device, Index >, ET >::GT( a, b ); + return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::GT( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -bool operator>( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator>( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::Comparison< ET, Containers::VectorView< Real, Device, Index > >::GT( a, b ); + return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::GT( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -bool operator>( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +bool +operator>( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index > >::GT( a, b ); + return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::GT( a, b ); } //// // Comparison operations - operator >= -template< typename Real, typename Device, typename Index, typename ET > -bool operator>=( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator>=( const VectorView< Real, Device, Index >& a, const ET& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real, Device, Index >, ET >::GE( a, b ); + return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::GE( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -bool operator>=( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > +bool +operator>=( const ET& a, const VectorView< Real, Device, Index >& b ) { - return Containers::Expressions::Comparison< ET, Containers::VectorView< Real, Device, Index > >::GE( a, b ); + return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::GE( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -bool operator>=( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) +bool +operator>=( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { - return Containers::Expressions::Comparison< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index > >::GE( a, b ); + return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::GE( a, b ); } //// // Minus template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Minus > -operator-( const Containers::VectorView< Real, Device, Index >& a ) +auto +operator-( const VectorView< Real, Device, Index >& a ) { - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Minus >( a ); + return Expressions::UnaryExpressionTemplate< VectorView< Real, Device, Index >, Expressions::Minus >( a ); } //// // Scalar product -template< typename Real, typename Device, typename Index, typename ET > -//Real +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > auto -operator,( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) -->decltype( TNL::sum( a * b ) ) +operator,( const VectorView< Real, Device, Index >& a, const ET& b ) { return TNL::sum( a * b ); } -template< typename ET, typename Real, typename Device, typename Index > -//Real +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > auto -operator,( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) -->decltype( TNL::sum( a * b ) ) +operator,( const ET& a, const VectorView< Real, Device, Index >& b ) { return TNL::sum( a * b ); } template< typename Real1, typename Real2, typename Device, typename Index > -auto operator,( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) -->decltype( TNL::sum( a * b ) ) +auto +operator,( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) { return TNL::sum( a * b ); } @@ -290,22 +326,24 @@ auto operator,( const Containers::VectorView< Real1, Device, Index >& a, const C //// // Min -template< typename Real, typename Device, typename Index, typename ET > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Min > +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > +auto min( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) { return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Min >( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Min > +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > +auto min( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) { return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Min >( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Min > +auto min( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) { return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Min >( a, b ); @@ -313,22 +351,24 @@ min( const Containers::VectorView< Real1, Device, Index >& a, const Containers:: //// // Max -template< typename Real, typename Device, typename Index, typename ET > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Max > +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > +auto max( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) { return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Max >( a, b ); } -template< typename ET, typename Real, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Max > +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > +auto max( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) { return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Max >( a, b ); } template< typename Real1, typename Real2, typename Device, typename Index > -const Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Max > +auto max( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) { return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Max >( a, b ); @@ -337,7 +377,7 @@ max( const Containers::VectorView< Real1, Device, Index >& a, const Containers:: //// // Abs template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Abs > +auto abs( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Abs >( a ); @@ -346,7 +386,7 @@ abs( const Containers::VectorView< Real, Device, Index >& a ) //// // Sine template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sin > +auto sin( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sin >( a ); @@ -355,7 +395,7 @@ sin( const Containers::VectorView< Real, Device, Index >& a ) //// // Cosine template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cos > +auto cos( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cos >( a ); @@ -364,7 +404,7 @@ cos( const Containers::VectorView< Real, Device, Index >& a ) //// // Tangent template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Tan > +auto tan( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Tan >( a ); @@ -373,7 +413,7 @@ tan( const Containers::VectorView< Real, Device, Index >& a ) //// // Sqrt template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sqrt > +auto sqrt( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sqrt >( a ); @@ -382,7 +422,7 @@ sqrt( const Containers::VectorView< Real, Device, Index >& a ) //// // Cbrt template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cbrt > +auto cbrt( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cbrt >( a ); @@ -391,7 +431,7 @@ cbrt( const Containers::VectorView< Real, Device, Index >& a ) //// // Power template< typename Real, typename Device, typename Index, typename ExpType > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Pow, ExpType > +auto pow( const Containers::VectorView< Real, Device, Index >& a, const ExpType& exp ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Pow, ExpType >( a, exp ); @@ -400,7 +440,7 @@ pow( const Containers::VectorView< Real, Device, Index >& a, const ExpType& exp //// // Floor template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Floor > +auto floor( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Floor >( a ); @@ -409,7 +449,7 @@ floor( const Containers::VectorView< Real, Device, Index >& a ) //// // Ceil template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Ceil > +auto ceil( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Ceil >( a ); @@ -418,7 +458,7 @@ ceil( const Containers::VectorView< Real, Device, Index >& a ) //// // Acos template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Acos > +auto acos( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Acos >( a ); @@ -427,7 +467,7 @@ acos( const Containers::VectorView< Real, Device, Index >& a ) //// // Asin template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Asin > +auto asin( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Asin >( a ); @@ -436,7 +476,7 @@ asin( const Containers::VectorView< Real, Device, Index >& a ) //// // Atan template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Atan > +auto atan( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Atan >( a ); @@ -445,7 +485,7 @@ atan( const Containers::VectorView< Real, Device, Index >& a ) //// // Cosh template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cosh > +auto cosh( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cosh >( a ); @@ -454,7 +494,7 @@ cosh( const Containers::VectorView< Real, Device, Index >& a ) //// // Tanh template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Tanh > +auto tanh( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Tanh >( a ); @@ -463,7 +503,7 @@ tanh( const Containers::VectorView< Real, Device, Index >& a ) //// // Log template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log > +auto log( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log >( a ); @@ -472,7 +512,7 @@ log( const Containers::VectorView< Real, Device, Index >& a ) //// // Log10 template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log10 > +auto log10( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log10 >( a ); @@ -481,7 +521,7 @@ log10( const Containers::VectorView< Real, Device, Index >& a ) //// // Log2 template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log2 > +auto log2( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log2 >( a ); @@ -490,7 +530,7 @@ log2( const Containers::VectorView< Real, Device, Index >& a ) //// // Exp template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Exp > +auto exp( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Exp >( a ); @@ -499,7 +539,7 @@ exp( const Containers::VectorView< Real, Device, Index >& a ) //// // Sign template< typename Real, typename Device, typename Index > -const Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sign > +auto sign( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sign >( a ); @@ -510,7 +550,7 @@ sign( const Containers::VectorView< Real, Device, Index >& a ) template< typename Real, typename Device, typename Index > -typename Containers::VectorView< Real, Device, Index >::RealType +Real min( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::ExpressionMin( a ); @@ -519,7 +559,7 @@ min( const Containers::VectorView< Real, Device, Index >& a ) template< typename Real, typename Device, typename Index > -typename Containers::VectorView< Real, Device, Index >::RealType +Real argMin( const Containers::VectorView< Real, Device, Index >& a, Index& arg ) { return Containers::Expressions::ExpressionArgMin( a, arg ); @@ -528,7 +568,7 @@ argMin( const Containers::VectorView< Real, Device, Index >& a, Index& arg ) template< typename Real, typename Device, typename Index > -typename Containers::VectorView< Real, Device, Index >::RealType +Real max( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::ExpressionMax( a ); @@ -537,7 +577,7 @@ max( const Containers::VectorView< Real, Device, Index >& a ) template< typename Real, typename Device, typename Index > -typename Containers::VectorView< Real, Device, Index >::RealType +Real argMax( const Containers::VectorView< Real, Device, Index >& a, Index& arg ) { return Containers::Expressions::ExpressionArgMax( a, arg ); @@ -548,7 +588,6 @@ template< typename Real, typename Index > auto sum( const Containers::VectorView< Real, Device, Index >& a ) --> decltype( Containers::Expressions::ExpressionSum( a ) ) { return Containers::Expressions::ExpressionSum( a ); } @@ -565,7 +604,7 @@ lpNorm( const Containers::VectorView< Real, Device, Index >& a, const Real2& p ) return Containers::Expressions::ExpressionLpNorm( a, p ); if( p == 2.0 ) return TNL::sqrt( Containers::Expressions::ExpressionLpNorm( a, p ) ); - return TNL::pow( Containers::Expressions::ExpressionLpNorm( a, p ), 1.0 / p ); + return TNL::pow( Containers::Expressions::ExpressionLpNorm( a, p ), (Real2) (1.0 / p) ); } template< typename Real, @@ -573,7 +612,6 @@ template< typename Real, typename Index > auto product( const Containers::VectorView< Real, Device, Index >& a ) --> decltype( Containers::Expressions::ExpressionProduct( a ) ) { return Containers::Expressions::ExpressionProduct( a ); } @@ -581,7 +619,7 @@ product( const Containers::VectorView< Real, Device, Index >& a ) template< typename Real, typename Device, typename Index > -bool +auto logicalOr( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::ExpressionLogicalOr( a ); @@ -592,7 +630,6 @@ template< typename Real, typename Index > auto binaryOr( const Containers::VectorView< Real, Device, Index >& a ) --> decltype( Containers::Expressions::ExpressionBinaryOr( a ) ) { return Containers::Expressions::ExpressionBinaryOr( a ); } @@ -600,7 +637,7 @@ binaryOr( const Containers::VectorView< Real, Device, Index >& a ) template< typename Real, typename Device, typename Index > -bool +auto logicalAnd( const Containers::VectorView< Real, Device, Index >& a ) { return Containers::Expressions::ExpressionLogicalAnd( a ); @@ -611,40 +648,39 @@ template< typename Real, typename Index > auto binaryAnd( const Containers::VectorView< Real, Device, Index >& a ) --> decltype( Containers::Expressions::ExpressionBinaryAnd( a ) ) { return Containers::Expressions::ExpressionBinaryAnd( a ); } //// // Dot product - the same as scalar product, just for convenience -template< typename Real, typename Device, typename Index, typename ET > +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > auto dot( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) -->decltype( TNL::sum( a * b ) ) { return TNL::sum( a * b ); } -template< typename ET, typename Real, typename Device, typename Index > +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > auto dot( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) -->decltype( TNL::sum( a * b ) ) { return TNL::sum( a * b ); } template< typename Real1, typename Real2, typename Device, typename Index1, typename Index2 > -//auto -Real1 dot( const Containers::VectorView< Real1, Device, Index1 >& a, const Containers::VectorView< Real2, Device, Index2 >& b ) -//->decltype( TNL::sum( a * b ) ) +auto +dot( const Containers::VectorView< Real1, Device, Index1 >& a, const Containers::VectorView< Real2, Device, Index2 >& b ) { return TNL::sum( a * b ); } //// // TODO: Replace this with multiplication when its safe -template< typename Real, typename Device, typename Index, typename ET > +template< typename Real, typename Device, typename Index, typename ET, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > Containers::VectorView< Real, Device, Index > Scale( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) { @@ -652,7 +688,8 @@ Scale( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) return result; } -template< typename ET, typename Real, typename Device, typename Index > +template< typename ET, typename Real, typename Device, typename Index, + typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Multiplication > Scale( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) {