/*************************************************************************** * blitz/array/iter.h Declaration of ArrayIterator * * $Id: iter.h,v 1.1.1.1 1999-11-26 16:37:07 ansari Exp $ * * Copyright (C) 1997,1998 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-suggest@cybervision.com * Bugs: blitz-bugs@cybervision.com * * For more information, please see the Blitz++ Home Page: * http://seurat.uwaterloo.ca/blitz/ * *************************************************************************** * $Log: not supported by cvs2svn $ * Revision 1.1.1.1 1999/04/09 17:59:03 ansari * Creation module DPC/Blitz (blitz 0.4) Reza 09/04/99 * * Revision 1.2 1998/03/14 00:04:47 tveldhui * 0.2-alpha-05 * * Revision 1.1 1997/07/16 14:51:20 tveldhui * Update: Alpha release 0.2 (Arrays) * */ #ifndef BZ_ARRAYITER_H #define BZ_ARRAYITER_H #ifdef BZ_HAVE_STD #include #else #include #endif BZ_NAMESPACE(blitz) #ifndef BZ_ARRAY_H #error must be included via #endif template class ArrayIterator { public: typedef P_numtype T_numtype; typedef Array T_array; typedef ArrayIterator T_iterator; typedef const T_array& T_ctorArg1; typedef int T_ctorArg2; // dummy enum { numArrayOperands = 1, numIndexPlaceholders = 0, rank = N_rank }; // NB: this ctor does NOT preserve stack and stride // parameters. This is for speed purposes. ArrayIterator(const ArrayIterator& x) : array_(x.array_), data_(x.data_) { } void operator=(const ArrayIterator& x) { array_ = x.array_; data_ = x.data_; stack_ = x.stack_; stride_ = x.stride_; } ArrayIterator(const T_array& array) : array_(array) { data_ = array.data(); } ~ArrayIterator() { } #ifdef BZ_ARRAY_EXPR_PASS_INDEX_BY_VALUE T_numtype operator()(TinyVector i) { return array_(i); } #else T_numtype operator()(const TinyVector& i) { return array_(i); } #endif int lbound(int rank) { if (rank < N_rank) return array_.lbound(rank); else return INT_MIN; // tiny(int()); } int ubound(int rank) { if (rank < N_rank) return array_.ubound(rank); else return INT_MAX; // huge(int()); } T_numtype operator*() { return *data_; } T_numtype operator[](int i) { return data_[i * stride_]; } T_numtype fastRead(int i) { return data_[i]; } int suggestStride(int rank) const { return array_.stride(rank); } _bz_bool isStride(int rank, int stride) const { return array_.stride(rank) == stride; } void push(int position) { stack_[position] = data_; } void pop(int position) { data_ = stack_[position]; } void advance() { data_ += stride_; } void advance(int n) { data_ += n * stride_; } void loadStride(int rank) { stride_ = array_.stride(rank); } const T_numtype * _bz_restrict data() const { return data_; } int stride() const { return stride_; } _bz_bool isUnitStride(int rank) const { return array_.stride(rank) == 1; } void advanceUnitStride() { ++data_; } _bz_bool canCollapse(int outerLoopRank, int innerLoopRank) const { return array_.canCollapse(outerLoopRank, innerLoopRank); } void prettyPrint(string& str, prettyPrintFormat& format) const { if (format.tersePrintingSelected()) str += format.nextArrayOperandSymbol(); else if (format.dumpArrayShapesMode()) { ostrstream ostr; ostr << array_.shape(); str += ostr.str(); } else { str += "Array<"; str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_numtype); str += ","; char tmpBuf[10]; sprintf(tmpBuf, "%d", N_rank); str += tmpBuf; str += ">"; } } template _bz_bool shapeCheck(const T_shape& shape) { return areShapesConformable(shape, array_.length()); } // Experimental T_numtype& operator()(int i, int j) { return (T_numtype&)data_[i*array_.stride(0) + j*array_.stride(1)]; } // Experimental T_numtype& operator()(int i, int j, int k) { return (T_numtype&)data_[i*array_.stride(0) + j*array_.stride(1) + k*array_.stride(2)]; } // Experimental void moveTo(int i, int j) { data_ = &const_cast(array_)(i,j); } void moveTo(int i, int j, int k) { data_ = &const_cast(array_)(i,j,k); } void moveTo(const TinyVector& i) { data_ = &const_cast(array_)(i); } // Experimental void operator=(T_numtype x) { *const_cast(data_) = x; } // Experimental template void operator=(T_value x) { *const_cast(data_) = x; } // Experimental template void operator+=(T_value x) { *const_cast(data_) += x; } // NEEDS_WORK: other operators // Experimental operator T_numtype() const { return *data_; } // Experimental T_numtype shift(int offset, int dim) { return data_[offset*array_.stride(dim)]; } // Experimental T_numtype shift(int offset1, int dim1, int offset2, int dim2) { return data_[offset1*array_.stride(dim1) + offset2*array_.stride(dim2)]; } private: const T_array& array_; const T_numtype * _bz_restrict data_; const T_numtype * _bz_restrict stack_[N_rank]; int stride_; }; BZ_NAMESPACE_END #endif // BZ_ARRAYITER_H