/*************************************************************************** * blitz/arrayexpr.h Array expression templates * * Copyright (C) 1997-2001 Todd Veldhuizen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Suggestions: blitz-dev@oonumerics.org * Bugs: blitz-bugs@oonumerics.org * * For more information, please see the Blitz++ Home Page: * http://oonumerics.org/blitz/ * ****************************************************************************/ #ifndef BZ_ARRAYTERNARYEXPR_H #define BZ_ARRAYTERNARYEXPR_H #ifndef BZ_ARRAY_H #error must be included via #endif #ifndef BZ_OPS_H #include #endif #ifndef BZ_PRETTYPRINT_H #include #endif #ifndef BZ_SHAPECHECK_H #include #endif #ifndef BZ_NUMINQUIRE_H #include #endif /* * The array expression templates iterator interface is followed by * these classes: * * _bz_ArrayExprTernaryOp " */ BZ_NAMESPACE(blitz) template class _bz_ArrayExprTernaryOp { public: typedef P_expr1 T_expr1; typedef P_expr2 T_expr2; typedef P_expr3 T_expr3; typedef _bz_typename T_expr1::T_numtype T_numtype1; typedef _bz_typename T_expr2::T_numtype T_numtype2; typedef _bz_typename T_expr3::T_numtype T_numtype3; typedef _bz_typename P_op::T_numtype T_numtype; typedef P_op T_op; typedef T_expr1 T_ctorArg1; typedef T_expr2 T_ctorArg2; typedef T_expr3 T_ctorArg3; enum { numArrayOperands = BZ_ENUM_CAST(P_expr1::numArrayOperands) + BZ_ENUM_CAST(P_expr2::numArrayOperands) + BZ_ENUM_CAST(P_expr3::numArrayOperands), numIndexPlaceholders = BZ_ENUM_CAST(P_expr1::numIndexPlaceholders) + BZ_ENUM_CAST(P_expr2::numIndexPlaceholders) + BZ_ENUM_CAST(P_expr3::numIndexPlaceholders), rank = (BZ_ENUM_CAST(P_expr1::rank) > BZ_ENUM_CAST(P_expr2::rank)) ? ( (BZ_ENUM_CAST(P_expr1::rank) > BZ_ENUM_CAST(P_expr3::rank)) ? BZ_ENUM_CAST(P_expr1::rank) : BZ_ENUM_CAST(P_expr3::rank) ) : ( (BZ_ENUM_CAST(P_expr2::rank) > BZ_ENUM_CAST(P_expr3::rank)) ? BZ_ENUM_CAST(P_expr2::rank) : BZ_ENUM_CAST(P_expr3::rank)) }; _bz_ArrayExprTernaryOp(const _bz_ArrayExprTernaryOp& a) : iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) { } template _bz_ArrayExprTernaryOp(BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, BZ_ETPARM(T3) c) : iter1_(a), iter2_(b), iter3_(c) { } // _bz_ArrayExprTernaryOp(T_expr1 a, T_expr2 b) // : iter1_(a), iter2_(b) // { } T_numtype operator*() { return T_op::apply(*iter1_, *iter2_,*iter3_); } #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE template T_numtype operator()(TinyVector i) { return T_op::apply(iter1_(i), iter2_(i),iter3_(i)); } #else template T_numtype operator()(const TinyVector& i) { return T_op::apply(iter1_(i), iter2_(i),iter3_(i)); } #endif int ascending(int rank) { return iter1_.ascending(rank); } int ordering(int rank) { return iter1_.ordering(rank); } int lbound(int rank) { return iter1_.lbound(rank); } int ubound(int rank) { return iter1_.ubound(rank); } void push(int position) { iter1_.push(position); iter2_.push(position); iter3_.push(position); } void pop(int position) { iter1_.pop(position); iter2_.pop(position); iter3_.pop(position); } void advance() { iter1_.advance(); iter2_.advance(); iter3_.advance(); } void advance(int n) { iter1_.advance(n); iter2_.advance(n); iter3_.advance(n); } void loadStride(int rank) { iter1_.loadStride(rank); iter2_.loadStride(rank); iter3_.loadStride(rank); } _bz_bool isUnitStride(int rank) const { return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank) && iter3_.isUnitStride(rank); } void advanceUnitStride() { iter1_.advanceUnitStride(); iter2_.advanceUnitStride(); iter3_.advanceUnitStride(); } _bz_bool canCollapse(int outerLoopRank, int innerLoopRank) const { // BZ_DEBUG_MESSAGE("_bz_ArrayExprTernaryOp<>::canCollapse"); return iter1_.canCollapse(outerLoopRank, innerLoopRank) && iter2_.canCollapse(outerLoopRank, innerLoopRank) && iter3_.canCollapse(outerLoopRank, innerLoopRank); } T_numtype operator[](int i) { return T_op::apply(iter1_[i], iter2_[i],iter3_[i]); } T_numtype fastRead(int i) { return T_op::apply(iter1_.fastRead(i), iter2_.fastRead(i),iter3_.fastRead(i)); } int suggestStride(int rank) const { int stride1 = iter1_.suggestStride(rank); int stride2 = iter2_.suggestStride(rank); int stride3 = iter2_.suggestStride(rank); if (stride1> stride2) if(stride1 > stride3) return stride1; else return stride3; else if (stride2 > stride3) return stride2; else return stride3; // return (stride1 > stride2) ? stride1 : stride2; } _bz_bool isStride(int rank, int stride) const { return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) && iter2_.isStride(rank,stride); } template void moveTo(const TinyVector& i) { iter1_.moveTo(i); iter2_.moveTo(i); iter3_.moveTo(i); } void prettyPrint(string& str, prettyPrintFormat& format) const { T_op::prettyPrint(str, format, iter1_, iter2_,iter3_); } template _bz_bool shapeCheck(const T_shape& shape) { return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape) && iter2_.shapeCheck(shape); } protected: _bz_ArrayExprTernaryOp() { } T_expr1 iter1_; T_expr2 iter2_; T_expr3 iter3_; }; template