10 #ifndef __utlExpression_h 11 #define __utlExpression_h 27 template<
class T1,
class T2>
33 template<
class TLeft,
class TRight>
36 template<
typename SubType,
typename ValueT>
class Expr;
60 template<
typename SubType,
typename ValueT>
71 return *
static_cast<const SubType*
>(
this);
76 return *
static_cast<SubType*
>(
this);
79 {
return SubType::GetDimension(); }
94 template<
typename ValueT>
104 enum { Dimension = 0 };
108 template<
typename TValue>
138 template<
typename OP,
typename TLeft,
typename TRight>
139 class BinaryOpExpr:
public Expr<BinaryOpExpr<OP,TLeft,TRight>, typename SuperFloatType<typename TLeft::ValueType, typename TRight::ValueType>::type >
152 BinaryOpExpr(
const TLeft& lhs,
const TRight& rhs): m_Left(lhs),m_Right(rhs), m_OP(OP())
155 SizeType lDim = TLeft::GetDimension();
156 SizeType rDim = TRight::GetDimension();
157 if (lDim>0 && rDim>0)
159 utlSAException(lDim>0 && rDim>0 && lDim!=rDim)(lDim)(rDim).msg(
"the dimensions of two sides are different");
160 const ShapeType leftShape=m_Left.GetShape(), rightShape=m_Right.GetShape();
161 for (
int i = 0; i < lDim; ++i )
163 (i)(leftShape[i])(rightShape[i]).msg(
"the sizes of two sides are different");
168 BinaryOpExpr(
const TLeft&& lhs,
const TRight&& rhs): m_Left(lhs),m_Right(rhs), m_OP(OP())
171 SizeType lDim = TLeft::GetDimension();
172 SizeType rDim = TRight::GetDimension();
173 if (lDim>0 && rDim>0)
175 utlSAException(lDim>0 && rDim>0 && lDim!=rDim)(lDim)(rDim).msg(
"the dimensions of two sides are different");
176 const ShapeType leftShape=m_Left.GetShape(), rightShape=m_Right.GetShape();
177 for (
int i = 0; i < lDim; ++i )
179 (i)(leftShape[i])(rightShape[i]).msg(
"the sizes of two sides are different");
191 SizeType lDim = TLeft::GetDimension();
192 SizeType rDim = TRight::GetDimension();
193 utlSAException(lDim>0 && rDim>0 && lDim!=rDim)(lDim)(rDim).msg(
"the dimensions of two sides are different");
203 if (TLeft::GetDimension()==0)
204 return m_Right.GetShape();
205 if (TRight::GetDimension()==0)
206 return m_Left.GetShape();
207 return m_Left.GetShape();
211 return m_OP( m_Left.Eval(i), m_Right.Eval(i) );
215 template<
typename OP,
typename TLeft,
typename ValueT>
216 class BinaryOpExpr<OP, TLeft,
ScalarExprBase<ValueT>>:
public Expr<BinaryOpExpr<OP,TLeft,ScalarExprBase<ValueT>>, Expr2ValueType<TLeft, ScalarExprBase<ValueT>> >
236 return TLeft::GetDimension();
241 return m_Left.GetShape();
245 return m_OP( m_Left.Eval(i), m_Scalar );
249 template<
typename OP,
typename TRight,
typename ValueT>
250 class BinaryOpExpr<OP,
ScalarExprBase<ValueT>, TRight>:
public Expr<BinaryOpExpr<OP,ScalarExprBase<ValueT>, TRight>, Expr2ValueType<TRight, ScalarExprBase<ValueT>> >
270 return TRight::GetDimension();
275 return m_Right.GetShape();
279 return m_OP( m_Scalar, m_Right.Eval(i) );
283 template<
typename OP,
typename ValueT1,
typename ValueT2>
313 return m_OP( m_Scalar1, m_Scalar2 );
320 template<
typename OP,
typename TA,
typename TB>
330 template<
typename OP,
typename TLeft,
typename TRight>
338 template<
typename OP,
typename TA>
341 return MakeExpr<OP>( lhs, rhs );
344 template<
typename OP,
typename TB>
347 return MakeExpr<OP>( lhs, rhs );
349 template<
typename OP,
typename TA>
352 return MakeExpr<OP>( lhs, rhs );
355 template<
typename OP,
typename TB>
358 return MakeExpr<OP>( lhs, rhs );
366 #define __BinaryOpExpr_Op(name, op) \ 367 template<typename TLeft, typename TRight> \ 368 inline BinaryOpExpr<name<Expr2ValueType<TLeft,TRight> >,TLeft,TRight> \ 369 operator op (const Expr<TLeft, typename TLeft::ValueType>& lhs, const Expr<TRight, typename TRight::ValueType>& rhs){ \ 370 return MakeExpr<name<Expr2ValueType<TLeft,TRight> > >(lhs, rhs); \ 372 template<typename TRight> \ 373 inline BinaryOpExpr<name<Expr2ValueType<ScalarExpr,TRight> >,ScalarExpr,TRight> \ 374 operator op (const ScalarExpr &lhs, const Expr<TRight, typename TRight::ValueType>& rhs){ \ 375 return MakeExpr<name<Expr2ValueType<ScalarExpr,TRight> > >(lhs, rhs); \ 377 template<typename TLeft> \ 378 inline BinaryOpExpr<name<Expr2ValueType<TLeft,ScalarExpr> >, TLeft,ScalarExpr > \ 379 operator op (const Expr<TLeft, typename TLeft::ValueType>& lhs, const ScalarExpr& rhs){ \ 380 return MakeExpr<name<Expr2ValueType<TLeft,ScalarExpr> > >(lhs, rhs); \ 382 template<typename TRight> \ 383 inline BinaryOpExpr<name<Expr2ValueType<ScalarExpr,TRight> >,ScalarExpr,TRight> \ 384 operator op (const double lhs, const Expr<TRight, typename TRight::ValueType>& rhs){ \ 385 return MakeExpr<name<Expr2ValueType<ScalarExpr,TRight> > >(ScalarExpr(lhs), rhs); \ 387 template<typename TLeft> \ 388 inline BinaryOpExpr<name<Expr2ValueType<TLeft,ScalarExpr> >, TLeft,ScalarExpr > \ 389 operator op (const Expr<TLeft, typename TLeft::ValueType>& lhs, const double rhs){ \ 390 return MakeExpr<name<Expr2ValueType<TLeft,ScalarExpr> > >(lhs, ScalarExpr(rhs)); \ 392 template<typename TRight> \ 393 inline BinaryOpExpr<name<Expr2ValueType<ScalarComplexExpr,TRight> >,ScalarComplexExpr,TRight> \ 394 operator op (const std::complex<double> lhs, const Expr<TRight, typename TRight::ValueType>& rhs){ \ 395 return MakeExpr<name<Expr2ValueType<ScalarComplexExpr,TRight> > >(ScalarComplexExpr(lhs), rhs); \ 397 template<typename TLeft> \ 398 inline BinaryOpExpr<name<Expr2ValueType<TLeft,ScalarComplexExpr> >, TLeft,ScalarComplexExpr > \ 399 operator op (const Expr<TLeft, typename TLeft::ValueType>& lhs, const std::complex<double> rhs){ \ 400 return MakeExpr<name<Expr2ValueType<TLeft,ScalarComplexExpr> > >(lhs, ScalarComplexExpr(rhs)); \ 415 template<typename OP, typename EType >
431 return EType::GetDimension();
435 return m_Expr.GetShape();
439 return m_OP( m_Expr.Eval(i) );
444 template<
typename OP,
typename EType>
450 template<
typename OP,
typename EType>
452 return MakeExpr<OP>(expr);
457 #define __UnaryOpExpr_Op(name, op) \ 458 template<typename TExpr> \ 459 inline UnaryOpExpr<name<typename TExpr::ValueType>,TExpr> \ 460 operator op (const Expr<TExpr, typename TExpr::ValueType>& lhs){ \ 461 return MakeExpr<name<typename TExpr::ValueType>>(lhs); \ Superclass::SizeType SizeType
Superclass::SizeType SizeType
const ShapeType GetShape() const
static SizeType GetDimension()
#define __UnaryOpExpr_Op(name, op)
define expressions for unary math operators
base class for expression
ScalarExprBase< std::complex< double > > ScalarComplexExpr
ScalarExprBase<std::complex<double> >
static SizeType GetDimension()
Superclass::ShapeType ShapeType
BinaryOpExpr(const TLeft &&lhs, const TRight &&rhs)
ValueType Eval(int i) const
BinaryOpExpr(const TLeft &lhs, const TRight &rhs)
ValueType Eval(int i) const
Superclass::ValueType ValueType
Superclass::ValueType ValueType
Superclass::SizeType SizeType
scalar expression base class for double and std::complex<double>
ScalarExprBase< double > ScalarExpr
ScalarExprBase<double>
const ShapeType GetShape() const
static SizeType GetDimension()
SizeType const * ShapeType
Expr< BinaryOpExpr< OP, ScalarExprBase< ValueT1 >, ScalarExprBase< ValueT2 > >, SuperType< ValueT1, ValueT2 > > Superclass
BinaryOpExpr(const BinaryOpExpr &&other)
Superclass::ShapeType ShapeType
Superclass::ShapeType ShapeType
const ShapeType GetShape() const
const ShapeType GetShape() const
ScalarExprBase(TValue scalar)
typename SuperFloatType< T1, T2 >::type SuperType
BinaryOpExpr(const ScalarExprBase< ValueT > &lhs, const TRight &rhs)
#define UTL_ALWAYS_INLINE
typename SuperFloatType< typename TLeft::ValueType, typename TRight::ValueType >::type Expr2ValueType
BinaryOpExpr< OP, TLeft, TRight > F(const Expr< TLeft, typename TLeft::ValueType > &lhs, const Expr< TRight, typename TRight::ValueType > &rhs)
#define __BinaryOpExpr_Op(name, op)
define expressions for binary math operators
BinaryOpExpr< OP, TA, TB > MakeExpr(const Expr< TA, typename TA::ValueType > &lhs, const Expr< TB, typename TB::ValueType > &rhs)
BinaryOpExpr(const ScalarExprBase< ValueT1 > &lhs, const ScalarExprBase< ValueT2 > &rhs)
const ValueType ConstRef(void) const
const ShapeType GetShape() const
Expr< BinaryOpExpr< OP, TLeft, ScalarExprBase< ValueT > >, Expr2ValueType< TLeft, ScalarExprBase< ValueT > > > Superclass
Superclass::SizeType SizeType
Superclass::ValueType ValueType
static SizeType GetDimension()
Superclass::ValueType ValueType
Superclass::ValueType ValueType
#define utlSAException(expr)
typename TExpr::ValueType Expr1ValueType
const ShapeType GetShape() const
unary operator expression
static SizeType GetDimension()
Expr< BinaryOpExpr< OP, TLeft, TRight >, typename SuperFloatType< typename TLeft::ValueType, typename TRight::ValueType >::type > Superclass
ValueType Eval(int i) const
const SubType & ConstRef(void) const
const ShapeType GetShape() const
Superclass::SizeType SizeType
Superclass::ShapeType ShapeType
Expr< UnaryOpExpr< OP, EType >, typename EType::ValueType > Superclass
Superclass::SizeType SizeType
ValueType Eval(int i) const
Binary operator expression class.
ValueType Eval(int i) const
Expr< ScalarExprBase< ValueT >, ValueT > Superclass
BinaryOpExpr(const TLeft &lhs, const ScalarExprBase< ValueT > &rhs)
UnaryOpExpr(const EType &expr)
Expr< BinaryOpExpr< OP, ScalarExprBase< ValueT >, TRight >, Expr2ValueType< ScalarExprBase< ValueT >, TRight > > Superclass
static SizeType GetDimension()
Superclass::ShapeType ShapeType
static SizeType GetDimension()
ValueType Eval(int i) const
conditional_t< std::is_scalar< T >::value &&std::is_scalar< t >::value, double, std::complex< double > > type
Superclass::ShapeType ShapeType