Commit 79a3009d authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Refactored horizontal operations in expression templates using function objects

- structs from HorizontalOperations.h reimplemented as function objects in
  Functional.h
- repetitive function definitions generated using macros
- added new operators: % (modulus) and ^ (xor)
parent 4f2c112a
Loading
Loading
Loading
Loading
+104 −343
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ template< typename T1,
          typename Operation >
struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, VectorExpressionVariable >
{
   using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) );
   using RealType = decltype( Operation{}( std::declval<T1>()[0], std::declval<T2>()[0] ) );
   using ValueType = RealType;
   using DeviceType = typename T1::DeviceType;
   using IndexType = typename T1::IndexType;
@@ -155,7 +155,7 @@ template< typename T1,
          typename Operation >
struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, ArithmeticVariable >
{
   using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>() ) );
   using RealType = decltype( Operation{}( std::declval<T1>()[0], std::declval<T2>() ) );
   using ValueType = RealType;
   using DeviceType = typename T1::DeviceType;
   using IndexType = typename T1::IndexType;
@@ -237,7 +237,7 @@ template< typename T1,
          typename Operation >
struct DistributedBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, VectorExpressionVariable >
{
   using RealType = decltype( Operation::evaluate( std::declval<T1>(), std::declval<T2>()[0] ) );
   using RealType = decltype( Operation{}( std::declval<T1>(), std::declval<T2>()[0] ) );
   using ValueType = RealType;
   using DeviceType = typename T2::DeviceType;
   using IndexType = typename T2::IndexType;
@@ -320,7 +320,7 @@ template< typename T1,
          typename Operation >
struct DistributedUnaryExpressionTemplate
{
   using RealType = decltype( Operation::evaluate( std::declval<T1>()[0] ) );
   using RealType = decltype( Operation{}( std::declval<T1>()[0] ) );
   using ValueType = RealType;
   using DeviceType = typename T1::DeviceType;
   using IndexType = typename T1::IndexType;
@@ -398,50 +398,86 @@ protected:

#ifndef DOXYGEN_ONLY

////
// Binary expressions addition
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
auto
operator+( const ET1& a, const ET2& b )
{
   return DistributedBinaryExpressionTemplate< ET1, ET2, Addition >( a, b );
}

////
// Binary expression subtraction
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
auto
operator-( const ET1& a, const ET2& b )
{
   return DistributedBinaryExpressionTemplate< ET1, ET2, Subtraction >( a, b );
}
#define TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION(fname, functor)                                \
   template< typename ET1,                                                                   \
             typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >         \
   auto                                                                                      \
   fname( const ET1& a )                                                                     \
   {                                                                                         \
      return DistributedUnaryExpressionTemplate< ET1, functor >( a );                        \
   }                                                                                         \

#define TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION(fname, functor)                               \
   template< typename ET1, typename ET2,                                                     \
             typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >   \
   auto                                                                                      \
   fname( const ET1& a, const ET2& b )                                                       \
   {                                                                                         \
      return DistributedBinaryExpressionTemplate< ET1, ET2, functor >( a, b );               \
   }                                                                                         \

TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( operator+, TNL::Plus )
TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( operator-, TNL::Minus )
TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( operator*, TNL::Multiplies )
TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( operator/, TNL::Divides )
TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( operator%, TNL::Modulus )
TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( min, TNL::Min )
TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION( max, TNL::Max )

TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( operator+, TNL::UnaryPlus )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( operator-, TNL::UnaryMinus )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( abs, TNL::Abs )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( exp, TNL::Exp )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( sqrt, TNL::Sqrt )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( cbrt, TNL::Cbrt )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( log, TNL::Log )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( log10, TNL::Log10 )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( log2, TNL::Log2 )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( sin, TNL::Sin )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( cos, TNL::Cos )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( tan, TNL::Tan )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( asin, TNL::Asin )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( acos, TNL::Acos )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( atan, TNL::Atan )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( sinh, TNL::Sinh )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( cosh, TNL::Cosh )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( tanh, TNL::Tanh )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( asinh, TNL::Asinh )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( acosh, TNL::Acosh )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( atanh, TNL::Atanh )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( floor, TNL::Floor )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( ceil, TNL::Ceil )
TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION( sign, TNL::Sign )

#undef TNL_MAKE_DISTRIBUTED_UNARY_EXPRESSION
#undef TNL_MAKE_DISTRIBUTED_BINARY_EXPRESSION

////
// Binary expression multiplication
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
// Pow
template< typename ET1, typename Real,
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
operator*( const ET1& a, const ET2& b )
pow( const ET1& a, const Real& exp )
{
   return DistributedBinaryExpressionTemplate< ET1, ET2, Multiplication >( a, b );
   return DistributedBinaryExpressionTemplate< ET1, Real, Pow >( a, exp );
}

////
// Binary expression division
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
// Cast
template< typename ResultType,
          typename ET1,
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
operator/( const ET1& a, const ET2& b )
cast( const ET1& a )
{
   return DistributedBinaryExpressionTemplate< ET1, ET2, Division >( a, b );
   using CastOperation = typename Cast< ResultType >::Operation;
   return DistributedUnaryExpressionTemplate< ET1, CastOperation >( a );
}

////
// Comparison operator ==
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
bool
operator==( const ET1& a, const ET2& b )
{
@@ -451,7 +487,7 @@ operator==( const ET1& a, const ET2& b )
////
// Comparison operator !=
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
bool
operator!=( const ET1& a, const ET2& b )
{
@@ -461,7 +497,7 @@ operator!=( const ET1& a, const ET2& b )
////
// Comparison operator <
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
bool
operator<( const ET1& a, const ET2& b )
{
@@ -471,7 +507,7 @@ operator<( const ET1& a, const ET2& b )
////
// Comparison operator <=
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
bool
operator<=( const ET1& a, const ET2& b )
{
@@ -481,7 +517,7 @@ operator<=( const ET1& a, const ET2& b )
////
// Comparison operator >
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
bool
operator>( const ET1& a, const ET2& b )
{
@@ -491,7 +527,7 @@ operator>( const ET1& a, const ET2& b )
////
// Comparison operator >=
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
bool
operator>=( const ET1& a, const ET2& b )
{
@@ -501,7 +537,7 @@ operator>=( const ET1& a, const ET2& b )
////
// Scalar product
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
auto
operator,( const ET1& a, const ET2& b )
{
@@ -509,301 +545,17 @@ operator,( const ET1& a, const ET2& b )
}

template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
          typename..., EnableIfDistributedBinaryExpression_t< ET1, ET2, bool > = true >
auto
dot( const ET1& a, const ET2& b )
{
   return (a, b);
}

////
// Unary expression plus
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
operator+( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, UnaryPlus >( a );
}

////
// Unary expression minus
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
operator-( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, UnaryMinus >( a );
}

////
// Binary expression min
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
auto
min( const ET1& a, const ET2& b )
{
   return DistributedBinaryExpressionTemplate< ET1, ET2, Min >( a, b );
}

////
// Binary expression max
template< typename ET1, typename ET2,
          typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void >
auto
max( const ET1& a, const ET2& b )
{
   return DistributedBinaryExpressionTemplate< ET1, ET2, Max >( a, b );
}

////
// Abs
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
abs( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Abs >( a );
}

////
// Pow
template< typename ET1, typename Real,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
pow( const ET1& a, const Real& exp )
{
   return DistributedBinaryExpressionTemplate< ET1, Real, Pow >( a, exp );
}

////
// Exp
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
exp( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Exp >( a );
}

////
// Sqrt
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
sqrt( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Sqrt >( a );
}

////
// Cbrt
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
cbrt( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Cbrt >( a );
}

////
// Log
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
log( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Log >( a );
}

////
// Log10
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
log10( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Log10 >( a );
}

////
// Log2
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
log2( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Log2 >( a );
}

////
// Sin
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
sin( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Sin >( a );
}

////
// Cos
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
cos( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Cos >( a );
}

////
// Tan
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
tan( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Tan >( a );
}

////
// Asin
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
asin( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Asin >( a );
}

////
// Acos
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
acos( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Acos >( a );
}

////
// Atan
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
atan( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Atan >( a );
}

////
// Sinh
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
sinh( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Sinh >( a );
}

////
// Cosh
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
cosh( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Cosh >( a );
}

////
// Tanh
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
tanh( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Tanh >( a );
}

////
// Asinh
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
asinh( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Asinh >( a );
}

////
// Acosh
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
acosh( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Acosh >( a );
}

////
// Atanh
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
atanh( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Atanh >( a );
}

////
// Floor
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
floor( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Floor >( a );
}

////
// Ceil
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
ceil( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Ceil >( a );
}

////
// Sign
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
auto
sign( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, Sign >( a );
}

////
// Cast
template< typename ResultType,
          typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >,
          // workaround: templated type alias cannot be declared at block level
          typename CastOperation = typename Cast< ResultType >::Operation,
          typename = void, typename = void >
auto
cast( const ET1& a )
{
   return DistributedUnaryExpressionTemplate< ET1, CastOperation >( a );
}

////
// Vertical operations
template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
min( const ET1& a )
{
@@ -811,7 +563,7 @@ min( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
argMin( const ET1& a )
{
@@ -819,7 +571,7 @@ argMin( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
max( const ET1& a )
{
@@ -827,7 +579,7 @@ max( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
argMax( const ET1& a )
{
@@ -835,7 +587,7 @@ argMax( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
sum( const ET1& a )
{
@@ -843,7 +595,7 @@ sum( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
maxNorm( const ET1& a )
{
@@ -851,7 +603,7 @@ maxNorm( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
l1Norm( const ET1& a )
{
@@ -859,7 +611,7 @@ l1Norm( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
l2Norm( const ET1& a )
{
@@ -869,7 +621,7 @@ l2Norm( const ET1& a )

template< typename ET1,
          typename Real,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
lpNorm( const ET1& a, const Real& p )
// since (1.0 / p) has type double, TNL::pow returns double
@@ -884,7 +636,7 @@ lpNorm( const ET1& a, const Real& p )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
product( const ET1& a )
{
@@ -892,7 +644,15 @@ product( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
logicalAnd( const ET1& a )
{
   return DistributedExpressionLogicalAnd( a );
}

template< typename ET1,
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
logicalOr( const ET1& a )
{
@@ -900,15 +660,15 @@ logicalOr( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
logicalAnd( const ET1& a )
binaryAnd( const ET1& a )
{
   return DistributedExpressionLogicalAnd( a );
   return DistributedExpressionBinaryAnd( a );
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
binaryOr( const ET1& a )
{
@@ -916,11 +676,11 @@ binaryOr( const ET1& a )
}

template< typename ET1,
          typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void >
          typename..., EnableIfDistributedUnaryExpression_t< ET1, bool > = true >
auto
binaryAnd( const ET1& a )
binaryXor( const ET1& a )
{
   return DistributedExpressionBinaryAnd( a );
   return DistributedExpressionBinaryXor( a );
}

////
@@ -976,6 +736,7 @@ using Expressions::operator+;
using Expressions::operator-;
using Expressions::operator*;
using Expressions::operator/;
using Expressions::operator%;
using Expressions::operator,;
using Expressions::operator==;
using Expressions::operator!=;
+14 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ auto DistributedExpressionLogicalOr( const Expression& expression ) -> std::deca
}

template< typename Expression >
auto DistributedExpressionBinaryAnd( const Expression& expression ) -> std::decay_t< decltype( expression[0] | expression[0] ) >
auto DistributedExpressionBinaryAnd( const Expression& expression ) -> std::decay_t< decltype( expression[0] & expression[0] ) >
{
   using ResultType = std::decay_t< decltype( expression[0] & expression[0] ) >;

@@ -201,6 +201,19 @@ auto DistributedExpressionBinaryOr( const Expression& expression ) -> std::decay
   return result;
}

template< typename Expression >
auto DistributedExpressionBinaryXor( const Expression& expression ) -> std::decay_t< decltype( expression[0] ^ expression[0] ) >
{
   using ResultType = std::decay_t< decltype( expression[0] ^ expression[0] ) >;

   ResultType result = 0;
   if( expression.getCommunicationGroup() != MPI::NullGroup() ) {
      const ResultType localResult = Algorithms::reduce( expression.getConstLocalView(), TNL::BitXor{} );
      MPI::Allreduce( &localResult, &result, 1, MPI_BXOR, expression.getCommunicationGroup() );
   }
   return result;
}

} // namespace Expressions
} // namespace Containers
} // namespace TNL
+109 −348

File changed.

Preview size limit exceeded, changes collapsed.

+0 −345

File deleted.

Preview size limit exceeded, changes collapsed.

+111 −376

File changed.

Preview size limit exceeded, changes collapsed.

Loading