// -*- C++ -*- /*************************************************************************** * blitz/array-impl.h Definition of the Array class * * $Id: array-impl.h 1414 2005-11-01 22:04:59Z cookedm $ * * Copyright (C) 1997-2001 Todd Veldhuizen * * This code was relicensed under the modified BSD license for use in SciPy * by Todd Veldhuizen (see LICENSE.txt in the weave directory). * * * Suggestions: blitz-dev@oonumerics.org * Bugs: blitz-bugs@oonumerics.org * * For more information, please see the Blitz++ Home Page: * http://oonumerics.org/blitz/ * ***************************************************************************/ /* * Wish list for array classes. * - Arrays whose dimensions are unknown at compile time. * - where()/elsewhere()/elsewhere() as in Dan Quinlan's implementation * - block reduction operations * - conversion to/from matrix & vector * - apply(T func(T)) * - apply(T func(const T&)) * - apply */ #ifndef BZ_ARRAY_H #define BZ_ARRAY_H #include #include #include #include #ifdef BZ_ARRAY_SPACE_FILLING_TRAVERSAL #include #endif #include #include #include // Subarrays and slicing #include // Tensor index notation #include // Multicomponent arrays #include // RectDomain class #include // GeneralArrayStorage BZ_NAMESPACE(blitz) /* * Forward declarations */ template class ArrayIterator; template class ConstArrayIterator; template class FastArrayIterator; template class _bz_ArrayExpr; template class IndirectArray; template void swap(Array&,Array&); template void find(Array,1>&,const Array&); /* * Declaration of class Array */ // NEEDS_WORK: Array should inherit protected from MemoryBlockReference. // To make this work, need to expose MemoryBlockReference::numReferences() // and make Array a friend of Array for slicing. template class Array : public MemoryBlockReference #ifdef BZ_NEW_EXPRESSION_TEMPLATES , public ETBase > #endif { private: typedef MemoryBlockReference T_base; using T_base::data_; using T_base::changeToNullBlock; using T_base::numReferences; public: ////////////////////////////////////////////// // Public Types ////////////////////////////////////////////// /* * T_numtype is the numeric type stored in the array. * T_index is a vector type which can be used to access elements * of many-dimensional arrays. * T_array is the array type itself -- Array * T_iterator is a a fast iterator for the array, used for expression * templates * iterator is a STL-style iterator * const_iterator is an STL-style const iterator */ typedef P_numtype T_numtype; typedef TinyVector T_index; typedef Array T_array; typedef FastArrayIterator T_iterator; typedef ArrayIterator iterator; typedef ConstArrayIterator const_iterator; static const int _bz_rank = N_rank; ////////////////////////////////////////////// // Constructors // ////////////////////////////////////////////// /* * Construct an array from an array expression. */ template explicit Array(_bz_ArrayExpr expr); /* * Any missing length arguments will have their value taken from the * last argument. For example, * Array A(32,64); * will create a 32x64x64 array. This is handled by setupStorage(). */ Array(GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { length_ = 0; stride_ = 0; zeroOffset_ = 0; } explicit Array(int length0, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { length_[0] = length0; setupStorage(0); } Array(int length0, int length1, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 2); TAU_TYPE_STRING(p1, "Array::Array() [T=" + CT(T_numtype) + ",N=" + CT(N_rank) + "]"); TAU_PROFILE(p1, "void (int,int)", TAU_BLITZ); length_[0] = length0; length_[1] = length1; setupStorage(1); } Array(int length0, int length1, int length2, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 3); length_[0] = length0; length_[1] = length1; length_[2] = length2; setupStorage(2); } Array(int length0, int length1, int length2, int length3, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 4); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; setupStorage(3); } Array(int length0, int length1, int length2, int length3, int length4, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 5); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; setupStorage(4); } Array(int length0, int length1, int length2, int length3, int length4, int length5, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 6); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; length_[5] = length5; setupStorage(5); } Array(int length0, int length1, int length2, int length3, int length4, int length5, int length6, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 7); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; length_[5] = length5; length_[6] = length6; setupStorage(6); } Array(int length0, int length1, int length2, int length3, int length4, int length5, int length6, int length7, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 8); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; length_[5] = length5; length_[6] = length6; length_[7] = length7; setupStorage(7); } Array(int length0, int length1, int length2, int length3, int length4, int length5, int length6, int length7, int length8, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 9); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; length_[5] = length5; length_[6] = length6; length_[7] = length7; length_[8] = length8; setupStorage(8); } Array(int length0, int length1, int length2, int length3, int length4, int length5, int length6, int length7, int length8, int length9, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 10); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; length_[5] = length5; length_[6] = length6; length_[7] = length7; length_[8] = length8; length_[9] = length9; setupStorage(9); } Array(int length0, int length1, int length2, int length3, int length4, int length5, int length6, int length7, int length8, int length9, int length10, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(N_rank >= 11); length_[0] = length0; length_[1] = length1; length_[2] = length2; length_[3] = length3; length_[4] = length4; length_[5] = length5; length_[6] = length6; length_[7] = length7; length_[8] = length8; length_[9] = length9; length_[10] = length10; setupStorage(10); } /* * Construct an array from an existing block of memory. Ownership * is not acquired (this is provided for backwards compatibility). */ Array(T_numtype* restrict dataFirst, TinyVector shape, GeneralArrayStorage storage = GeneralArrayStorage()) : MemoryBlockReference(product(shape), dataFirst, neverDeleteData), storage_(storage) { BZPRECONDITION(dataFirst != 0); length_ = shape; computeStrides(); data_ += zeroOffset_; } /* * Construct an array from an existing block of memory, with a * given set of strides. Ownership is not acquired (i.e. the memory * block will not be freed by Blitz++). */ Array(T_numtype* restrict dataFirst, TinyVector shape, TinyVector stride, GeneralArrayStorage storage = GeneralArrayStorage()) : MemoryBlockReference(product(shape), dataFirst, neverDeleteData), storage_(storage) { BZPRECONDITION(dataFirst != 0); length_ = shape; stride_ = stride; calculateZeroOffset(); data_ += zeroOffset_; } /* * Construct an array from an existing block of memory. */ Array(T_numtype* restrict dataFirst, TinyVector shape, preexistingMemoryPolicy deletionPolicy, GeneralArrayStorage storage = GeneralArrayStorage()) : MemoryBlockReference(product(shape), dataFirst, deletionPolicy), storage_(storage) { BZPRECONDITION(dataFirst != 0); length_ = shape; computeStrides(); data_ += zeroOffset_; if (deletionPolicy == duplicateData) reference(copy()); } /* * Construct an array from an existing block of memory, with a * given set of strides. */ Array(T_numtype* restrict dataFirst, TinyVector shape, TinyVector stride, preexistingMemoryPolicy deletionPolicy, GeneralArrayStorage storage = GeneralArrayStorage()) : MemoryBlockReference(product(shape), dataFirst, deletionPolicy), storage_(storage) { BZPRECONDITION(dataFirst != 0); length_ = shape; stride_ = stride; calculateZeroOffset(); data_ += zeroOffset_; if (deletionPolicy == duplicateData) reference(copy()); } /* * This constructor takes an extent (length) vector and storage format. */ Array(const TinyVector& extent, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { length_ = extent; setupStorage(N_rank - 1); } /* * This construct takes a vector of bases (lbounds) and a vector of * extents. */ Array(const TinyVector& lbounds, const TinyVector& extent, const GeneralArrayStorage& storage = GeneralArrayStorage()); /* * These constructors allow arbitrary bases (starting indices) to be set. * e.g. Array A(Range(10,20), Range(20,30)) * will create an 11x11 array whose indices are 10..20 and 20..30 */ Array(Range r0, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); setupStorage(0); } Array(Range r0, Range r1, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); setupStorage(1); } Array(Range r0, Range r1, Range r2, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); setupStorage(2); } Array(Range r0, Range r1, Range r2, Range r3, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); setupStorage(3); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); setupStorage(4); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous() && r5.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); length_[5] = r5.length(); storage_.setBase(5, r5.first()); setupStorage(5); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous() && r5.isAscendingContiguous() && r6.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); length_[5] = r5.length(); storage_.setBase(5, r5.first()); length_[6] = r6.length(); storage_.setBase(6, r6.first()); setupStorage(6); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous() && r5.isAscendingContiguous() && r6.isAscendingContiguous() && r7.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); length_[5] = r5.length(); storage_.setBase(5, r5.first()); length_[6] = r6.length(); storage_.setBase(6, r6.first()); length_[7] = r7.length(); storage_.setBase(7, r7.first()); setupStorage(7); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous() && r5.isAscendingContiguous() && r6.isAscendingContiguous() && r7.isAscendingContiguous() && r8.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); length_[5] = r5.length(); storage_.setBase(5, r5.first()); length_[6] = r6.length(); storage_.setBase(6, r6.first()); length_[7] = r7.length(); storage_.setBase(7, r7.first()); length_[8] = r8.length(); storage_.setBase(8, r8.first()); setupStorage(8); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous() && r5.isAscendingContiguous() && r6.isAscendingContiguous() && r7.isAscendingContiguous() && r8.isAscendingContiguous() && r9.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); length_[5] = r5.length(); storage_.setBase(5, r5.first()); length_[6] = r6.length(); storage_.setBase(6, r6.first()); length_[7] = r7.length(); storage_.setBase(7, r7.first()); length_[8] = r8.length(); storage_.setBase(8, r8.first()); length_[9] = r9.length(); storage_.setBase(9, r9.first()); setupStorage(9); } Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, Range r10, GeneralArrayStorage storage = GeneralArrayStorage()) : storage_(storage) { BZPRECONDITION(r0.isAscendingContiguous() && r1.isAscendingContiguous() && r2.isAscendingContiguous() && r3.isAscendingContiguous() && r4.isAscendingContiguous() && r5.isAscendingContiguous() && r6.isAscendingContiguous() && r7.isAscendingContiguous() && r8.isAscendingContiguous() && r9.isAscendingContiguous() && r10.isAscendingContiguous()); length_[0] = r0.length(); storage_.setBase(0, r0.first()); length_[1] = r1.length(); storage_.setBase(1, r1.first()); length_[2] = r2.length(); storage_.setBase(2, r2.first()); length_[3] = r3.length(); storage_.setBase(3, r3.first()); length_[4] = r4.length(); storage_.setBase(4, r4.first()); length_[5] = r5.length(); storage_.setBase(5, r5.first()); length_[6] = r6.length(); storage_.setBase(6, r6.first()); length_[7] = r7.length(); storage_.setBase(7, r7.first()); length_[8] = r8.length(); storage_.setBase(8, r8.first()); length_[9] = r9.length(); storage_.setBase(9, r9.first()); length_[10] = r10.length(); storage_.setBase(10, r10.first()); setupStorage(10); } /* * Create a reference of another array */ Array(const Array& array) #ifdef BZ_NEW_EXPRESSION_TEMPLATES : MemoryBlockReference(), ETBase< Array >(array) #else : MemoryBlockReference() #endif { // NEEDS_WORK: this const_cast is a tad ugly. reference(const_cast(array)); } /* * These constructors are used for creating interlaced arrays (see * */ Array(const TinyVector& shape, int lastExtent, const GeneralArrayStorage& storage); //Array(const TinyVector& shape, // int lastExtent, const GeneralArrayStorage& storage); /* * These constructors make the array a view of a subportion of another * array. If there fewer than N_rank Range arguments provided, no * slicing is performed in the unspecified ranks. * e.g. Array A(20,20,20); * Array B(A, Range(5,15)); * is equivalent to: * Array B(A, Range(5,15), Range::all(), Range::all()); */ Array(Array& array, Range r0) { constructSubarray(array, r0); } Array(Array& array, Range r0, Range r1) { constructSubarray(array, r0, r1); } Array(Array& array, Range r0, Range r1, Range r2) { constructSubarray(array, r0, r1, r2); } Array(Array& array, Range r0, Range r1, Range r2, Range r3) { constructSubarray(array, r0, r1, r2, r3); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4) { constructSubarray(array, r0, r1, r2, r3, r4); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5) { constructSubarray(array, r0, r1, r2, r3, r4, r5); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6) { constructSubarray(array, r0, r1, r2, r3, r4, r5, r6); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7) { constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8) { constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9) { constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9); } Array(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, Range r10) { constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10); } Array(Array& array, const RectDomain& subdomain) { constructSubarray(array, subdomain); } /* Constructor added by Julian Cummings */ Array(Array& array, const StridedDomain& subdomain) { constructSubarray(array, subdomain); } /* * This constructor is invoked by the operator()'s which take * a combination of integer and Range arguments. It's not intended * for end-user use. */ template Array(Array& array, R0 r0, R1 r1, R2 r2, R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10) { constructSlice(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10); } ////////////////////////////////////////////// // Member functions ////////////////////////////////////////////// const TinyVector& base() const { return storage_.base(); } int base(int rank) const { return storage_.base(rank); } iterator begin() { return iterator(*this); } const_iterator begin() const { return const_iterator(*this); } T_iterator beginFast() const { return T_iterator(*this); } // Deprecated: now extractComponent(...) template Array chopComponent(P_numtype2 a, int compNum, int numComponents) const { return extractComponent(a, compNum, numComponents); } int cols() const { return length_[1]; } int columns() const { return length_[1]; } T_array copy() const; // data_ always refers to the point (0,0,...,0) which may // not be in the array if the base is not zero in each rank. // These data() routines return a pointer to the first // element in the array (but note that it may not be // stored first in memory if some ranks are stored descending). int dataOffset() const { return dot(storage_.base(), stride_); } const T_numtype* restrict data() const { return data_ + dataOffset(); } T_numtype* restrict data() { return data_ + dataOffset(); } // These dataZero() routines refer to the point (0,0,...,0) // which may not be in the array if the bases are nonzero. const T_numtype* restrict dataZero() const { return data_; } T_numtype* restrict dataZero() { return data_; } // These dataFirst() routines refer to the element in the // array which falls first in memory. int dataFirstOffset() const { int pos = 0; // Used to use tinyvector expressions: // return data_ + dot(storage_.base() // + (1 - storage_.ascendingFlag()) * (length_ - 1), stride_); for (int i=0; i < N_rank; ++i) pos += (storage_.base(i) + (1-storage_.isRankStoredAscending(i)) * (length_(i)-1)) * stride_(i); return pos; } const T_numtype* restrict dataFirst() const { return data_ + dataFirstOffset(); } T_numtype* restrict dataFirst() { return data_ + dataFirstOffset(); } int depth() const { return length_[2]; } int dimensions() const { return N_rank; } RectDomain domain() const { return RectDomain(lbound(), ubound()); } void dumpStructureInformation(ostream& os = cout) const; iterator end() { return iterator(); } const_iterator end() const { return const_iterator(); } int extent(int rank) const { return length_[rank]; } const TinyVector& extent() const { return length_; } template Array extractComponent(P_numtype2, int compNum, int numComponents) const; void free() { changeToNullBlock(); length_ = 0; } bool isMajorRank(int rank) const { return storage_.ordering(rank) == 0; } bool isMinorRank(int rank) const { return storage_.ordering(rank) != 0; } bool isRankStoredAscending(int rank) const { return storage_.isRankStoredAscending(rank); } bool isStorageContiguous() const; int lbound(int rank) const { return base(rank); } TinyVector lbound() const { return base(); } int length(int rank) const { return length_[rank]; } const TinyVector& length() const { return length_; } void makeUnique(); int numElements() const { return product(length_); } // NEEDS_WORK -- Expose the numReferences() method // MemoryBlockReference::numReferences; // The storage_.ordering_ array is a list of dimensions from // the most minor (stride 1) to major dimension. Generally, // ordering(0) will return the dimension which has the smallest // stride, and ordering(N_rank-1) will return the dimension with // the largest stride. int ordering(int storageRankIndex) const { return storage_.ordering(storageRankIndex); } const TinyVector& ordering() const { return storage_.ordering(); } void transposeSelf(int r0, int r1, int r2=0, int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int r9=0, int r10=0); T_array transpose(int r0, int r1, int r2=0, int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int r9=0, int r10=0); int rank() const { return N_rank; } void reference(const T_array&); // Added by Derrick Bass T_array reindex(const TinyVector&); void reindexSelf(const TinyVector&); void resize(int extent); void resize(int extent1, int extent2); void resize(int extent1, int extent2, int extent3); void resize(int extent1, int extent2, int extent3, int extent4); void resize(int extent1, int extent2, int extent3, int extent4, int extent5); void resize(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6); void resize(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7); void resize(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8); void resize(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8, int extent9); void resize(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8, int extent9, int extent10); void resize(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8, int extent9, int extent10, int extent11); void resize(Range r1); void resize(Range r1, Range r2); void resize(Range r1, Range r2, Range r3); void resize(Range r1, Range r2, Range r3, Range r4); void resize(Range r1, Range r2, Range r3, Range r4, Range r5); void resize(Range r1, Range r2, Range r3, Range r4, Range r5, Range r6); void resize(Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7); void resize(Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8); void resize(Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9); void resize(Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, Range r10); void resize(Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, Range r10, Range r11); void resize(const TinyVector&); void resizeAndPreserve(const TinyVector&); void resizeAndPreserve(int extent); void resizeAndPreserve(int extent1, int extent2); void resizeAndPreserve(int extent1, int extent2, int extent3); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8, int extent9); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8, int extent9, int extent10); void resizeAndPreserve(int extent1, int extent2, int extent3, int extent4, int extent5, int extent6, int extent7, int extent8, int extent9, int extent10, int extent11); // NEEDS_WORK -- resizeAndPreserve(Range,...) // NEEDS_WORK -- resizeAndPreserve(const Domain&); T_array reverse(int rank); void reverseSelf(int rank); int rows() const { return length_[0]; } void setStorage(GeneralArrayStorage); void slice(int rank, Range r); const TinyVector& shape() const { return length_; } int size() const { return numElements(); } const TinyVector& stride() const { return stride_; } int stride(int rank) const { return stride_[rank]; } int ubound(int rank) const { return base(rank) + length_(rank) - 1; } TinyVector ubound() const { TinyVector ub; for (int i=0; i < N_rank; ++i) ub(i) = base(i) + extent(i) - 1; // WAS: ub = base() + extent() - 1; return ub; } int zeroOffset() const { return zeroOffset_; } ////////////////////////////////////////////// // Debugging routines ////////////////////////////////////////////// bool isInRangeForDim(int i, int d) const { return i >= base(d) && (i - base(d)) < length_[d]; } bool isInRange(int i0) const { return i0 >= base(0) && (i0 - base(0)) < length_[0]; } bool isInRange(int i0, int i1) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1]; } bool isInRange(int i0, int i1, int i2) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2]; } bool isInRange(int i0, int i1, int i2, int i3) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3]; } bool isInRange(int i0, int i1, int i2, int i3, int i4) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4]; } bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4] && i5 >= base(5) && (i5 - base(5)) < length_[5]; } bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4] && i5 >= base(5) && (i5 - base(5)) < length_[5] && i6 >= base(6) && (i6 - base(6)) < length_[6]; } bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4] && i5 >= base(5) && (i5 - base(5)) < length_[5] && i6 >= base(6) && (i6 - base(6)) < length_[6] && i7 >= base(7) && (i7 - base(7)) < length_[7]; } bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4] && i5 >= base(5) && (i5 - base(5)) < length_[5] && i6 >= base(6) && (i6 - base(6)) < length_[6] && i7 >= base(7) && (i7 - base(7)) < length_[7] && i8 >= base(8) && (i8 - base(8)) < length_[8]; } bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4] && i5 >= base(5) && (i5 - base(5)) < length_[5] && i6 >= base(6) && (i6 - base(6)) < length_[6] && i7 >= base(7) && (i7 - base(7)) < length_[7] && i8 >= base(8) && (i8 - base(8)) < length_[8] && i9 >= base(9) && (i9 - base(9)) < length_[9]; } bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) const { return i0 >= base(0) && (i0 - base(0)) < length_[0] && i1 >= base(1) && (i1 - base(1)) < length_[1] && i2 >= base(2) && (i2 - base(2)) < length_[2] && i3 >= base(3) && (i3 - base(3)) < length_[3] && i4 >= base(4) && (i4 - base(4)) < length_[4] && i5 >= base(5) && (i5 - base(5)) < length_[5] && i6 >= base(6) && (i6 - base(6)) < length_[6] && i7 >= base(7) && (i7 - base(7)) < length_[7] && i8 >= base(8) && (i8 - base(8)) < length_[8] && i9 >= base(9) && (i9 - base(9)) < length_[9] && i10 >= base(10) && (i10 - base(10)) < length_[10]; } bool isInRange(const T_index& index) const { for (int i=0; i < N_rank; ++i) if (index[i] < base(i) || (index[i] - base(i)) >= length_[i]) return false; return true; } bool assertInRange(const T_index& BZ_DEBUG_PARAM(index)) const { BZPRECHECK(isInRange(index), "Array index out of range: " << index << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0)) const { BZPRECHECK(isInRange(i0), "Array index out of range: " << i0 << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1)) const { BZPRECHECK(isInRange(i0,i1), "Array index out of range: (" << i0 << ", " << i1 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2)) const { BZPRECHECK(isInRange(i0,i1,i2), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3)) const { BZPRECHECK(isInRange(i0,i1,i2,i3), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4), int BZ_DEBUG_PARAM(i5)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ", " << i5 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4), int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ", " << i5 << ", " << i6 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4), int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4), int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7), int BZ_DEBUG_PARAM(i8)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 << ", " << i8 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4), int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7), int BZ_DEBUG_PARAM(i8), int BZ_DEBUG_PARAM(i9)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8,i9), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 << ", " << i8 << ", " << i9 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1), int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4), int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7), int BZ_DEBUG_PARAM(i8), int BZ_DEBUG_PARAM(i9), int BZ_DEBUG_PARAM(i10)) const { BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10), "Array index out of range: (" << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 << ", " << i8 << ", " << i9 << ", " << i10 << ")" << endl << "Lower bounds: " << storage_.base() << endl << "Length: " << length_ << endl); return true; } ////////////////////////////////////////////// // Subscripting operators ////////////////////////////////////////////// template const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index); return data_[dot(index, stride_)]; } template T_numtype& restrict operator()(const TinyVector& index) { assertInRange(index); return data_[dot(index, stride_)]; } const T_numtype& restrict operator()(TinyVector index) const { assertInRange(index[0]); return data_[index[0] * stride_[0]]; } T_numtype& operator()(TinyVector index) { assertInRange(index[0]); return data_[index[0] * stride_[0]]; } const T_numtype& restrict operator()(TinyVector index) const { assertInRange(index[0], index[1]); return data_[index[0] * stride_[0] + index[1] * stride_[1]]; } T_numtype& operator()(TinyVector index) { assertInRange(index[0], index[1]); return data_[index[0] * stride_[0] + index[1] * stride_[1]]; } const T_numtype& restrict operator()(TinyVector index) const { assertInRange(index[0], index[1], index[2]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2]]; } T_numtype& operator()(TinyVector index) { assertInRange(index[0], index[1], index[2]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7], index[8]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7] + index[8] * stride_[8]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7], index[8]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7] + index[8] * stride_[8]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7], index[8], index[9]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7] + index[8] * stride_[8] + index[9] * stride_[9]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7], index[8], index[9]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7] + index[8] * stride_[8] + index[9] * stride_[9]]; } const T_numtype& restrict operator()(const TinyVector& index) const { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7], index[8], index[9], index[10]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7] + index[8] * stride_[8] + index[9] * stride_[9] + index[10] * stride_[10]]; } T_numtype& operator()(const TinyVector& index) { assertInRange(index[0], index[1], index[2], index[3], index[4], index[5], index[6], index[7], index[8], index[9], index[10]); return data_[index[0] * stride_[0] + index[1] * stride_[1] + index[2] * stride_[2] + index[3] * stride_[3] + index[4] * stride_[4] + index[5] * stride_[5] + index[6] * stride_[6] + index[7] * stride_[7] + index[8] * stride_[8] + index[9] * stride_[9] + index[10] * stride_[10]]; } const T_numtype& restrict operator()(int i0) const { assertInRange(i0); return data_[i0 * stride_[0]]; } T_numtype& restrict operator()(int i0) { assertInRange(i0); return data_[i0 * stride_[0]]; } const T_numtype& restrict operator()(int i0, int i1) const { assertInRange(i0, i1); return data_[i0 * stride_[0] + i1 * stride_[1]]; } T_numtype& restrict operator()(int i0, int i1) { assertInRange(i0, i1); return data_[i0 * stride_[0] + i1 * stride_[1]]; } const T_numtype& restrict operator()(int i0, int i1, int i2) const { assertInRange(i0, i1, i2); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2]]; } T_numtype& restrict operator()(int i0, int i1, int i2) { assertInRange(i0, i1, i2); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3) const { assertInRange(i0, i1, i2, i3); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3) { assertInRange(i0, i1, i2, i3); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4) const { assertInRange(i0, i1, i2, i3, i4); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4) { assertInRange(i0, i1, i2, i3, i4); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5) const { assertInRange(i0, i1, i2, i3, i4, i5); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5) { assertInRange(i0, i1, i2, i3, i4, i5); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const { assertInRange(i0, i1, i2, i3, i4, i5, i6); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6) { assertInRange(i0, i1, i2, i3, i4, i5, i6); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7) const { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7) { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8) const { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] + i8 * stride_[8]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8) { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] + i8 * stride_[8]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9) const { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] + i8 * stride_[8] + i9 * stride_[9]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9) { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] + i8 * stride_[8] + i9 * stride_[9]]; } const T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) const { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]]; } T_numtype& restrict operator()(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10) { assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10); return data_[i0 * stride_[0] + i1 * stride_[1] + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4] + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7] + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]]; } /* * Slicing to produce subarrays. If the number of Range arguments is * fewer than N_rank, then missing arguments are treated like Range::all(). */ T_array& noConst() const { return const_cast(*this); } T_array operator()(const RectDomain& subdomain) const { return T_array(noConst(), subdomain); } /* Operator added by Julian Cummings */ T_array operator()(const StridedDomain& subdomain) const { return T_array(noConst(), subdomain); } T_array operator()(Range r0) const { return T_array(noConst(), r0); } T_array operator()(Range r0, Range r1) const { return T_array(noConst(), r0, r1); } T_array operator()(Range r0, Range r1, Range r2) const { return T_array(noConst(), r0, r1, r2); } T_array operator()(Range r0, Range r1, Range r2, Range r3) const { return T_array(noConst(), r0, r1, r2, r3); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4) const { return T_array(noConst(), r0, r1, r2, r3, r4); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5) const { return T_array(noConst(), r0, r1, r2, r3, r4, r5); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6) const { return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7) const { return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8) const { return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7, r8); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9) const { return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7, r8, r9); } T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, Range r10) const { return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10); } // Allow any mixture of Range, int and Vector objects as // operands for operator(): A(Range(3,7), 5, Range(2,4)) /* * These versions of operator() allow any combination of int * and Range operands to be used. Each int operand reduces * the rank of the resulting array by one. * * e.g. Array A(20,20,20,20); * Array B = A(Range(5,15), 3, 5, Range(8,9)); * * SliceInfo is a helper class defined in . * It counts the number of Range vs. int arguments and does some * other helpful things. * * Once partial specialization becomes widely implemented, these * operators may be expanded to accept Vector arguments * and produce ArrayPick objects. * * This operator() is not provided with a single argument because * the appropriate cases exist above. */ #ifdef BZ_HAVE_PARTIAL_ORDERING template typename SliceInfo::T_slice operator()(T1 r1, T2 r2) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, r6, nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, nilArraySection(), nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, nilArraySection(), nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, r9, nilArraySection(), nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, nilArraySection()); } template typename SliceInfo::T_slice operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const { typedef typename SliceInfo::T_slice slice; return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11); } #endif // BZ_HAVE_PARTIAL_ORDERING /* * These versions of operator() are provided to support tensor-style * array notation, e.g. * * Array A, B; * firstIndex i; * secondIndex j; * thirdIndex k; * Array C = A(i,j) * B(j,k); */ template _bz_ArrayExpr > operator()(IndexPlaceholder) const { return _bz_ArrayExpr > (noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } template _bz_ArrayExpr > operator()(IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder, IndexPlaceholder) const { return _bz_ArrayExpr >(noConst()); } ////////////////////////////////////////////// // Support for multicomponent arrays ////////////////////////////////////////////// /* * See for an explanation of the traits class * multicomponent_traits. */ Array::T_element,N_rank> operator[](const unsigned component) { typedef typename multicomponent_traits::T_element T_compType; return extractComponent(T_compType(),component, multicomponent_traits::numComponents); } const Array::T_element,N_rank> operator[](const unsigned component) const { typedef typename multicomponent_traits::T_element T_compType; return extractComponent(T_compType(),component, multicomponent_traits::numComponents); } Array::T_element,N_rank> operator[](const int component) { return operator[](static_cast(component)); } const Array::T_element,N_rank> operator[](const int component) const { return operator[](static_cast(component)); } ////////////////////////////////////////////// // Indirection ////////////////////////////////////////////// template IndirectArray operator[](const T_indexContainer& index) { return IndirectArray(*this, const_cast(index)); } ////////////////////////////////////////////// // Assignment Operators ////////////////////////////////////////////// // Scalar operand // NEEDS_WORK : need a precondition check on // isStorageContiguous when operator, is used. ListInitializationSwitch operator=(T_numtype x) { return ListInitializationSwitch(*this, x); } T_array& initialize(T_numtype); // Was: // T_array& operator=(T_numtype); #ifdef BZ_NEW_EXPRESSION_TEMPLATES template T_array& operator=(const ETBase&); T_array& operator=(const Array&); template T_array& operator+=(const T&); template T_array& operator-=(const T&); template T_array& operator*=(const T&); template T_array& operator/=(const T&); template T_array& operator%=(const T&); template T_array& operator^=(const T&); template T_array& operator&=(const T&); template T_array& operator|=(const T&); template T_array& operator>>=(const T&); template T_array& operator<<=(const T&); #else T_array& operator+=(T_numtype); T_array& operator-=(T_numtype); T_array& operator*=(T_numtype); T_array& operator/=(T_numtype); T_array& operator%=(T_numtype); T_array& operator^=(T_numtype); T_array& operator&=(T_numtype); T_array& operator|=(T_numtype); T_array& operator>>=(T_numtype); T_array& operator<<=(T_numtype); // Array operands T_array& operator=(const Array&); template T_array& operator=(const Array&); template T_array& operator+=(const Array&); template T_array& operator-=(const Array&); template T_array& operator*=(const Array&); template T_array& operator/=(const Array&); template T_array& operator%=(const Array&); template T_array& operator^=(const Array&); template T_array& operator&=(const Array&); template T_array& operator|=(const Array&); template T_array& operator>>=(const Array&); template T_array& operator<<=(const Array&); // Array expression operands template inline T_array& operator=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator+=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator-=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator*=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator/=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator%=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator^=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator&=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator|=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator>>=(BZ_ETPARM(_bz_ArrayExpr) expr); template inline T_array& operator<<=(BZ_ETPARM(_bz_ArrayExpr) expr); // NEEDS_WORK -- Index placeholder operand // NEEDS_WORK -- Random operand #endif public: // Undocumented implementation routines template inline T_array& evaluate(T_expr expr, T_update); #ifdef BZ_HAVE_STD #ifdef BZ_ARRAY_SPACE_FILLING_TRAVERSAL template inline T_array& evaluateWithFastTraversal( const TraversalOrder& order, T_expr expr, T_update); #endif // BZ_ARRAY_SPACE_FILLING_TRAVERSAL #endif #ifdef BZ_ARRAY_2D_STENCIL_TILING template inline T_array& evaluateWithTiled2DTraversal( T_expr expr, T_update); #endif template inline T_array& evaluateWithIndexTraversal1( T_expr expr, T_update); template inline T_array& evaluateWithIndexTraversalN( T_expr expr, T_update); template inline T_array& evaluateWithStackTraversal1( T_expr expr, T_update); template inline T_array& evaluateWithStackTraversalN( T_expr expr, T_update); T_numtype* restrict getInitializationIterator() { return dataFirst(); } bool canCollapse(int outerRank, int innerRank) const { #ifdef BZ_DEBUG_TRAVERSE BZ_DEBUG_MESSAGE("stride(" << innerRank << ")=" << stride(innerRank) << ", extent()=" << extent(innerRank) << ", stride(outerRank)=" << stride(outerRank)); #endif return (stride(innerRank) * extent(innerRank) == stride(outerRank)); } protected: ////////////////////////////////////////////// // Implementation routines ////////////////////////////////////////////// _bz_inline2 void computeStrides(); _bz_inline2 void setupStorage(int rank); void constructSubarray(Array& array, const RectDomain&); void constructSubarray(Array& array, const StridedDomain&); void constructSubarray(Array& array, Range r0); void constructSubarray(Array& array, Range r0, Range r1); void constructSubarray(Array& array, Range r0, Range r1, Range r2); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9); void constructSubarray(Array& array, Range r0, Range r1, Range r2, Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9, Range r10); void calculateZeroOffset(); template void constructSlice(Array& array, R0 r0, R1 r1, R2 r2, R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10); template void slice(int& setRank, Range r, Array& array, TinyVector& rankMap, int sourceRank); template void slice(int& setRank, int i, Array& array, TinyVector& rankMap, int sourceRank); template void slice(int&, nilArraySection, Array&, TinyVector&, int) { } void doTranspose(int destRank, int sourceRank, T_array& array); protected: ////////////////////////////////////////////// // Data members ////////////////////////////////////////////// // NB: adding new data members may require changes to ctors, reference() /* * For a description of the storage_ members, see the comments for class * GeneralArrayStorage above. * * length_[] contains the extent of each rank. E.g. a 10x20x30 array * would have length_ = { 10, 20, 30}. * stride_[] contains the stride to move to the next element along each * rank. * zeroOffset_ is the distance from the first element in the array * to the point (0,0,...,0). If base_ is zero and all ranks are * stored ascending, then zeroOffset_ is zero. This value * is needed because to speed up indexing, the data_ member * (inherited from MemoryBlockReference) always refers to * (0,0,...,0). */ GeneralArrayStorage storage_; TinyVector length_; TinyVector stride_; int zeroOffset_; }; /* * Rank numbers start with zero, which may be confusing to users coming * from Fortran. To make code more readable, the following constants * may help. Example: instead of * * int firstRankExtent = A.extent(0); * * One can write: * * int firstRankExtent = A.extent(firstRank); */ const int firstRank = 0; const int secondRank = 1; const int thirdRank = 2; const int fourthRank = 3; const int fifthRank = 4; const int sixthRank = 5; const int seventhRank = 6; const int eighthRank = 7; const int ninthRank = 8; const int tenthRank = 9; const int eleventhRank = 10; const int firstDim = 0; const int secondDim = 1; const int thirdDim = 2; const int fourthDim = 3; const int fifthDim = 4; const int sixthDim = 5; const int seventhDim = 6; const int eighthDim = 7; const int ninthDim = 8; const int tenthDim = 9; const int eleventhDim = 10; /* * Global Functions */ template ostream& operator<<(ostream&, const Array&); template ostream& operator<<(ostream&, const Array&); template ostream& operator<<(ostream&, const Array&); template istream& operator>>(istream& is, Array& x); template void swap(Array& a,Array& b) { Array c(a); a.reference(b); b.reference(c); } template void find(Array,1>& indices, const _bz_ArrayExpr& expr) { find(indices, static_cast< Array >(expr)); } template void find(Array,1>& indices, const Array& exprVals) { indices.resize(exprVals.size()); typename Array::const_iterator it, end = exprVals.end(); int j=0; for (it = exprVals.begin(); it != end; ++it) if (*it) indices(j++) = it.position(); if (j) indices.resizeAndPreserve(j); else indices.free(); return; } BZ_NAMESPACE_END /* * Include implementations of the member functions and some additional * global functions. */ #include // Array iterators #include // Fast Array iterators (for et) #include // Array expression objects #include // Member functions #include // Array expression evaluation #include // Assignment operators #include // Output formatting #include // Expression templates #include // Array reduction expression templates #include // Allocation of interlaced arrays #include // Array resize, resizeAndPreserve #include // Slicing and subarrays #include // Cycling arrays #include // Special support for complex arrays #include // Zipping multicomponent types #include // where(X,Y,Z) #include // Indirection #include // Stencil objects #endif // BZ_ARRAY_H