functorExpr.h   functorExpr.h 
// -*- C++ -*- // -*- C++ -*-
/************************************************************************** * /************************************************************************** *
* blitz/array/functorExpr.h User-defined functors for arrays * blitz/array/functorExpr.h User-defined functors for arrays
* *
* $Id: functorExpr.h,v 1.8 2005/05/07 04:17:57 julianc Exp $ * $Id$
* *
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
* *
* This program is free software; you can redistribute it and/or * This file is a part of Blitz.
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * Blitz is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * Blitz is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Blitz. If not, see <http://www.gnu.org/licenses/>.
* *
* Suggestions: blitz-dev@oonumerics.org * Suggestions: blitz-devel@lists.sourceforge.net
* Bugs: blitz-bugs@oonumerics.org * Bugs: blitz-support@lists.sourceforge.net
* *
* For more information, please see the Blitz++ Home Page: * For more information, please see the Blitz++ Home Page:
* http://oonumerics.org/blitz/ * https://sourceforge.net/projects/blitz/
* *
************************************************************************** **/ ************************************************************************** **/
/* This header file is designed to allow the use of Blitz++ with /* This header file is designed to allow the use of Blitz++ with
functors (classes defining an operator()) and more general member functors (classes defining an operator()) and more general member
functions. It works best if you have access to the class source code; functions. It works best if you have access to the class source code;
there is limited support for classes that cannot be modified. The best there is limited support for classes that cannot be modified. The best
approach in that case is usually to write an adapter class. approach in that case is usually to write an adapter class.
This works with class methods that take one, two or three arguments. This works with class methods that take one, two or three arguments.
skipping to change at line 83 skipping to change at line 88
A = C + classInstance.funcname(tensor::i, tensor::j) A = C + classInstance.funcname(tensor::i, tensor::j)
All the member functions to be applied must be declared const. All the member functions to be applied must be declared const.
There is also some support for classes where the source code is not There is also some support for classes where the source code is not
available or not to be tampered with. For example, available or not to be tampered with. For example,
A = C + applyFunctor(classInstance, B * tensor::i); A = C + applyFunctor(classInstance, B * tensor::i);
A = C + applyFunctor(classInstance, tensor::i, tensor::j); A = C + applyFunctor(classInstance, tensor::i, tensor::j);
This approach does not work for arbitrary member functions. The This approach does not work for arbitrary s. The
class must be a proper functor with an operator(). class must be a proper functor with an operator().
*/ */
#ifndef BZ_ARRAY_FUNCTOREXPR_H #ifndef BZ_ARRAY_FUNCTOREXPR_H
#define BZ_ARRAY_FUNCTOREXPR_H #define BZ_ARRAY_FUNCTOREXPR_H
#ifndef BZ_ARRAY_H #ifndef BZ_ARRAY_H
#error <blitz/array/functorExpr.h> must be included via <blitz/array.h> #error <blitz/array/functorExpr.h> must be included via <blitz/array.h>
#endif #endif
#include <blitz/prettyprint.h> #include <blitz/prettyprint.h>
#include <blitz/shapecheck.h> #include <blitz/shapecheck.h>
#include <blitz/tinyvec.h> #include <blitz/tinyvec2.h>
BZ_NAMESPACE(blitz) BZ_NAMESPACE(blitz)
template<typename P_functor, typename P_expr, typename P_result> template<typename P_functor, typename P_expr, typename P_result>
class _bz_FunctorExpr { class _bz_FunctorExpr {
public: public:
typedef P_functor T_functor; typedef P_functor T_functor;
typedef P_expr T_expr; typedef P_expr T_expr;
typedef _bz_typename T_expr::T_numtype T_numtype1; typedef _bz_typename T_expr::T_numtype T_numtype1;
typedef P_result T_numtype; typedef P_result T_numtype;
// select return type
typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
typedef typename selectET<typename T_expr::T_typeprop,
T_numtype,
_bz_FunctorExpr<T_functor,
test,
P_result> >::T_selected T_typepr
op;
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
typedef T_numtype T_optype;
typedef T_expr T_ctorArg1; typedef T_expr T_ctorArg1;
typedef int T_ctorArg2; // dummy typedef int T_ctorArg2; // dummy
typedef int T_ctorArg3; // dummy typedef int T_ctorArg3; // dummy
typedef _bz_FunctorExpr<P_functor, _bz_typename P_expr::T_range_result,
P_result> T_range_result;
static const int static const int
numArrayOperands = T_expr::numArrayOperands, numArrayOperands = T_expr::numArrayOperands,
numTVOperands = T_expr::numTVOperands,
numTMOperands = T_expr::numTMOperands,
numIndexPlaceholders = T_expr::numIndexPlaceholders, numIndexPlaceholders = T_expr::numIndexPlaceholders,
rank = T_expr::rank; minWidth = T_expr::minWidth,
maxWidth = T_expr::maxWidth,
rank_ = T_expr::rank_;
template<int N> struct tvresult {
typedef _bz_FunctorExpr<
T_functor,
typename T_expr::template tvresult<N>::Type,
T_numtype> Type;
};
_bz_FunctorExpr(const _bz_FunctorExpr<P_functor,P_expr,P_result>& a) _bz_FunctorExpr(const _bz_FunctorExpr<P_functor,P_expr,P_result>& a)
: f_(a.f_), iter_(a.iter_) : f_(a.f_), iter_(a.iter_)
{ } { }
_bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr) a) _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr) a)
: f_(f), iter_(a) : f_(f), iter_(a)
{ } { }
_bz_FunctorExpr(BZ_ETPARM(T_functor) f, _bz_typename T_expr::T_ctorArg1 // this is identical to the above constructor
a) //_bz_FunctorExpr(BZ_ETPARM(T_functor) f, _bz_typename T_expr::T_ctorArg1
: f_(f), iter_(a) a)
{ } //: f_(f), iter_(a) { }
#if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC #if BZ_TEMPLATE_CTOR_DOESNT_CAUSE_HAVOC
template<typename T1> template<typename T1>
explicit _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a) explicit _bz_FunctorExpr(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a)
: f_(f), iter_(a) : f_(f), iter_(a)
{ } { }
#endif #endif
T_numtype operator*() /* Functions for reading data. Because they must depend on the
{ return f_(*iter_); } * result type, they utilize a helper class.
*/
// For numtypes, apply operator
template<typename T> struct readHelper {
static T_result fastRead(const T_functor& f, const T_expr& iter,
diffType i) {
return f(iter.fastRead(i)); };
static T_result indexop(const T_functor& f, const T_expr& iter, int i)
{
return f(iter[i]); };
static T_result deref(const T_functor& f, const T_expr& iter) {
return f(*iter); }
static T_result first_value(const T_functor& f, const T_expr& iter) {
return f(iter.first_value()); }
static T_result shift(const T_functor& f, const T_expr& iter,
int offset, int dim) {
return f(iter.shift(offset, dim)); }
static T_result shift(const T_functor& f, const T_expr& iter,
int offset1, int dim1,int offset2, int dim2) {
return f(iter.shift(offset1, dim1, offset2, dim2)); }
template<int N_rank>
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
static T_result indexop(const T_functor& f, const T_expr& iter,
const TinyVector<int, N_rank> i) {
#else
static T_result indexop(const T_functor& f, const T_expr& iter,
const TinyVector<int, N_rank>& i) {
#endif
return f(iter(i)); }
};
// For ET types, bypass operator and create expression
template<typename T> struct readHelper<ETBase<T> > {
static T_result fastRead(const T_functor& f, const T_expr& iter,
diffType i) {
return T_result(f,iter.fastRead(i)); };
static T_result indexop(const T_functor& f, const T_expr& iter, int i
) {
return T_result(f,iter[i]); };
static T_result deref(const T_functor& f, const T_expr& iter) {
return T_result(f,*iter); }
static T_result first_value(const T_functor& f, const T_expr& iter) {
return iter.first_value(); }
static T_result shift(const T_functor& f, const T_expr& iter,
int offset, int dim) {
return T_result(f,iter.shift(offset, dim)); }
static T_result shift(const T_functor& f, const T_expr& iter,
int offset1, int dim1,int offset2, int dim2) {
return T_result(f,iter.shift(offset1, dim1, offset2, dim2)); }
template<int N_rank>
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
template<int N_rank> static T_result indexop(const T_functor& f, const T_expr& iter,
T_numtype operator()(TinyVector<int,N_rank> i) const TinyVector<int, N_rank> i) {
{ return f_(iter_(i)); }
#else #else
static T_result indexop(const T_functor& f, const T_expr& iter,
const TinyVector<int, N_rank>& i) {
#endif
return T_result(f,iter(i)); }
};
T_result fastRead(diffType i) const {
return readHelper<T_typeprop>::fastRead(f_, iter_, i); }
template<int N>
typename tvresult<N>::Type fastRead_tv(diffType i) const
{ return typename tvresult<N>::Type(f_,iter_.template fastRead_tv<N>(
i)); }
T_result operator[](int i) const {
return readHelper<T_typeprop>::indexop(f_, iter_, i); }
template<int N_rank> template<int N_rank>
T_numtype operator()(const TinyVector<int,N_rank>& i) #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
{ return f_(iter_(i)); } T_result operator()(const TinyVector<int, N_rank> i) const {
#else
T_result operator()(const TinyVector<int, N_rank>& i) const {
#endif #endif
return readHelper<T_typeprop>::indexop(f_, iter_,i); }
T_result operator*() const {
return readHelper<T_typeprop>::deref(f_, iter_); }
T_result first_value() const {
return readHelper<T_typeprop>::first_value(f_, iter_); }
int ascending(int rank) T_result shift(int offset, int dim) const {
{ return iter_.ascending(rank); } return readHelper<T_typeprop>::shift(f_,iter_,offset, dim); }
int ordering(int rank) T_result shift(int offset1, int dim1,int offset2, int dim2) const {
{ return iter_.ordering(rank); } return readHelper<T_typeprop>::shift(f_,iter_,offset1, dim1,
offset2, dim2); }
int lbound(int rank) // ****** end reading
{ return iter_.lbound(rank); }
int ubound(int rank) bool isVectorAligned(diffType offset) const
{ return iter_.ubound(rank); } { return iter_.isVectorAligned(offset); }
void push(int position) T_range_result operator()(RectDomain<rank_> d) const
{ iter_.push(position); } {
return T_range_result(f_, iter_(d));
}
void pop(int position) int ascending(const int rank) const { return iter_.ascending(rank); }
{ iter_.pop(position); } int ordering(const int rank) const { return iter_.ordering(rank); }
int lbound(const int rank) const { return iter_.lbound(rank); }
int ubound(const int rank) const { return iter_.ubound(rank); }
RectDomain<rank_> domain() const { return iter_.domain(); }
void advance() void push(const int position) { iter_.push(position); }
{ iter_.advance(); }
void advance(int n) void pop(const int position) { iter_.pop(position); }
{ iter_.advance(n); }
void loadStride(int rank) void advance() { iter_.advance(); }
{ iter_.loadStride(rank); }
bool isUnitStride(int rank) const void advance(const int n) { iter_.advance(n); }
{ return iter_.isUnitStride(rank); }
void advanceUnitStride() void loadStride(const int rank) { iter_.loadStride(rank); }
{ iter_.advanceUnitStride(); }
bool canCollapse(int outerLoopRank, int innerLoopRank) const bool isUnitStride(const int rank) const { return iter_.isUnitStride(ran
k); }
bool isUnitStride() const { return iter_.isUnitStride(); }
void advanceUnitStride() { iter_.advanceUnitStride(); }
bool canCollapse(const int outerLoopRank, const int innerLoopRank) cons
t
{ {
return iter_.canCollapse(outerLoopRank, innerLoopRank); return iter_.canCollapse(outerLoopRank, innerLoopRank);
} }
T_numtype operator[](int i) // this is needed for the stencil expression fastRead to work
{ return f_(iter_[i]); } void _bz_offsetData(sizeType i)
{ iter_._bz_offsetData(i); }
// and these are needed for stencil expression shift to work
void _bz_offsetData(sizeType offset, int dim)
{ iter_._bz_offsetData(offset, dim);}
T_numtype fastRead(int i) void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d
{ return f_(iter_.fastRead(i)); } im2)
{ iter_._bz_offsetData(offset1, dim1, offset2, dim2);}
int suggestStride(int rank) const diffType suggestStride(const int rank) const
{ return iter_.suggestStride(rank); } { return iter_.suggestStride(rank); }
bool isStride(int rank, int stride) const bool isStride(const int rank,const diffType stride) const
{ return iter_.isStride(rank,stride); } { return iter_.isStride(rank,stride); }
void prettyPrint(BZ_STD_SCOPE(string) &str, void prettyPrint(BZ_STD_SCOPE(string) &str,
prettyPrintFormat& format) const prettyPrintFormat& format) const
{ {
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor);
str += "("; str += "(";
iter_.prettyPrint(str, format); iter_.prettyPrint(str, format);
str += ")"; str += ")";
} }
template<typename T_shape> template<typename T_shape>
bool shapeCheck(const T_shape& shape) bool shapeCheck(const T_shape& shape) const
{ return iter_.shapeCheck(shape); } { return iter_.shapeCheck(shape); }
template<int N_rank> template<int N_rank>
void moveTo(const TinyVector<int,N_rank>& i) void moveTo(const TinyVector<int,N_rank>& i)
{ {
iter_.moveTo(i); iter_.moveTo(i);
} }
// sliceinfo for expressions
template<typename T1, typename T2 = nilArraySection,
class T3 = nilArraySection, typename T4 = nilArraySection,
class T5 = nilArraySection, typename T6 = nilArraySection,
class T7 = nilArraySection, typename T8 = nilArraySection,
class T9 = nilArraySection, typename T10 = nilArraySection,
class T11 = nilArraySection>
class SliceInfo {
public:
typedef typename T_expr::template SliceInfo<T1, T2, T3, T4, T5, T6, T7,
T8, T9, T10, T11>::T_slice T_slice1;
typedef _bz_FunctorExpr<T_functor, T_slice1, T_numtype> T_slice;
};
template<typename T1, typename T2, typename T3, typename T4, typename T
5, typename T6,
typename T7, typename T8, typename T9, typename T10, typename T11>
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r
9, T10 r10, T11 r11) const
{
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic
e
(f_,iter_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11));
}
protected: protected:
_bz_FunctorExpr() { } _bz_FunctorExpr() { }
T_functor f_; T_functor f_;
T_expr iter_; T_expr iter_;
}; };
template<typename P_functor, typename P_expr1, typename P_expr2, typename P _result> template<typename P_functor, typename P_expr1, typename P_expr2, typename P _result>
class _bz_FunctorExpr2 class _bz_FunctorExpr2
{ {
public: public:
typedef P_functor T_functor; typedef P_functor T_functor;
typedef P_expr1 T_expr1; typedef P_expr1 T_expr1;
typedef P_expr2 T_expr2; typedef P_expr2 T_expr2;
typedef _bz_typename T_expr1::T_numtype T_numtype1; typedef _bz_typename T_expr1::T_numtype T_numtype1;
typedef _bz_typename T_expr2::T_numtype T_numtype2; typedef _bz_typename T_expr2::T_numtype T_numtype2;
typedef P_result T_numtype; typedef P_result T_numtype;
// select return type
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr
apped1;
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr
apped2;
typedef typename selectET2<typename T_expr1::T_typeprop,
typename T_expr2::T_typeprop,
T_numtype,
_bz_FunctorExpr2<T_functor,
typename asExpr<T_unwrapped1>:
:T_expr,
typename asExpr<T_unwrapped2>:
:T_expr,
T_numtype> >::T_selected T_typ
eprop;
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
typedef T_numtype T_optype;
typedef T_expr1 T_ctorArg1; typedef T_expr1 T_ctorArg1;
typedef T_expr1 T_ctorArg2; typedef T_expr1 T_ctorArg2;
typedef int T_ctorArg3; // dummy typedef int T_ctorArg3; // dummy
typedef _bz_FunctorExpr2<P_functor,
_bz_typename P_expr1::T_range_result,
_bz_typename P_expr2::T_range_result,
P_result> T_range_result;
static const int static const int
numArrayOperands = T_expr1::numArrayOperands numArrayOperands = T_expr1::numArrayOperands
+ T_expr2::numArrayOperands, + T_expr2::numArrayOperands,
numTVOperands = T_expr1::numTVOperands + T_expr2::numTVOperands,
numTMOperands = T_expr1::numTMOperands + T_expr2::numTMOperands,
numIndexPlaceholders = T_expr1::numIndexPlaceholders numIndexPlaceholders = T_expr1::numIndexPlaceholders
+ T_expr2::numIndexPlaceholders, + T_expr2::numIndexPlaceholders,
rank = T_expr1::rank > T_expr2::rank minWidth = BZ_MIN(T_expr1::minWidth, T_expr2::minWidth),
? T_expr1::rank : T_expr2::rank; maxWidth = BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth),
rank_ = BZ_MAX(T_expr1::rank_, T_expr2::rank_);
template<int N> struct tvresult {
typedef _bz_FunctorExpr2<
T_functor,
typename T_expr1::template tvresult<N>::Type,
typename T_expr2::template tvresult<N>::Type,
T_numtype> Type;
};
_bz_FunctorExpr2(const _bz_FunctorExpr2<P_functor, P_expr1, P_expr2, _bz_FunctorExpr2(const _bz_FunctorExpr2<P_functor, P_expr1, P_expr2,
P_result>& a) P_result>& a)
: f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_) : f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_)
{ } { }
_bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a, _bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a,
BZ_ETPARM(T_expr2) b) BZ_ETPARM(T_expr2) b)
: f_(f), iter1_(a), iter2_(b) : f_(f), iter1_(a), iter2_(b)
{ } { }
template<typename T1, typename T2> template<typename T1, typename T2>
_bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b) _bz_FunctorExpr2(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b)
: f_(f), iter1_(a), iter2_(b) : f_(f), iter1_(a), iter2_(b)
{ } { }
T_numtype operator*() /* Functions for reading. Because they must depend on the result
{ return f_(*iter1_, *iter2_); } * type, they utilize a helper class.
*/
// For numtypes, apply operator
template<typename T> struct readHelper {
static T_result fastRead(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, diffType i) {
return f(iter1.fastRead(i), iter2.fastRead(i)); }
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, int i) {
return f(iter1[i], iter2[i]); };
static T_result deref(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2) {
return f(*iter1, *iter2); }
static T_result first_value(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2) {
return f(iter1.first_value(), iter2.first_value()); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2,
int offset, int dim) {
return f(iter1.shift(offset, dim),iter2.shift(offset, dim)); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2,
int offset1, int dim1,int offset2, int dim2) {
return f(iter1.shift(offset1, dim1, offset2, dim2),
iter2.shift(offset1, dim1, offset2, dim2)); }
template<int N_rank>
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
static T_result indexop(const T_functor& f, const T_expr& iter,
const T_expr2& iter2,
const TinyVector<int, N_rank> i) {
#else
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2,
const TinyVector<int, N_rank>& i) {
#endif
return f(iter1(i), iter2(i)); };
};
// For ET types, bypass operator and create expression
template<typename T> struct readHelper<ETBase<T> > {
static T_result fastRead(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, diffType i) {
return T_result(f,iter1.fastRead(i), iter2.fastRead(i)); }
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, int i) {
return T_result(f,iter1[i], iter2[i]); };
static T_result deref(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2) {
return T_result(f,*iter1, *iter2); }
static T_result first_value(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2) {
return T_result(f,iter1.first_value(), iter2.first_value()); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2,
int offset, int dim) {
return T_result(f,iter1.shift(offset, dim),iter2.shift(offset, dim));
}
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2,
int offset1, int dim1,int offset2, int dim2) {
return T_result(f,iter1.shift(offset1, dim1, offset2, dim2),
iter2.shift(offset1, dim1, offset2, dim2)); }
template<int N_rank>
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
template<int N_rank> static T_result indexop(const T_functor& f, const T_expr1& iter1,
T_numtype operator()(TinyVector<int, N_rank> i) const T_expr2& iter2,
{ return f_(iter1_(i), iter2_(i)); } const TinyVector<int, N_rank> i) {
#else #else
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2,
const TinyVector<int, N_rank>& i) {
#endif
return T_result(f,iter1(i), iter2(i)); }
};
T_result fastRead(diffType i) const {
return readHelper<T_typeprop>::fastRead(f_, iter1_, iter2_, i); }
template<int N>
typename tvresult<N>::Type fastRead_tv(diffType i) const
{ return typename tvresult<N>::Type(f_,
iter1_.template fastRead_tv<N>(i),
iter2_.template fastRead_tv<N>(i))
; }
T_result operator[](int i) const {
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, i); }
template<int N_rank> template<int N_rank>
T_numtype operator()(const TinyVector<int, N_rank>& i) #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
{ return f_(iter1_(i), iter2_(i)); } T_result operator()(const TinyVector<int, N_rank> i) const {
#else
T_result operator()(const TinyVector<int, N_rank>& i) const {
#endif #endif
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, i); }
T_result operator*() const {
return readHelper<T_typeprop>::deref(f_, iter1_, iter2_); }
T_result first_value() const {
return readHelper<T_typeprop>::first_value(f_, iter1_, iter2_); }
int ascending(int rank) T_result shift(int offset, int dim) const {
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_,offset, dim); }
T_result shift(int offset1, int dim1,int offset2, int dim2) const
{ {
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_,
offset1, dim1, offset2, dim2); }
// ****** end reading
T_range_result operator()(RectDomain<rank_> d) const
{
return T_range_result(f_, iter1_(d), iter2_(d));
}
bool isVectorAligned(diffType offset) const
{ return iter1_.isVectorAligned(offset) &&
iter2_.isVectorAligned(offset); }
int ascending(const int rank) const {
return bounds::compute_ascending(rank, iter1_.ascending(rank), return bounds::compute_ascending(rank, iter1_.ascending(rank),
iter2_.ascending(rank)); iter2_.ascending(rank));
} }
int ordering(int rank) int ordering(const int rank) const {
{
return bounds::compute_ordering(rank, iter1_.ordering(rank), return bounds::compute_ordering(rank, iter1_.ordering(rank),
iter2_.ordering(rank)); iter2_.ordering(rank));
} }
int lbound(int rank) int lbound(const int rank) const {
{
return bounds::compute_lbound(rank, iter1_.lbound(rank), return bounds::compute_lbound(rank, iter1_.lbound(rank),
iter2_.lbound(rank)); iter2_.lbound(rank));
} }
int ubound(int rank) int ubound(const int rank) const {
{
return bounds::compute_ubound(rank, iter1_.ubound(rank), return bounds::compute_ubound(rank, iter1_.ubound(rank),
iter2_.ubound(rank)); iter2_.ubound(rank));
} }
void push(int position) // defer calculation to lbound/ubound
{ RectDomain<rank_> domain() const
{
TinyVector<int, rank_> lb, ub;
for(int r=0; r<rank_; ++r) {
lb[r]=lbound(r); ub[r]=ubound(r);
}
return RectDomain<rank_>(lb,ub);
}
void push(const int position) {
iter1_.push(position); iter1_.push(position);
iter2_.push(position); iter2_.push(position);
} }
void pop(int position) void pop(const int position) {
{
iter1_.pop(position); iter1_.pop(position);
iter2_.pop(position); iter2_.pop(position);
} }
void advance() void advance() {
{
iter1_.advance(); iter1_.advance();
iter2_.advance(); iter2_.advance();
} }
void advance(int n) void advance(const int n) {
{
iter1_.advance(n); iter1_.advance(n);
iter2_.advance(n); iter2_.advance(n);
} }
void loadStride(int rank) void loadStride(const int rank) {
{
iter1_.loadStride(rank); iter1_.loadStride(rank);
iter2_.loadStride(rank); iter2_.loadStride(rank);
} }
bool isUnitStride(int rank) const bool isUnitStride(const int rank) const
{ return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); } { return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank); }
void advanceUnitStride() bool isUnitStride() const
{ { return iter1_.isUnitStride() && iter2_.isUnitStride(); }
void advanceUnitStride() {
iter1_.advanceUnitStride(); iter1_.advanceUnitStride();
iter2_.advanceUnitStride(); iter2_.advanceUnitStride();
} }
bool canCollapse(int outerLoopRank, int innerLoopRank) const bool canCollapse(const int outerLoopRank,const int innerLoopRank) const
{ {
return iter1_.canCollapse(outerLoopRank, innerLoopRank) return iter1_.canCollapse(outerLoopRank, innerLoopRank)
&& iter2_.canCollapse(outerLoopRank, innerLoopRank); && iter2_.canCollapse(outerLoopRank, innerLoopRank);
} }
T_numtype operator[](int i) // this is needed for the stencil expression fastRead to work
{ return f_(iter1_[i], iter2_[i]); } void _bz_offsetData(sizeType i)
{ iter1_._bz_offsetData(i); iter2_._bz_offsetData(i); }
T_numtype fastRead(int i) // and these are needed for stencil expression shift to work
{ return f_(iter1_.fastRead(i), iter2_.fastRead(i)); } void _bz_offsetData(sizeType offset, int dim)
{
iter1_._bz_offsetData(offset, dim);
iter2_._bz_offsetData(offset, dim);
}
int suggestStride(int rank) const void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d im2)
{ {
int stride1 = iter1_.suggestStride(rank); iter1_._bz_offsetData(offset1, dim1, offset2, dim2);
int stride2 = iter2_.suggestStride(rank); iter2_._bz_offsetData(offset1, dim1, offset2, dim2);
}
diffType suggestStride(const int rank) const
{
diffType stride1 = iter1_.suggestStride(rank);
diffType stride2 = iter2_.suggestStride(rank);
return ( stride1>stride2 ? stride1 : stride2 ); return ( stride1>stride2 ? stride1 : stride2 );
} }
bool isStride(int rank, int stride) const bool isStride(const int rank,const diffType stride) const
{ {
return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) ; return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) ;
} }
void prettyPrint(BZ_STD_SCOPE(string) &str, void prettyPrint(BZ_STD_SCOPE(string) &str,
prettyPrintFormat& format) const prettyPrintFormat& format) const
{ {
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor);
str += "("; str += "(";
iter1_.prettyPrint(str, format); iter1_.prettyPrint(str, format);
skipping to change at line 381 skipping to change at line 665
} }
template<int N_rank> template<int N_rank>
void moveTo(const TinyVector<int,N_rank>& i) void moveTo(const TinyVector<int,N_rank>& i)
{ {
iter1_.moveTo(i); iter1_.moveTo(i);
iter2_.moveTo(i); iter2_.moveTo(i);
} }
template<typename T_shape> template<typename T_shape>
bool shapeCheck(const T_shape& shape) bool shapeCheck(const T_shape& shape) const
{ return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); } { return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape); }
// sliceinfo for expressions
template<typename T1, typename T2 = nilArraySection,
class T3 = nilArraySection, typename T4 = nilArraySection,
class T5 = nilArraySection, typename T6 = nilArraySection,
class T7 = nilArraySection, typename T8 = nilArraySection,
class T9 = nilArraySection, typename T10 = nilArraySection,
class T11 = nilArraySection>
class SliceInfo {
public:
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7
, T8, T9, T10, T11>::T_slice T_slice1;
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7
, T8, T9, T10, T11>::T_slice T_slice2;
typedef _bz_FunctorExpr2<T_functor, T_slice1, T_slice2, T_numtype> T_sl
ice;
};
template<typename T1, typename T2, typename T3, typename T4, typename T
5, typename T6,
typename T7, typename T8, typename T9, typename T10, typename T11>
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r
9, T10 r10, T11 r11) const
{
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic
e
(f_,iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11),
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11));
}
protected: protected:
_bz_FunctorExpr2() { } _bz_FunctorExpr2() { }
T_functor f_; T_functor f_;
T_expr1 iter1_; T_expr1 iter1_;
T_expr2 iter2_; T_expr2 iter2_;
}; };
template<typename P_functor, typename P_expr1, typename P_expr2, typename P _expr3, template<typename P_functor, typename P_expr1, typename P_expr2, typename P _expr3,
class P_result> class P_result>
skipping to change at line 405 skipping to change at line 713
{ {
public: public:
typedef P_functor T_functor; typedef P_functor T_functor;
typedef P_expr1 T_expr1; typedef P_expr1 T_expr1;
typedef P_expr2 T_expr2; typedef P_expr2 T_expr2;
typedef P_expr3 T_expr3; typedef P_expr3 T_expr3;
typedef _bz_typename T_expr1::T_numtype T_numtype1; typedef _bz_typename T_expr1::T_numtype T_numtype1;
typedef _bz_typename T_expr2::T_numtype T_numtype2; typedef _bz_typename T_expr2::T_numtype T_numtype2;
typedef _bz_typename T_expr3::T_numtype T_numtype3; typedef _bz_typename T_expr3::T_numtype T_numtype3;
typedef P_result T_numtype; typedef P_result T_numtype;
// select return type
typedef typename unwrapET<typename T_expr1::T_result>::T_unwrapped T_unwr
apped1;
typedef typename unwrapET<typename T_expr2::T_result>::T_unwrapped T_unwr
apped2;
typedef typename unwrapET<typename T_expr3::T_result>::T_unwrapped T_unwr
apped3;
typedef typename selectET2<typename T_expr1::T_typeprop,
typename T_expr2::T_typeprop,
T_numtype,
char>::T_selected T_intermediary;
typedef typename selectET2<T_intermediary,
typename T_expr3::T_typeprop,
T_numtype,
_bz_FunctorExpr3<P_functor,
typename asExpr<T_unwrapped1>:
:T_expr,
typename asExpr<T_unwrapped2>:
:T_expr,
typename asExpr<T_unwrapped3>:
:T_expr,
T_numtype> >::T_selected T_typ
eprop;
typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
typedef T_numtype T_optype;
typedef T_expr1 T_ctorArg1; typedef T_expr1 T_ctorArg1;
typedef T_expr2 T_ctorArg2; typedef T_expr2 T_ctorArg2;
typedef T_expr3 T_ctorArg3; typedef T_expr3 T_ctorArg3;
typedef _bz_FunctorExpr3<P_functor,
_bz_typename P_expr1::T_range_result,
_bz_typename P_expr2::T_range_result,
_bz_typename P_expr3::T_range_result,
P_result> T_range_result;
static const int static const int
numArrayOperands = T_expr1::numArrayOperands numArrayOperands = T_expr1::numArrayOperands
+ T_expr2::numArrayOperands + T_expr2::numArrayOperands
+ T_expr3::numArrayOperands, + T_expr3::numArrayOperands,
numTVOperands = T_expr1::numTVOperands +
T_expr2::numTVOperands +
T_expr3::numTVOperands,
numTMOperands = T_expr1::numTMOperands +
T_expr2::numTMOperands +
T_expr3::numTMOperands,
numIndexPlaceholders = T_expr1::numIndexPlaceholders numIndexPlaceholders = T_expr1::numIndexPlaceholders
+ T_expr2::numIndexPlaceholders + T_expr2::numIndexPlaceholders
+ T_expr3::numIndexPlaceholders, + T_expr3::numIndexPlaceholders,
rank12 = T_expr1::rank > T_expr2::rank minWidth = BZ_MIN(BZ_MIN(T_expr1::minWidth, T_expr2::minWidth),
? T_expr1::rank : T_expr2::rank, T_expr3::minWidth),
rank = rank12 > T_expr3::rank ? rank12 : T_expr3::rank; maxWidth = BZ_MAX(BZ_MAX(T_expr1::maxWidth, T_expr2::maxWidth),
T_expr3::maxWidth),
rank_ = BZ_MAX(BZ_MAX(T_expr1::rank_, T_expr2::rank_),
T_expr3::rank_);
template<int N> struct tvresult {
typedef _bz_FunctorExpr3<
T_functor,
typename T_expr1::template tvresult<N>::Type,
typename T_expr2::template tvresult<N>::Type,
typename T_expr3::template tvresult<N>::Type,
T_numtype> Type;
};
_bz_FunctorExpr3(const _bz_FunctorExpr3<P_functor, P_expr1, P_expr2, _bz_FunctorExpr3(const _bz_FunctorExpr3<P_functor, P_expr1, P_expr2,
P_expr3, P_result>& a) P_expr3, P_result>& a)
: f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_) : f_(a.f_), iter1_(a.iter1_), iter2_(a.iter2_), iter3_(a.iter3_)
{ } { }
_bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a, _bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T_expr1) a,
BZ_ETPARM(T_expr2) b, BZ_ETPARM(T_expr3) c) BZ_ETPARM(T_expr2) b, BZ_ETPARM(T_expr3) c)
: f_(f), iter1_(a), iter2_(b), iter3_(c) : f_(f), iter1_(a), iter2_(b), iter3_(c)
{ } { }
template<typename T1, typename T2, typename T3> template<typename T1, typename T2, typename T3>
_bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b, _bz_FunctorExpr3(BZ_ETPARM(T_functor) f, BZ_ETPARM(T1) a, BZ_ETPARM(T2) b,
BZ_ETPARM(T3) c) BZ_ETPARM(T3) c)
: f_(f), iter1_(a), iter2_(b), iter3_(c) : f_(f), iter1_(a), iter2_(b), iter3_(c)
{ } { }
T_numtype operator*() /* Functions for reading. Because they must depend on the result
{ return f_(*iter1_, *iter2_, *iter3_); } * type, they utilize a helper class.
*/
// For numtypes, apply operator
template<typename T> struct readHelper {
static T_result fastRead(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
diffType i) {
return f(iter1.fastRead(i), iter2.fastRead(i),
iter3.fastRead(i)); }
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
int i) {
return f(iter1[i], iter2[i], iter3[i]); }
static T_result deref(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3) {
return f(*iter1, *iter2, *iter3); };
static T_result first_value(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3)
{
return f(iter1.first_value(), iter2.first_value(),
iter3.first_value()); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
int offset, int dim) {
return f(iter1.shift(offset, dim),iter2.shift(offset, dim),
iter3.shift(offset, dim)); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
int offset1, int dim1,int offset2, int dim2) {
return f(iter1.shift(offset1, dim1, offset2, dim2),
iter2.shift(offset1, dim1, offset2, dim2),
iter2.shift(offset1, dim1, offset2, dim2)); }
template<int N_rank>
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
const TinyVector<int, N_rank> i) {
#else
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
const TinyVector<int, N_rank>& i) {
#endif
return f(iter1(i), iter2(i), iter3(i) ); };
};
// For ET types, bypass operator and create expression
template<typename T> struct readHelper<ETBase<T> > {
static T_result fastRead(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
diffType i) {
return T_result(f, iter1.fastRead(i), iter2.fastRead(i),
iter3.fastRead(i)); }
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
int i) {
return T_result(f, iter1[i], iter2[i], iter3[i]); };
static T_result deref(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3) {
return T_result(f, *iter1, *iter2, *iter3); };
static T_result first_value(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3)
{
return T_result(f, iter1.first_value(), iter2.first_value(),
iter3.first_value()); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
int offset, int dim) {
return T_result(f,iter1.shift(offset, dim),iter2.shift(offset, dim),
iter3.shift(offset, dim)); }
static T_result shift(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
int offset1, int dim1,int offset2, int dim2) {
return T_result(f, iter1.shift(offset1, dim1, offset2, dim2),
iter2.shift(offset1, dim1, offset2, dim2),
iter2.shift(offset1, dim1, offset2, dim2)); }
template<int N_rank>
#ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
template<int N_rank> static T_result indexop(const T_functor& f, const T_expr1& iter1,
T_numtype operator()(TinyVector<int, N_rank> i) const T_expr2& iter2, const T_expr3& iter3,
{ return f_(iter1_(i), iter2_(i), iter3_(i)); } const TinyVector<int, N_rank> i) {
#else #else
static T_result indexop(const T_functor& f, const T_expr1& iter1,
const T_expr2& iter2, const T_expr3& iter3,
const TinyVector<int, N_rank>& i) {
#endif
return T_result(f, iter1(i), iter2(i), iter3(i) ); }
};
T_result fastRead(diffType i) const {
return readHelper<T_typeprop>::fastRead(f_, iter1_, iter2_, iter3_, i
); }
template<int N>
typename tvresult<N>::Type fastRead_tv(diffType i) const
{ return typename tvresult<N>::Type(f_,
iter1_.template fastRead_tv<N>(i),
iter2_.template fastRead_tv<N>(i),
iter3_.template fastRead_tv<N>(i))
; }
T_result operator[](int i) const {
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, iter3_, i)
; }
template<int N_rank> template<int N_rank>
T_numtype operator()(const TinyVector<int, N_rank>& i) #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE
{ return f_(iter1_(i), iter2_(i), iter3_(i)); } T_result operator()(const TinyVector<int, N_rank> i) const {
#else
T_result operator()(const TinyVector<int, N_rank>& i) const {
#endif #endif
return readHelper<T_typeprop>::indexop(f_, iter1_, iter2_, iter3_, i ); }
int ascending(int rank) T_result operator*() const {
{ return readHelper<T_typeprop>::deref(f_, iter1_, iter2_, iter3_); }
T_result first_value() const {
return readHelper<T_typeprop>::first_value(f_, iter1_, iter2_, iter3
_); }
T_result shift(int offset, int dim) const {
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_,
iter3_, offset, dim); }
T_result shift(int offset1, int dim1,int offset2, int dim2) const {
return readHelper<T_typeprop>::shift(f_,iter1_,iter2_,iter3_,
offset1, dim1, offset2, dim2); }
// ****** end reading
bool isVectorAligned(diffType offset) const
{ return iter1_.isVectorAligned(offset) &&
iter2_.isVectorAligned(offset) &&
iter3_.isVectorAligned(offset); }
T_range_result operator()(RectDomain<rank_> d) const
{
return T_range_result(f_, iter1_(d), iter2_(d), iter3_(d));
}
int ascending(const int rank) const {
return bounds::compute_ascending(rank, iter1_.ascending(rank), return bounds::compute_ascending(rank, iter1_.ascending(rank),
bounds::compute_ascending(rank, iter2_.ascending(rank), bounds::compute_ascending(rank, iter2_.ascending(rank),
iter3_.ascending(rank))); iter3_.ascending(rank)));
} }
int ordering(int rank) int ordering(const int rank) const {
{
return bounds::compute_ordering(rank, iter1_.ordering(rank), return bounds::compute_ordering(rank, iter1_.ordering(rank),
bounds::compute_ordering(rank, iter2_.ordering(rank), bounds::compute_ordering(rank, iter2_.ordering(rank),
iter3_.ordering(rank))); iter3_.ordering(rank)));
} }
int lbound(int rank) int lbound(const int rank) const {
{
return bounds::compute_lbound(rank, iter1_.lbound(rank), return bounds::compute_lbound(rank, iter1_.lbound(rank),
bounds::compute_lbound(rank, iter2_.lbound(rank), bounds::compute_lbound(rank, iter2_.lbound(rank),
iter3_.lbound(rank))); iter3_.lbound(rank)));
} }
int ubound(int rank) int ubound(const int rank) const {
{
return bounds::compute_ubound(rank, iter1_.ubound(rank), return bounds::compute_ubound(rank, iter1_.ubound(rank),
bounds::compute_ubound(rank, iter2_.ubound(rank), bounds::compute_ubound(rank, iter2_.ubound(rank),
iter3_.ubound(rank))); iter3_.ubound(rank)));
} }
void push(int position) // defer calculation to lbound/ubound
{ RectDomain<rank_> domain() const
{
TinyVector<int, rank_> lb, ub;
for(int r=0; r<rank_; ++r) {
lb[r]=lbound(r); ub[r]=ubound(r);
}
return RectDomain<rank_>(lb,ub);
}
void push(const int position) {
iter1_.push(position); iter1_.push(position);
iter2_.push(position); iter2_.push(position);
iter3_.push(position); iter3_.push(position);
} }
void pop(int position) void pop(const int position) {
{
iter1_.pop(position); iter1_.pop(position);
iter2_.pop(position); iter2_.pop(position);
iter3_.pop(position); iter3_.pop(position);
} }
void advance() void advance() {
{
iter1_.advance(); iter1_.advance();
iter2_.advance(); iter2_.advance();
iter3_.advance(); iter3_.advance();
} }
void advance(int n) void advance(const int n) {
{
iter1_.advance(n); iter1_.advance(n);
iter2_.advance(n); iter2_.advance(n);
iter3_.advance(n); iter3_.advance(n);
} }
void loadStride(int rank) void loadStride(const int rank) {
{
iter1_.loadStride(rank); iter1_.loadStride(rank);
iter2_.loadStride(rank); iter2_.loadStride(rank);
iter3_.loadStride(rank); iter3_.loadStride(rank);
} }
bool isUnitStride(int rank) const bool isUnitStride(const int rank) const {
{
return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank) return iter1_.isUnitStride(rank) && iter2_.isUnitStride(rank)
&& iter3_.isUnitStride(rank); && iter3_.isUnitStride(rank);
} }
void advanceUnitStride() bool isUnitStride() const {
{ return iter1_.isUnitStride() && iter2_.isUnitStride()
&& iter3_.isUnitStride();
}
void advanceUnitStride() {
iter1_.advanceUnitStride(); iter1_.advanceUnitStride();
iter2_.advanceUnitStride(); iter2_.advanceUnitStride();
iter3_.advanceUnitStride(); iter3_.advanceUnitStride();
} }
bool canCollapse(int outerLoopRank, int innerLoopRank) const bool canCollapse(const int outerLoopRank,const int innerLoopRank) const
{ {
return iter1_.canCollapse(outerLoopRank, innerLoopRank) return iter1_.canCollapse(outerLoopRank, innerLoopRank)
&& iter2_.canCollapse(outerLoopRank, innerLoopRank) && iter2_.canCollapse(outerLoopRank, innerLoopRank)
&& iter3_.canCollapse(outerLoopRank, innerLoopRank); && iter3_.canCollapse(outerLoopRank, innerLoopRank);
} }
T_numtype operator[](int i) // this is needed for the stencil expression fastRead to work
{ return f_(iter1_[i], iter2_[i], iter3_[i]); } void _bz_offsetData(sizeType i)
{ iter1_._bz_offsetData(i); iter2_._bz_offsetData(i);
iter3_._bz_offsetData(i); }
T_numtype fastRead(int i) // and these are needed for stencil expression shift to work
{ return f_(iter1_.fastRead(i), iter2_.fastRead(i), iter3_.fastRead(i)) void _bz_offsetData(sizeType offset, int dim)
; } {
iter1_._bz_offsetData(offset, dim);
iter2_._bz_offsetData(offset, dim);
iter3_._bz_offsetData(offset, dim);
}
int suggestStride(int rank) const void _bz_offsetData(sizeType offset1, int dim1, sizeType offset2, int d im2)
{ {
int stride1 = iter1_.suggestStride(rank); iter1_._bz_offsetData(offset1, dim1, offset2, dim2);
int stride2 = iter2_.suggestStride(rank); iter2_._bz_offsetData(offset1, dim1, offset2, dim2);
int stride3 = iter3_.suggestStride(rank); iter3_._bz_offsetData(offset1, dim1, offset2, dim2);
}
diffType suggestStride(const int rank) const {
diffType stride1 = iter1_.suggestStride(rank);
diffType stride2 = iter2_.suggestStride(rank);
diffType stride3 = iter3_.suggestStride(rank);
return ( stride1 > (stride2 = (stride2>stride3 ? stride2 : stride3)) ? return ( stride1 > (stride2 = (stride2>stride3 ? stride2 : stride3)) ?
stride1 : stride2 ); stride1 : stride2 );
} }
bool isStride(int rank, int stride) const bool isStride(const int rank,const diffType stride) const {
{
return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride) return iter1_.isStride(rank,stride) && iter2_.isStride(rank,stride)
&& iter3_.isStride(rank,stride); && iter3_.isStride(rank,stride);
} }
void prettyPrint(BZ_STD_SCOPE(string) &str, void prettyPrint(BZ_STD_SCOPE(string) &str,
prettyPrintFormat& format) const prettyPrintFormat& format) const
{ {
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor); str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_functor);
str += "("; str += "(";
iter1_.prettyPrint(str, format); iter1_.prettyPrint(str, format);
skipping to change at line 575 skipping to change at line 1064
template<int N_rank> template<int N_rank>
void moveTo(const TinyVector<int,N_rank>& i) void moveTo(const TinyVector<int,N_rank>& i)
{ {
iter1_.moveTo(i); iter1_.moveTo(i);
iter2_.moveTo(i); iter2_.moveTo(i);
iter3_.moveTo(i); iter3_.moveTo(i);
} }
template<typename T_shape> template<typename T_shape>
bool shapeCheck(const T_shape& shape) bool shapeCheck(const T_shape& shape) const
{ {
return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape) return iter1_.shapeCheck(shape) && iter2_.shapeCheck(shape)
&& iter3_.shapeCheck(shape); && iter3_.shapeCheck(shape);
} }
// sliceinfo for expressions
template<typename T1, typename T2 = nilArraySection,
class T3 = nilArraySection, typename T4 = nilArraySection,
class T5 = nilArraySection, typename T6 = nilArraySection,
class T7 = nilArraySection, typename T8 = nilArraySection,
class T9 = nilArraySection, typename T10 = nilArraySection,
class T11 = nilArraySection>
class SliceInfo {
public:
typedef typename T_expr1::template SliceInfo<T1, T2, T3, T4, T5, T6, T7
, T8, T9, T10, T11>::T_slice T_slice1;
typedef typename T_expr2::template SliceInfo<T1, T2, T3, T4, T5, T6, T7
, T8, T9, T10, T11>::T_slice T_slice2;
typedef typename T_expr3::template SliceInfo<T1, T2, T3, T4, T5, T6, T7
, T8, T9, T10, T11>::T_slice T_slice3;
typedef _bz_FunctorExpr3<T_functor, T_slice1, T_slice2, T_slice3, T_num
type> T_slice;
};
template<typename T1, typename T2, typename T3, typename T4, typename T
5, typename T6,
typename T7, typename T8, typename T9, typename T10, typename T11>
typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice
operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r
9, T10 r10, T11 r11) const
{
return typename SliceInfo<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slic
e
(f_,iter1_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11),
iter2_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11),
iter3_(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11));
}
protected: protected:
_bz_FunctorExpr3() { } _bz_FunctorExpr3() { }
T_functor f_; T_functor f_;
T_expr1 iter1_; T_expr1 iter1_;
T_expr2 iter2_; T_expr2 iter2_;
T_expr3 iter3_; T_expr3 iter3_;
}; };
template<typename P_functor, typename P_expr> template<typename P_functor, typename P_expr>
skipping to change at line 651 skipping to change at line 1166
BZ_NAMESPACE_END // End of stuff in namespace BZ_NAMESPACE_END // End of stuff in namespace
#define _BZ_MAKE_FUNCTOR(classname, funcname) \ #define _BZ_MAKE_FUNCTOR(classname, funcname) \
class _bz_Functor ## classname ## funcname \ class _bz_Functor ## classname ## funcname \
{ \ { \
public: \ public: \
_bz_Functor ## classname ## funcname (const classname& c) \ _bz_Functor ## classname ## funcname (const classname& c) \
: c_(c) \ : c_(c) \
{ } \ { } \
template<typename T_numtype1> \ template<typename T_numtype1> \
inline T_numtype1 operator()(T_numtype1 x) const \ inline T_numtype1 operator()(T_numtype1 x) const \
{ return c_.funcname(x); } \ { return c_.funcname(x); } \
private: \ private: \
const classname& c_; \ const classname& c_; \
}; };
#define _BZ_MAKE_FUNCTOR2(classname, funcname) \ #define _BZ_MAKE_FUNCTOR2(classname, funcname) \
class _bz_Functor ## classname ## funcname \ class _bz_Functor ## classname ## funcname \
{ \ { \
public: \ public: \
skipping to change at line 735 skipping to change at line 1250
{ return c_.funcname(x,y,z); } \ { return c_.funcname(x,y,z); } \
private: \ private: \
const classname& c_; \ const classname& c_; \
}; };
#define BZ_DECLARE_FUNCTOR(classname) \ #define BZ_DECLARE_FUNCTOR(classname) \
template<typename P_expr> \ template<typename P_expr> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \
classname, \ classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr)<classname, \ BZ_BLITZ_SCOPE(_bz_FunctorExpr)<classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \
(*this, a.unwrap()); \ (*this, a.unwrap()); \
} }
#define BZ_DECLARE_FUNCTOR2(classname) \ #define BZ_DECLARE_FUNCTOR2(classname) \
template<typename P_expr1, typename P_expr2> \ template<typename P_expr1, typename P_expr2> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \
classname, \ classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<classname, \ BZ_BLITZ_SCOPE(_bz_FunctorExpr2)<classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \
(*this, a.unwrap(), b.unwrap()); \ (*this, a.unwrap(), b.unwrap()); \
} }
#define BZ_DECLARE_FUNCTOR3(classname) \ #define BZ_DECLARE_FUNCTOR3(classname) \
template<typename P_expr1, typename P_expr2, typename P_expr3> \ template<typename P_expr1, typename P_expr2, typename P_expr3> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \
classname, \ classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> > \ BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> > \
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<classname, \ BZ_BLITZ_SCOPE(_bz_FunctorExpr3)<classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >\ BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> >\
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ (*this, a.unwrap(), b.unwrap(), c.unwrap()); \
} }
#define BZ_DECLARE_FUNCTOR_RET(classname, ret) \ #define BZ_DECLARE_FUNCTOR_RET(classname, ret) \
template<typename P_expr> \ template<typename P_expr> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \
classname, \ classname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \
ret> > \ ret> > \
operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ operator()(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \
skipping to change at line 860 skipping to change at line 1375
ret> > \ ret> > \
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ (*this, a.unwrap(), b.unwrap(), c.unwrap()); \
} }
#define BZ_DECLARE_MEMBER_FUNCTION(classname, funcname) \ #define BZ_DECLARE_MEMBER_FUNCTION(classname, funcname) \
_BZ_MAKE_FUNCTOR(classname, funcname) \ _BZ_MAKE_FUNCTOR(classname, funcname) \
template<typename P_expr> \ template<typename P_expr> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_numtype> > \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr::T_optype> > \
(*this, a.unwrap()); \ (_bz_Functor ## classname ## funcname(*this), a.unwrap()); \
} }
#define BZ_DECLARE_MEMBER_FUNCTION2(classname, funcname) \ #define BZ_DECLARE_MEMBER_FUNCTION2(classname, funcname) \
_BZ_MAKE_FUNCTOR2(classname, funcname) \ _BZ_MAKE_FUNCTOR2(classname, funcname) \
template<typename P_expr1, typename P_expr2> \ template<typename P_expr1, typename P_expr2> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype)> > \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype)> > \
(*this, a.unwrap(), b.unwrap()); \ (_bz_Functor ## classname ## funcname(*this), a.unwrap(), b.unwrap())
; \
} }
#define BZ_DECLARE_MEMBER_FUNCTION3(classname, funcname) \ #define BZ_DECLARE_MEMBER_FUNCTION3(classname, funcname) \
_BZ_MAKE_FUNCTOR3(classname, funcname) \ _BZ_MAKE_FUNCTOR3(classname, funcname) \
template<typename P_expr1, typename P_expr2, typename P_expr3> \ template<typename P_expr1, typename P_expr2, typename P_expr3> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> > \ BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> > \
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr::T_optype, \
BZ_PROMOTE(_bz_typename \ BZ_PROMOTE(_bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_numtype, \ BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr::T_optype, \
_bz_typename \ _bz_typename \
BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_numtype))> >\ BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr::T_optype))> >\
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ (_bz_Functor ## classname ## funcname(*this), \
a.unwrap(), b.unwrap(), c.unwrap()); \
} }
#define BZ_DECLARE_MEMBER_FUNCTION_RET(classname, funcname, ret) \ #define BZ_DECLARE_MEMBER_FUNCTION_RET(classname, funcname, ret) \
_BZ_MAKE_FUNCTOR_RET(classname, funcname, ret) \ _BZ_MAKE_FUNCTOR_RET(classname, funcname, ret) \
template<typename P_expr> \ template<typename P_expr> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \
ret> > \ ret> > \
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \ funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr>& a) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \ BZ_BLITZ_SCOPE(_bz_FunctorExpr)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr>::T_expr, ret> > \
ret> > \ (_bz_Functor ## classname ## funcname(*this), a.unwrap()); \
(*this, a.unwrap()); \
} }
#define BZ_DECLARE_MEMBER_FUNCTION2_RET(classname, funcname, ret) \ #define BZ_DECLARE_MEMBER_FUNCTION2_RET(classname, funcname, ret) \
_BZ_MAKE_FUNCTOR2_RET(classname, funcname, ret) \ _BZ_MAKE_FUNCTOR2_RET(classname, funcname, ret) \
template<typename P_expr1, typename P_expr2> \ template<typename P_expr1, typename P_expr2> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
ret> > \ ret> > \
funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \ funcname(const BZ_BLITZ_SCOPE(ETBase)<P_expr1>& a, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \ const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \ BZ_BLITZ_SCOPE(_bz_FunctorExpr2)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
ret> > \ ret> > \
(*this, a.unwrap(), b.unwrap()); \ (_bz_Functor ## classname ## funcname(*this), a.unwrap(), b.unwrap()) ; \
} }
#define BZ_DECLARE_MEMBER_FUNCTION3_RET(classname, funcname, ret) \ #define BZ_DECLARE_MEMBER_FUNCTION3_RET(classname, funcname, ret) \
_BZ_MAKE_FUNCTOR3_RET(classname, funcname, ret) \ _BZ_MAKE_FUNCTOR3_RET(classname, funcname, ret) \
template<typename P_expr1, typename P_expr2, typename P_expr3> \ template<typename P_expr1, typename P_expr2, typename P_expr3> \
BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ BZ_BLITZ_SCOPE(_bz_ArrayExpr)<BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \
skipping to change at line 987 skipping to change at line 1502
const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \ const BZ_BLITZ_SCOPE(ETBase)<P_expr2>& b, \
const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \ const BZ_BLITZ_SCOPE(ETBase)<P_expr3>& c) const \
{ \ { \
return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \ return BZ_BLITZ_SCOPE(_bz_ArrayExpr)< \
BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \ BZ_BLITZ_SCOPE(_bz_FunctorExpr3)< \
_bz_Functor ## classname ## funcname, \ _bz_Functor ## classname ## funcname, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr1>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr2>::T_expr, \
_bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \ _bz_typename BZ_BLITZ_SCOPE(asExpr)<P_expr3>::T_expr, \
ret> > \ ret> > \
(*this, a.unwrap(), b.unwrap(), c.unwrap()); \ (_bz_Functor ## classname ## funcname(*this), \
a.unwrap(), b.unwrap(), c.unwrap()); \
} }
#endif // BZ_ARRAY_FUNCTOREXPR_H #endif // BZ_ARRAY_FUNCTOREXPR_H
 End of changes. 125 change blocks. 
172 lines changed or deleted 733 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/