blitz/array-impl.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  * blitz/array-impl.h    Definition of the Array<P_numtype, N_rank> class
00004  *
00005  * $Id: array-impl.h,v 1.25 2005/10/13 23:46:43 julianc Exp $
00006  *
00007  * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU General Public License
00011  * as published by the Free Software Foundation; either version 2
00012  * of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * Suggestions:          blitz-dev@oonumerics.org
00020  * Bugs:                 blitz-bugs@oonumerics.org
00021  *
00022  * For more information, please see the Blitz++ Home Page:
00023  *    http://oonumerics.org/blitz/
00024  *
00025  ***************************************************************************/
00026 
00027 /*
00028  * Wish list for array classes.
00029  *  - Arrays whose dimensions are unknown at compile time.
00030  *  - where()/elsewhere()/elsewhere() as in Dan Quinlan's implementation
00031  *  - block reduction operations
00032  *  - conversion to/from matrix & vector
00033  *  - apply(T func(T))
00034  *  - apply(T func(const T&))
00035  *  - apply<T func(T)>
00036  */
00037 
00038 #ifndef BZ_ARRAY_H
00039 #define BZ_ARRAY_H
00040 
00041 #include <blitz/blitz.h>
00042 #include <blitz/memblock.h>
00043 #include <blitz/range.h>
00044 #include <blitz/tinyvec.h>
00045 
00046 #ifdef BZ_ARRAY_SPACE_FILLING_TRAVERSAL
00047 #include <blitz/traversal.h>
00048 #endif
00049 
00050 #include <blitz/indexexpr.h>
00051 #include <blitz/prettyprint.h>
00052 
00053 #include <blitz/array/slice.h>     // Subarrays and slicing
00054 #include <blitz/array/map.h>       // Tensor index notation
00055 #include <blitz/array/multi.h>     // Multicomponent arrays
00056 #include <blitz/array/domain.h>    // RectDomain class
00057 #include <blitz/array/storage.h>   // GeneralArrayStorage
00058 
00059 
00060 BZ_NAMESPACE(blitz)
00061 
00062 /*
00063  * Forward declarations
00064  */
00065 
00066 template<typename T_numtype, int N_rank>
00067 class ArrayIterator;
00068 
00069 template<typename T_numtype, int N_rank>
00070 class ConstArrayIterator;
00071 
00072 template<typename T_numtype, int N_rank>
00073 class FastArrayIterator;
00074 
00075 template<typename P_expr>
00076 class _bz_ArrayExpr;
00077 
00078 template<typename T_array, typename T_index>
00079 class IndirectArray;
00080 
00081 template <typename P_numtype,int N_rank>
00082 void swap(Array<P_numtype,N_rank>&,Array<P_numtype,N_rank>&);
00083 
00084 template <typename P_numtype, int N_rank>
00085 void find(Array<TinyVector<int,N_rank>,1>&,const Array<P_numtype,N_rank>&);
00086 
00087 /*
00088  * Declaration of class Array
00089  */
00090 
00091 // NEEDS_WORK: Array should inherit protected from MemoryBlockReference.
00092 // To make this work, need to expose MemoryBlockReference::numReferences()
00093 // and make Array<P,N2> a friend of Array<P,N> for slicing.
00094 
00095 template<typename P_numtype, int N_rank>
00096 class Array : public MemoryBlockReference<P_numtype> 
00097 #ifdef BZ_NEW_EXPRESSION_TEMPLATES
00098     , public ETBase<Array<P_numtype,N_rank> >
00099 #endif
00100 {
00101 
00102 private:
00103     typedef MemoryBlockReference<P_numtype> T_base;
00104     using T_base::data_;
00105     using T_base::changeToNullBlock;
00106     using T_base::numReferences;
00107 
00108 public:
00110     // Public Types
00112 
00113     /*
00114      * T_numtype  is the numeric type stored in the array.
00115      * T_index    is a vector type which can be used to access elements
00116      *            of many-dimensional arrays.
00117      * T_array    is the array type itself -- Array<T_numtype, N_rank>
00118      * T_iterator is a a fast iterator for the array, used for expression
00119      *            templates
00120      * iterator   is a STL-style iterator
00121      * const_iterator is an STL-style const iterator
00122      */
00123 
00124     typedef P_numtype                T_numtype;
00125     typedef TinyVector<int, N_rank>  T_index;
00126     typedef Array<T_numtype, N_rank> T_array;
00127     typedef FastArrayIterator<T_numtype, N_rank> T_iterator;
00128 
00129     typedef ArrayIterator<T_numtype,N_rank> iterator;
00130     typedef ConstArrayIterator<T_numtype,N_rank> const_iterator;
00131 
00132     static const int _bz_rank = N_rank;
00133 
00135     // Constructors                             //
00137 
00138     
00139     /*
00140      * Construct an array from an array expression.
00141      */
00142 
00143     template<typename T_expr>
00144     explicit Array(_bz_ArrayExpr<T_expr> expr);
00145 
00146     /*
00147      * Any missing length arguments will have their value taken from the
00148      * last argument.  For example,
00149      *   Array<int,3> A(32,64);
00150      * will create a 32x64x64 array.  This is handled by setupStorage().
00151      */
00152 
00153     Array(GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00154         : storage_(storage)
00155     {
00156         length_ = 0;
00157         stride_ = 0;
00158         zeroOffset_ = 0;
00159     }
00160 
00161     explicit Array(int length0, 
00162         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00163         : storage_(storage)
00164     {
00165         length_[0] = length0;
00166         setupStorage(0);
00167     }
00168 
00169     Array(int length0, int length1,
00170         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00171         : storage_(storage)
00172     {
00173         BZPRECONDITION(N_rank >= 2);
00174         TAU_TYPE_STRING(p1, "Array<T,N>::Array() [T="
00175             + CT(T_numtype) + ",N=" + CT(N_rank) + "]");
00176         TAU_PROFILE(p1, "void (int,int)", TAU_BLITZ);
00177 
00178         length_[0] = length0;
00179         length_[1] = length1;
00180         setupStorage(1);
00181     }
00182 
00183     Array(int length0, int length1, int length2,
00184         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00185         : storage_(storage)
00186     {
00187         BZPRECONDITION(N_rank >= 3);
00188         length_[0] = length0;
00189         length_[1] = length1;
00190         length_[2] = length2;
00191         setupStorage(2);
00192     }
00193 
00194     Array(int length0, int length1, int length2, int length3,
00195         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00196         : storage_(storage)
00197     {
00198         BZPRECONDITION(N_rank >= 4);
00199         length_[0] = length0;
00200         length_[1] = length1;
00201         length_[2] = length2;
00202         length_[3] = length3;
00203         setupStorage(3);
00204     }
00205 
00206     Array(int length0, int length1, int length2, int length3, int length4,
00207         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00208         : storage_(storage)
00209     {
00210         BZPRECONDITION(N_rank >= 5);
00211         length_[0] = length0;
00212         length_[1] = length1;
00213         length_[2] = length2;
00214         length_[3] = length3;
00215         length_[4] = length4;
00216         setupStorage(4);
00217     }
00218 
00219     Array(int length0, int length1, int length2, int length3, int length4,
00220         int length5,
00221         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00222         : storage_(storage)
00223     {
00224         BZPRECONDITION(N_rank >= 6);
00225         length_[0] = length0;
00226         length_[1] = length1;
00227         length_[2] = length2;
00228         length_[3] = length3;
00229         length_[4] = length4;
00230         length_[5] = length5;
00231         setupStorage(5);
00232     }
00233 
00234     Array(int length0, int length1, int length2, int length3, int length4,
00235         int length5, int length6,
00236         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00237         : storage_(storage)
00238     {
00239         BZPRECONDITION(N_rank >= 7);
00240         length_[0] = length0;
00241         length_[1] = length1;
00242         length_[2] = length2;
00243         length_[3] = length3;
00244         length_[4] = length4;
00245         length_[5] = length5;
00246         length_[6] = length6;
00247         setupStorage(6);
00248     }
00249 
00250     Array(int length0, int length1, int length2, int length3, int length4,
00251         int length5, int length6, int length7,
00252         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00253         : storage_(storage)
00254     {
00255         BZPRECONDITION(N_rank >= 8);
00256         length_[0] = length0;
00257         length_[1] = length1;
00258         length_[2] = length2;
00259         length_[3] = length3;
00260         length_[4] = length4;
00261         length_[5] = length5;
00262         length_[6] = length6;
00263         length_[7] = length7;
00264         setupStorage(7);
00265     }
00266 
00267     Array(int length0, int length1, int length2, int length3, int length4,
00268         int length5, int length6, int length7, int length8,
00269         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00270         : storage_(storage)
00271     {
00272         BZPRECONDITION(N_rank >= 9);
00273         length_[0] = length0;
00274         length_[1] = length1;
00275         length_[2] = length2;
00276         length_[3] = length3;
00277         length_[4] = length4;
00278         length_[5] = length5;
00279         length_[6] = length6;
00280         length_[7] = length7;
00281         length_[8] = length8;
00282         setupStorage(8);
00283     }
00284 
00285     Array(int length0, int length1, int length2, int length3, int length4,
00286         int length5, int length6, int length7, int length8, int length9,
00287         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00288         : storage_(storage)
00289     {
00290         BZPRECONDITION(N_rank >= 10);
00291         length_[0] = length0;
00292         length_[1] = length1;
00293         length_[2] = length2;
00294         length_[3] = length3;
00295         length_[4] = length4;
00296         length_[5] = length5;
00297         length_[6] = length6;
00298         length_[7] = length7;
00299         length_[8] = length8;
00300         length_[9] = length9;
00301         setupStorage(9);
00302     }
00303 
00304     Array(int length0, int length1, int length2, int length3, int length4,
00305         int length5, int length6, int length7, int length8, int length9,
00306         int length10,
00307         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00308         : storage_(storage)
00309     {
00310         BZPRECONDITION(N_rank >= 11);
00311         length_[0] = length0;
00312         length_[1] = length1;
00313         length_[2] = length2;
00314         length_[3] = length3;
00315         length_[4] = length4;
00316         length_[5] = length5;
00317         length_[6] = length6;
00318         length_[7] = length7;
00319         length_[8] = length8;
00320         length_[9] = length9;
00321         length_[10] = length10;
00322         setupStorage(10);
00323     }
00324 
00325     /*
00326      * Construct an array from an existing block of memory.  Ownership
00327      * is not acquired (this is provided for backwards compatibility).
00328      */
00329     Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape,
00330         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00331       : MemoryBlockReference<T_numtype>(product(shape), dataFirst, 
00332           neverDeleteData),
00333         storage_(storage)
00334     {
00335         BZPRECONDITION(dataFirst != 0);
00336 
00337         length_ = shape;
00338         computeStrides();
00339         data_ += zeroOffset_;
00340     }
00341 
00342     /*
00343      * Construct an array from an existing block of memory, with a
00344      * given set of strides.  Ownership is not acquired (i.e. the memory
00345      * block will not be freed by Blitz++).
00346      */
00347     Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape,
00348         TinyVector<int, N_rank> stride, 
00349         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00350       : MemoryBlockReference<T_numtype>(product(shape), dataFirst, 
00351           neverDeleteData),
00352         storage_(storage)
00353     {
00354         BZPRECONDITION(dataFirst != 0);
00355 
00356         length_ = shape;
00357         stride_ = stride;
00358         calculateZeroOffset();
00359         data_ += zeroOffset_;
00360     }
00361 
00362     /*
00363      * Construct an array from an existing block of memory.
00364      */
00365     Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape,
00366         preexistingMemoryPolicy deletionPolicy,
00367         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00368       : MemoryBlockReference<T_numtype>(product(shape), dataFirst, 
00369             deletionPolicy),
00370         storage_(storage)
00371     {
00372         BZPRECONDITION(dataFirst != 0);
00373 
00374         length_ = shape;
00375         computeStrides();
00376         data_ += zeroOffset_;
00377 
00378         if (deletionPolicy == duplicateData)
00379             reference(copy());
00380     }
00381 
00382     /*
00383      * Construct an array from an existing block of memory, with a
00384      * given set of strides.  
00385      */
00386     Array(T_numtype* restrict dataFirst, TinyVector<int, N_rank> shape,
00387         TinyVector<int, N_rank> stride,
00388         preexistingMemoryPolicy deletionPolicy,
00389         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00390       : MemoryBlockReference<T_numtype>(product(shape), dataFirst, 
00391           deletionPolicy),
00392         storage_(storage)
00393     {
00394         BZPRECONDITION(dataFirst != 0);
00395 
00396         length_ = shape;
00397         stride_ = stride;
00398         calculateZeroOffset();
00399         data_ += zeroOffset_;
00400 
00401         if (deletionPolicy == duplicateData)
00402             reference(copy());
00403     }
00404 
00405     /*
00406      * This constructor takes an extent (length) vector and storage format.
00407      */
00408 
00409     Array(const TinyVector<int, N_rank>& extent, 
00410         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00411         : storage_(storage)
00412     {
00413         length_ = extent;
00414         setupStorage(N_rank - 1);
00415     }
00416 
00417     /*
00418      * This construct takes a vector of bases (lbounds) and a vector of
00419      * extents.
00420      */
00421 
00422     Array(const TinyVector<int, N_rank>& lbounds,
00423         const TinyVector<int, N_rank>& extent,
00424         const GeneralArrayStorage<N_rank>& storage 
00425            = GeneralArrayStorage<N_rank>());
00426 
00427     /*
00428      * These constructors allow arbitrary bases (starting indices) to be set.
00429      * e.g. Array<int,2> A(Range(10,20), Range(20,30))
00430      * will create an 11x11 array whose indices are 10..20 and 20..30
00431      */
00432     Array(Range r0, 
00433         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00434         : storage_(storage)
00435     {
00436         BZPRECONDITION(r0.isAscendingContiguous());
00437 
00438         length_[0] = r0.length();
00439         storage_.setBase(0, r0.first());
00440         setupStorage(0);
00441     }
00442 
00443     Array(Range r0, Range r1,
00444         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00445         : storage_(storage)
00446     {
00447         BZPRECONDITION(r0.isAscendingContiguous() && 
00448             r1.isAscendingContiguous());
00449 
00450         length_[0] = r0.length();
00451         storage_.setBase(0, r0.first());
00452         length_[1] = r1.length();
00453         storage_.setBase(1, r1.first());
00454 
00455         setupStorage(1);
00456     }
00457 
00458     Array(Range r0, Range r1, Range r2,
00459         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00460         : storage_(storage)
00461     {
00462         BZPRECONDITION(r0.isAscendingContiguous() &&
00463             r1.isAscendingContiguous() && r2.isAscendingContiguous());
00464 
00465         length_[0] = r0.length();
00466         storage_.setBase(0, r0.first());
00467         length_[1] = r1.length();
00468         storage_.setBase(1, r1.first());
00469         length_[2] = r2.length();
00470         storage_.setBase(2, r2.first());
00471 
00472         setupStorage(2);
00473     }
00474 
00475     Array(Range r0, Range r1, Range r2, Range r3,
00476         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00477         : storage_(storage)
00478     {
00479         BZPRECONDITION(r0.isAscendingContiguous() &&
00480             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00481             && r3.isAscendingContiguous());
00482 
00483         length_[0] = r0.length();
00484         storage_.setBase(0, r0.first());
00485         length_[1] = r1.length();
00486         storage_.setBase(1, r1.first());
00487         length_[2] = r2.length();
00488         storage_.setBase(2, r2.first());
00489         length_[3] = r3.length();
00490         storage_.setBase(3, r3.first());
00491 
00492         setupStorage(3);
00493     }
00494 
00495     Array(Range r0, Range r1, Range r2, Range r3, Range r4,
00496         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00497         : storage_(storage)
00498     {
00499         BZPRECONDITION(r0.isAscendingContiguous() &&
00500             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00501             && r3.isAscendingContiguous() && r4.isAscendingContiguous());
00502 
00503         length_[0] = r0.length();
00504         storage_.setBase(0, r0.first());
00505         length_[1] = r1.length();
00506         storage_.setBase(1, r1.first());
00507         length_[2] = r2.length();
00508         storage_.setBase(2, r2.first());
00509         length_[3] = r3.length();
00510         storage_.setBase(3, r3.first());
00511         length_[4] = r4.length();
00512         storage_.setBase(4, r4.first());
00513 
00514         setupStorage(4);
00515     }
00516 
00517     Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
00518         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00519         : storage_(storage)
00520     {
00521         BZPRECONDITION(r0.isAscendingContiguous() &&
00522             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00523             && r3.isAscendingContiguous() && r4.isAscendingContiguous()
00524             && r5.isAscendingContiguous());
00525 
00526         length_[0] = r0.length();
00527         storage_.setBase(0, r0.first());
00528         length_[1] = r1.length();
00529         storage_.setBase(1, r1.first());
00530         length_[2] = r2.length();
00531         storage_.setBase(2, r2.first());
00532         length_[3] = r3.length();
00533         storage_.setBase(3, r3.first());
00534         length_[4] = r4.length();
00535         storage_.setBase(4, r4.first());
00536         length_[5] = r5.length();
00537         storage_.setBase(5, r5.first());
00538 
00539         setupStorage(5);
00540     }
00541 
00542     Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
00543         Range r6,
00544         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00545         : storage_(storage)
00546     {
00547         BZPRECONDITION(r0.isAscendingContiguous() &&
00548             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00549             && r3.isAscendingContiguous() && r4.isAscendingContiguous()
00550             && r5.isAscendingContiguous() && r6.isAscendingContiguous());
00551 
00552         length_[0] = r0.length();
00553         storage_.setBase(0, r0.first());
00554         length_[1] = r1.length();
00555         storage_.setBase(1, r1.first());
00556         length_[2] = r2.length();
00557         storage_.setBase(2, r2.first());
00558         length_[3] = r3.length();
00559         storage_.setBase(3, r3.first());
00560         length_[4] = r4.length();
00561         storage_.setBase(4, r4.first());
00562         length_[5] = r5.length();
00563         storage_.setBase(5, r5.first());
00564         length_[6] = r6.length();
00565         storage_.setBase(6, r6.first());
00566 
00567         setupStorage(6);
00568     }
00569 
00570     Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
00571         Range r6, Range r7,
00572         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00573         : storage_(storage)
00574     {
00575         BZPRECONDITION(r0.isAscendingContiguous() &&
00576             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00577             && r3.isAscendingContiguous() && r4.isAscendingContiguous()
00578             && r5.isAscendingContiguous() && r6.isAscendingContiguous()
00579             && r7.isAscendingContiguous());
00580 
00581         length_[0] = r0.length();
00582         storage_.setBase(0, r0.first());
00583         length_[1] = r1.length();
00584         storage_.setBase(1, r1.first());
00585         length_[2] = r2.length();
00586         storage_.setBase(2, r2.first());
00587         length_[3] = r3.length();
00588         storage_.setBase(3, r3.first());
00589         length_[4] = r4.length();
00590         storage_.setBase(4, r4.first());
00591         length_[5] = r5.length();
00592         storage_.setBase(5, r5.first());
00593         length_[6] = r6.length();
00594         storage_.setBase(6, r6.first());
00595         length_[7] = r7.length();
00596         storage_.setBase(7, r7.first());
00597 
00598         setupStorage(7);
00599     }
00600 
00601     Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
00602         Range r6, Range r7, Range r8,
00603         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00604         : storage_(storage)
00605     {
00606         BZPRECONDITION(r0.isAscendingContiguous() &&
00607             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00608             && r3.isAscendingContiguous() && r4.isAscendingContiguous()
00609             && r5.isAscendingContiguous() && r6.isAscendingContiguous()
00610             && r7.isAscendingContiguous() && r8.isAscendingContiguous());
00611 
00612         length_[0] = r0.length();
00613         storage_.setBase(0, r0.first());
00614         length_[1] = r1.length();
00615         storage_.setBase(1, r1.first());
00616         length_[2] = r2.length();
00617         storage_.setBase(2, r2.first());
00618         length_[3] = r3.length();
00619         storage_.setBase(3, r3.first());
00620         length_[4] = r4.length();
00621         storage_.setBase(4, r4.first());
00622         length_[5] = r5.length();
00623         storage_.setBase(5, r5.first());
00624         length_[6] = r6.length();
00625         storage_.setBase(6, r6.first());
00626         length_[7] = r7.length();
00627         storage_.setBase(7, r7.first());
00628         length_[8] = r8.length();
00629         storage_.setBase(8, r8.first());
00630 
00631         setupStorage(8);
00632     }
00633 
00634     Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
00635         Range r6, Range r7, Range r8, Range r9,
00636         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00637         : storage_(storage)
00638     {
00639         BZPRECONDITION(r0.isAscendingContiguous() &&
00640             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00641             && r3.isAscendingContiguous() && r4.isAscendingContiguous()
00642             && r5.isAscendingContiguous() && r6.isAscendingContiguous()
00643             && r7.isAscendingContiguous() && r8.isAscendingContiguous()
00644             && r9.isAscendingContiguous());
00645 
00646         length_[0] = r0.length();
00647         storage_.setBase(0, r0.first());
00648         length_[1] = r1.length();
00649         storage_.setBase(1, r1.first());
00650         length_[2] = r2.length();
00651         storage_.setBase(2, r2.first());
00652         length_[3] = r3.length();
00653         storage_.setBase(3, r3.first());
00654         length_[4] = r4.length();
00655         storage_.setBase(4, r4.first());
00656         length_[5] = r5.length();
00657         storage_.setBase(5, r5.first());
00658         length_[6] = r6.length();
00659         storage_.setBase(6, r6.first());
00660         length_[7] = r7.length();
00661         storage_.setBase(7, r7.first());
00662         length_[8] = r8.length();
00663         storage_.setBase(8, r8.first());
00664         length_[9] = r9.length();
00665         storage_.setBase(9, r9.first());
00666 
00667         setupStorage(9);
00668     }
00669 
00670     Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
00671         Range r6, Range r7, Range r8, Range r9, Range r10,
00672         GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
00673         : storage_(storage)
00674     {
00675         BZPRECONDITION(r0.isAscendingContiguous() &&
00676             r1.isAscendingContiguous() && r2.isAscendingContiguous()
00677             && r3.isAscendingContiguous() && r4.isAscendingContiguous()
00678             && r5.isAscendingContiguous() && r6.isAscendingContiguous()
00679             && r7.isAscendingContiguous() && r8.isAscendingContiguous()
00680             && r9.isAscendingContiguous() && r10.isAscendingContiguous());
00681 
00682         length_[0] = r0.length();
00683         storage_.setBase(0, r0.first());
00684         length_[1] = r1.length();
00685         storage_.setBase(1, r1.first());
00686         length_[2] = r2.length();
00687         storage_.setBase(2, r2.first());
00688         length_[3] = r3.length();
00689         storage_.setBase(3, r3.first());
00690         length_[4] = r4.length();
00691         storage_.setBase(4, r4.first());
00692         length_[5] = r5.length();
00693         storage_.setBase(5, r5.first());
00694         length_[6] = r6.length();
00695         storage_.setBase(6, r6.first());
00696         length_[7] = r7.length();
00697         storage_.setBase(7, r7.first());
00698         length_[8] = r8.length();
00699         storage_.setBase(8, r8.first());
00700         length_[9] = r9.length();
00701         storage_.setBase(9, r9.first());
00702         length_[10] = r10.length();
00703         storage_.setBase(10, r10.first());
00704 
00705         setupStorage(10);
00706     }
00707 
00708     /*
00709      * Create a reference of another array
00710      */
00711     Array(const Array<T_numtype, N_rank>& array)
00712 #ifdef BZ_NEW_EXPRESSION_TEMPLATES
00713         : MemoryBlockReference<T_numtype>(),
00714           ETBase< Array<T_numtype, N_rank> >(array)
00715 #else
00716         : MemoryBlockReference<T_numtype>()
00717 #endif
00718     {
00719         // NEEDS_WORK: this const_cast is a tad ugly.
00720         reference(const_cast<T_array&>(array));
00721     }
00722 
00723     /*
00724      * These constructors are used for creating interlaced arrays (see
00725      * <blitz/arrayshape.h>
00726      */
00727     Array(const TinyVector<int,N_rank-1>& shape,
00728         int lastExtent, const GeneralArrayStorage<N_rank>& storage);
00729     //Array(const TinyVector<Range,N_rank-1>& shape,
00730     //    int lastExtent, const GeneralArrayStorage<N_rank>& storage);
00731 
00732     /*
00733      * These constructors make the array a view of a subportion of another
00734      * array.  If there fewer than N_rank Range arguments provided, no
00735      * slicing is performed in the unspecified ranks.
00736      * e.g. Array<int,3> A(20,20,20);
00737      *      Array<int,3> B(A, Range(5,15));
00738      * is equivalent to:
00739      *      Array<int,3> B(A, Range(5,15), Range::all(), Range::all());
00740      */
00741     Array(Array<T_numtype, N_rank>& array, Range r0)
00742     {
00743         constructSubarray(array, r0);
00744     }
00745 
00746     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1)
00747     {
00748         constructSubarray(array, r0, r1);
00749     }
00750 
00751     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2)
00752     {
00753         constructSubarray(array, r0, r1, r2);
00754     }
00755 
00756     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00757         Range r3)
00758     {
00759         constructSubarray(array, r0, r1, r2, r3);
00760     }
00761 
00762     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00763         Range r3, Range r4)
00764     {
00765         constructSubarray(array, r0, r1, r2, r3, r4);
00766     }
00767 
00768     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00769         Range r3, Range r4, Range r5)
00770     {
00771         constructSubarray(array, r0, r1, r2, r3, r4, r5);
00772     }
00773 
00774     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00775         Range r3, Range r4, Range r5, Range r6)
00776     {
00777         constructSubarray(array, r0, r1, r2, r3, r4, r5, r6);
00778     }
00779 
00780     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00781         Range r3, Range r4, Range r5, Range r6, Range r7)
00782     {
00783         constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7);
00784     }
00785 
00786     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00787         Range r3, Range r4, Range r5, Range r6, Range r7, Range r8)
00788     {
00789         constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8);
00790     }
00791 
00792     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00793         Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9)
00794     {
00795         constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9);
00796     }
00797 
00798     Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
00799         Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9,
00800         Range r10)
00801     {
00802         constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10);
00803     }
00804 
00805     Array(Array<T_numtype, N_rank>& array, 
00806         const RectDomain<N_rank>& subdomain)
00807     {
00808         constructSubarray(array, subdomain);
00809     }
00810 
00811     /* Constructor added by Julian Cummings */
00812     Array(Array<T_numtype, N_rank>& array, 
00813         const StridedDomain<N_rank>& subdomain)
00814     {
00815         constructSubarray(array, subdomain);
00816     }
00817 
00818     /*
00819      * This constructor is invoked by the operator()'s which take
00820      * a combination of integer and Range arguments.  It's not intended
00821      * for end-user use.
00822      */
00823     template<int N_rank2, typename R0, typename R1, typename R2, typename R3, typename R4,
00824         typename R5, typename R6, typename R7, typename R8, typename R9, typename R10>
00825     Array(Array<T_numtype,N_rank2>& array, R0 r0, R1 r1, R2 r2,
00826         R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10)
00827     {
00828         constructSlice(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10);
00829     }
00830 
00832     // Member functions
00834 
00835     const TinyVector<int, N_rank>&    base() const
00836     { return storage_.base(); }
00837 
00838     int                               base(int rank) const
00839     { return storage_.base(rank); }
00840 
00841     iterator                          begin() 
00842     { return iterator(*this); }
00843 
00844     const_iterator                    begin() const
00845     { return const_iterator(*this); }
00846 
00847     T_iterator                        beginFast() const
00848     { return T_iterator(*this); }
00849 
00850     // Deprecated: now extractComponent(...)
00851     template<typename P_numtype2>
00852     Array<P_numtype2,N_rank>          chopComponent(P_numtype2 a, int compNum,
00853                                           int numComponents) const
00854     { return extractComponent(a, compNum, numComponents); }
00855 
00856     int                               cols() const
00857     { return length_[1]; }
00858 
00859     int                               columns() const
00860     { return length_[1]; }
00861 
00862     T_array                           copy() const;
00863 
00864     // data_ always refers to the point (0,0,...,0) which may
00865     // not be in the array if the base is not zero in each rank.
00866     // These data() routines return a pointer to the first
00867     // element in the array (but note that it may not be
00868     // stored first in memory if some ranks are stored descending).
00869 
00870     int                               dataOffset() const
00871     {
00872         return dot(storage_.base(), stride_);
00873     }
00874 
00875     const T_numtype* restrict     data() const
00876     { return data_ + dataOffset(); }
00877 
00878     T_numtype* restrict           data() 
00879     { return data_ + dataOffset(); }
00880 
00881     // These dataZero() routines refer to the point (0,0,...,0)
00882     // which may not be in the array if the bases are nonzero.
00883     
00884     const T_numtype* restrict     dataZero() const
00885     { return data_; }
00886 
00887     T_numtype* restrict           dataZero()
00888     { return data_; }
00889 
00890     // These dataFirst() routines refer to the element in the
00891     // array which falls first in memory.
00892 
00893     int                               dataFirstOffset() const
00894     {
00895         int pos = 0;
00896 
00897         // Used to use tinyvector expressions:
00898         // return data_ + dot(storage_.base()
00899         //     + (1 - storage_.ascendingFlag()) * (length_ - 1), stride_);
00900 
00901         for (int i=0; i < N_rank; ++i)
00902            pos += (storage_.base(i) + (1-storage_.isRankStoredAscending(i)) *
00903               (length_(i)-1)) * stride_(i);
00904 
00905         return pos;
00906     }
00907     
00908     const T_numtype* restrict     dataFirst() const
00909     {
00910         return data_ + dataFirstOffset();
00911     }
00912 
00913     T_numtype* restrict           dataFirst()
00914     {
00915         return data_ + dataFirstOffset();
00916     }
00917 
00918     int                               depth() const
00919     { return length_[2]; }
00920 
00921     int                               dimensions() const
00922     { return N_rank; }
00923 
00924     RectDomain<N_rank>                domain() const
00925     {
00926         return RectDomain<N_rank>(lbound(), ubound());
00927     }
00928 
00929     void dumpStructureInformation(ostream& os = cout) const;
00930 
00931     iterator                          end()
00932     {
00933         return iterator();
00934     }
00935 
00936     const_iterator                    end() const
00937     {
00938         return const_iterator();
00939     }
00940 
00941     int                               extent(int rank) const
00942     { return length_[rank]; }
00943 
00944     const TinyVector<int,N_rank>&     extent() const
00945     { return length_; }
00946 
00947     template<typename P_numtype2>
00948     Array<P_numtype2,N_rank>          extractComponent(P_numtype2, int compNum,
00949                                           int numComponents) const;
00950 
00951     void                              free() 
00952     {
00953         changeToNullBlock();
00954         length_ = 0;
00955     }
00956  
00957     bool isMajorRank(int rank) const { return storage_.ordering(rank) == 0; }
00958     bool isMinorRank(int rank) const { return storage_.ordering(rank) != 0; }
00959     bool isRankStoredAscending(int rank) const {
00960         return storage_.isRankStoredAscending(rank);
00961     }
00962 
00963     bool isStorageContiguous() const;
00964 
00965     int                    lbound(int rank) const { return base(rank); }
00966     TinyVector<int,N_rank> lbound()         const { return base(); }
00967 
00968     int                            length(int rank) const { return length_[rank]; }
00969     const TinyVector<int, N_rank>& length()         const { return length_; }
00970 
00971     void makeUnique();
00972 
00973     int numElements() const { return product(length_); }
00974 
00975     // NEEDS_WORK -- Expose the numReferences() method
00976     // MemoryBlockReference<T_numtype>::numReferences;
00977 
00978     // The storage_.ordering_ array is a list of dimensions from
00979     // the most minor (stride 1) to major dimension.  Generally,
00980     // ordering(0) will return the dimension which has the smallest
00981     // stride, and ordering(N_rank-1) will return the dimension with
00982     // the largest stride.
00983     int                               ordering(int storageRankIndex) const
00984     { return storage_.ordering(storageRankIndex); }
00985 
00986     const TinyVector<int, N_rank>&    ordering() const
00987     { return storage_.ordering(); }
00988 
00989     void                              transposeSelf(int r0, int r1, int r2=0, 
00990         int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int 
00991         r9=0, int r10=0);
00992     T_array                           transpose(int r0, int r1, int r2=0,
00993         int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int
00994         r9=0, int r10=0);
00995 
00996     int                               rank() const
00997     { return N_rank; }
00998 
00999     void                              reference(const T_array&);
01000 
01001     // Added by Derrick Bass
01002     T_array                           reindex(const TinyVector<int,N_rank>&);
01003     void                              reindexSelf(const 
01004                                                 TinyVector<int,N_rank>&);
01005 
01006     void                              resize(int extent);
01007     void                              resize(int extent1, int extent2);
01008     void                              resize(int extent1, int extent2,
01009                                         int extent3);
01010     void                              resize(int extent1, int extent2,
01011                                         int extent3, int extent4);
01012     void                              resize(int extent1, int extent2,
01013                                         int extent3, int extent4, int extent5);
01014     void                              resize(int extent1, int extent2,
01015                                         int extent3, int extent4, int extent5,
01016                                         int extent6);
01017     void                              resize(int extent1, int extent2,
01018                                         int extent3, int extent4, int extent5,
01019                                         int extent6, int extent7);
01020     void                              resize(int extent1, int extent2,
01021                                         int extent3, int extent4, int extent5,
01022                                         int extent6, int extent7, int extent8);
01023     void                              resize(int extent1, int extent2,
01024                                         int extent3, int extent4, int extent5,
01025                                         int extent6, int extent7, int extent8,
01026                                         int extent9);
01027     void                              resize(int extent1, int extent2,
01028                                         int extent3, int extent4, int extent5,
01029                                         int extent6, int extent7, int extent8,
01030                                         int extent9, int extent10);
01031     void                              resize(int extent1, int extent2,
01032                                         int extent3, int extent4, int extent5,
01033                                         int extent6, int extent7, int extent8,
01034                                         int extent9, int extent10, 
01035                                         int extent11);
01036 
01037 
01038     void                              resize(Range r1);
01039     void                              resize(Range r1, Range r2);
01040     void                              resize(Range r1, Range r2, Range r3);
01041     void                              resize(Range r1, Range r2, Range r3,
01042                                         Range r4);
01043     void                              resize(Range r1, Range r2, Range r3,
01044                                         Range r4, Range r5);
01045     void                              resize(Range r1, Range r2, Range r3,
01046                                         Range r4, Range r5, Range r6);
01047     void                              resize(Range r1, Range r2, Range r3,
01048                                         Range r4, Range r5, Range r6,
01049                                         Range r7);
01050     void                              resize(Range r1, Range r2, Range r3,
01051                                         Range r4, Range r5, Range r6,
01052                                         Range r7, Range r8);
01053     void                              resize(Range r1, Range r2, Range r3,
01054                                         Range r4, Range r5, Range r6,
01055                                         Range r7, Range r8, Range r9);
01056     void                              resize(Range r1, Range r2, Range r3,
01057                                         Range r4, Range r5, Range r6,
01058                                         Range r7, Range r8, Range r9, 
01059                                         Range r10);
01060     void                              resize(Range r1, Range r2, Range r3,
01061                                         Range r4, Range r5, Range r6,
01062                                         Range r7, Range r8, Range r9, 
01063                                         Range r10, Range r11);
01064 
01065     void                              resize(const TinyVector<int,N_rank>&);
01066  
01067 
01068     void                              resizeAndPreserve(const TinyVector<int,
01069                                                                    N_rank>&);
01070     void                              resizeAndPreserve(int extent);
01071     void                              resizeAndPreserve(int extent1, 
01072                                         int extent2);
01073     void                              resizeAndPreserve(int extent1, 
01074                                         int extent2, int extent3);
01075     void                              resizeAndPreserve(int extent1,
01076                                         int extent2, int extent3, int extent4);
01077     void                              resizeAndPreserve(int extent1,
01078                                         int extent2, int extent3, int extent4,
01079                                         int extent5);
01080     void                              resizeAndPreserve(int extent1,
01081                                         int extent2, int extent3, int extent4,
01082                                         int extent5, int extent6);
01083     void                              resizeAndPreserve(int extent1,
01084                                         int extent2, int extent3, int extent4,
01085                                         int extent5, int extent6, int extent7);
01086     void                              resizeAndPreserve(int extent1,
01087                                         int extent2, int extent3, int extent4,
01088                                         int extent5, int extent6, int extent7,
01089                                         int extent8);
01090     void                              resizeAndPreserve(int extent1,
01091                                         int extent2, int extent3, int extent4,
01092                                         int extent5, int extent6, int extent7,
01093                                         int extent8, int extent9);
01094     void                              resizeAndPreserve(int extent1,
01095                                         int extent2, int extent3, int extent4,
01096                                         int extent5, int extent6, int extent7,
01097                                         int extent8, int extent9, 
01098                                         int extent10);
01099     void                              resizeAndPreserve(int extent1,
01100                                         int extent2, int extent3, int extent4,
01101                                         int extent5, int extent6, int extent7,
01102                                         int extent8, int extent9, int extent10,
01103                                         int extent11);
01104 
01105     // NEEDS_WORK -- resizeAndPreserve(Range,...)
01106     // NEEDS_WORK -- resizeAndPreserve(const Domain<N_rank>&);
01107 
01108     T_array                           reverse(int rank);
01109     void                              reverseSelf(int rank);
01110 
01111     int                               rows() const
01112     { return length_[0]; }
01113     
01114     void                              setStorage(GeneralArrayStorage<N_rank>);
01115     
01116     void                              slice(int rank, Range r);
01117 
01118     const TinyVector<int, N_rank>&    shape() const
01119     { return length_; }
01120 
01121     int                               size() const
01122     { return numElements(); }
01123 
01124     const TinyVector<int, N_rank>&    stride() const
01125     { return stride_; }
01126 
01127     int                               stride(int rank) const
01128     { return stride_[rank]; }
01129 
01130     int                               ubound(int rank) const
01131     { return base(rank) + length_(rank) - 1; }
01132 
01133     TinyVector<int, N_rank>           ubound() const
01134     { 
01135         TinyVector<int, N_rank> ub;
01136         for (int i=0; i < N_rank; ++i)
01137           ub(i) = base(i) + extent(i) - 1;
01138         // WAS: ub = base() + extent() - 1;
01139         return ub;
01140     }
01141 
01142     int                               zeroOffset() const
01143     { return zeroOffset_; }
01144 
01146     // Debugging routines
01148 
01149     bool isInRangeForDim(int i, int d) const {
01150         return i >= base(d) && (i - base(d)) < length_[d];
01151     }
01152 
01153     bool isInRange(int i0) const {
01154         return i0 >= base(0) && (i0 - base(0)) < length_[0];
01155     }
01156 
01157     bool isInRange(int i0, int i1) const {
01158         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01159             && i1 >= base(1) && (i1 - base(1)) < length_[1];
01160     }
01161 
01162     bool isInRange(int i0, int i1, int i2) const {
01163         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01164             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01165             && i2 >= base(2) && (i2 - base(2)) < length_[2];
01166     }
01167 
01168     bool isInRange(int i0, int i1, int i2, int i3) const {
01169         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01170             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01171             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01172             && i3 >= base(3) && (i3 - base(3)) < length_[3];
01173     }
01174 
01175     bool isInRange(int i0, int i1, int i2, int i3, int i4) const {
01176         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01177             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01178             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01179             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01180             && i4 >= base(4) && (i4 - base(4)) < length_[4];
01181     }
01182 
01183     bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5) const {
01184         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01185             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01186             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01187             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01188             && i4 >= base(4) && (i4 - base(4)) < length_[4]
01189             && i5 >= base(5) && (i5 - base(5)) < length_[5];
01190     }
01191 
01192     bool isInRange(int i0, int i1, int i2, int i3, int i4, int i5, int i6) const {
01193         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01194             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01195             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01196             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01197             && i4 >= base(4) && (i4 - base(4)) < length_[4]
01198             && i5 >= base(5) && (i5 - base(5)) < length_[5]
01199             && i6 >= base(6) && (i6 - base(6)) < length_[6];
01200     }
01201 
01202     bool isInRange(int i0, int i1, int i2, int i3, int i4,
01203         int i5, int i6, int i7) const {
01204         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01205             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01206             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01207             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01208             && i4 >= base(4) && (i4 - base(4)) < length_[4]
01209             && i5 >= base(5) && (i5 - base(5)) < length_[5]
01210             && i6 >= base(6) && (i6 - base(6)) < length_[6]
01211             && i7 >= base(7) && (i7 - base(7)) < length_[7];
01212     }
01213 
01214     bool isInRange(int i0, int i1, int i2, int i3, int i4,
01215         int i5, int i6, int i7, int i8) const {
01216         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01217             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01218             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01219             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01220             && i4 >= base(4) && (i4 - base(4)) < length_[4]
01221             && i5 >= base(5) && (i5 - base(5)) < length_[5]
01222             && i6 >= base(6) && (i6 - base(6)) < length_[6]
01223             && i7 >= base(7) && (i7 - base(7)) < length_[7]
01224             && i8 >= base(8) && (i8 - base(8)) < length_[8];
01225     }
01226 
01227     bool isInRange(int i0, int i1, int i2, int i3, int i4,
01228         int i5, int i6, int i7, int i8, int i9) const {
01229         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01230             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01231             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01232             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01233             && i4 >= base(4) && (i4 - base(4)) < length_[4]
01234             && i5 >= base(5) && (i5 - base(5)) < length_[5]
01235             && i6 >= base(6) && (i6 - base(6)) < length_[6]
01236             && i7 >= base(7) && (i7 - base(7)) < length_[7]
01237             && i8 >= base(8) && (i8 - base(8)) < length_[8]
01238             && i9 >= base(9) && (i9 - base(9)) < length_[9];
01239     }
01240 
01241     bool isInRange(int i0, int i1, int i2, int i3, int i4,
01242         int i5, int i6, int i7, int i8, int i9, int i10) const {
01243         return i0 >= base(0) && (i0 - base(0)) < length_[0]
01244             && i1 >= base(1) && (i1 - base(1)) < length_[1]
01245             && i2 >= base(2) && (i2 - base(2)) < length_[2]
01246             && i3 >= base(3) && (i3 - base(3)) < length_[3]
01247             && i4 >= base(4) && (i4 - base(4)) < length_[4]
01248             && i5 >= base(5) && (i5 - base(5)) < length_[5]
01249             && i6 >= base(6) && (i6 - base(6)) < length_[6]
01250             && i7 >= base(7) && (i7 - base(7)) < length_[7]
01251             && i8 >= base(8) && (i8 - base(8)) < length_[8]
01252             && i9 >= base(9) && (i9 - base(9)) < length_[9]
01253             && i10 >= base(10) && (i10 - base(10)) < length_[10];
01254     }
01255 
01256     bool isInRange(const T_index& index) const {
01257         for (int i=0; i < N_rank; ++i)
01258             if (index[i] < base(i) || (index[i] - base(i)) >= length_[i])
01259                 return false;
01260 
01261         return true;
01262     }
01263 
01264     bool assertInRange(const T_index& BZ_DEBUG_PARAM(index)) const {
01265         BZPRECHECK(isInRange(index), "Array index out of range: " << index
01266             << endl << "Lower bounds: " << storage_.base() << endl
01267             <<         "Length:       " << length_ << endl);
01268         return true;
01269     }
01270 
01271     bool assertInRange(int BZ_DEBUG_PARAM(i0)) const {
01272         BZPRECHECK(isInRange(i0), "Array index out of range: " << i0
01273             << endl << "Lower bounds: " << storage_.base() << endl
01274             <<         "Length:       " << length_ << endl);
01275         return true;
01276     }
01277 
01278     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1)) const {
01279         BZPRECHECK(isInRange(i0,i1), "Array index out of range: (" 
01280             << i0 << ", " << i1 << ")"
01281             << endl << "Lower bounds: " << storage_.base() << endl
01282             <<         "Length:       " << length_ << endl);
01283         return true;
01284     }
01285 
01286     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01287         int BZ_DEBUG_PARAM(i2)) const
01288     {
01289         BZPRECHECK(isInRange(i0,i1,i2), "Array index out of range: ("
01290             << i0 << ", " << i1 << ", " << i2 << ")"
01291             << endl << "Lower bounds: " << storage_.base() << endl
01292             <<         "Length:       " << length_ << endl);
01293         return true;
01294     }
01295 
01296     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01297         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3)) const
01298     {
01299         BZPRECHECK(isInRange(i0,i1,i2,i3), "Array index out of range: ("
01300             << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ")"
01301             << endl << "Lower bounds: " << storage_.base() << endl
01302             <<         "Length:       " << length_ << endl);
01303         return true;
01304     }
01305 
01306     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01307         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3),
01308         int BZ_DEBUG_PARAM(i4)) const
01309     {
01310         BZPRECHECK(isInRange(i0,i1,i2,i3,i4), "Array index out of range: ("
01311             << i0 << ", " << i1 << ", " << i2 << ", " << i3 
01312             << ", " << i4 << ")"
01313             << endl << "Lower bounds: " << storage_.base() << endl
01314             <<         "Length:       " << length_ << endl);
01315         return true;
01316     }
01317 
01318     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01319         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4),
01320         int BZ_DEBUG_PARAM(i5)) const
01321     {
01322         BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5), "Array index out of range: ("
01323             << i0 << ", " << i1 << ", " << i2 << ", " << i3
01324             << ", " << i4 << ", " << i5 << ")"
01325             << endl << "Lower bounds: " << storage_.base() << endl
01326             <<         "Length:       " << length_ << endl);
01327         return true;
01328     }
01329 
01330     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01331         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4),
01332         int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6)) const
01333     {
01334         BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6), 
01335             "Array index out of range: ("
01336             << i0 << ", " << i1 << ", " << i2 << ", " << i3
01337             << ", " << i4 << ", " << i5 << ", " << i6 << ")"
01338             << endl << "Lower bounds: " << storage_.base() << endl
01339             <<         "Length:       " << length_ << endl);
01340         return true;
01341     }
01342 
01343     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01344         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4),
01345         int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6),
01346         int BZ_DEBUG_PARAM(i7)) const
01347     {
01348         BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7),
01349             "Array index out of range: ("
01350             << i0 << ", " << i1 << ", " << i2 << ", " << i3
01351             << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 << ")"
01352             << endl << "Lower bounds: " << storage_.base() << endl
01353             <<         "Length:       " << length_ << endl);
01354         return true;
01355     }
01356 
01357     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01358         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4),
01359         int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7),
01360         int BZ_DEBUG_PARAM(i8)) const
01361     {
01362         BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8),
01363             "Array index out of range: ("
01364             << i0 << ", " << i1 << ", " << i2 << ", " << i3
01365             << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 
01366             << ", " << i8 << ")"
01367             << endl << "Lower bounds: " << storage_.base() << endl
01368             <<         "Length:       " << length_ << endl);
01369         return true;
01370     }
01371 
01372     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01373         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4),
01374         int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7),
01375         int BZ_DEBUG_PARAM(i8), int BZ_DEBUG_PARAM(i9)) const
01376     {
01377         BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8,i9),
01378             "Array index out of range: ("
01379             << i0 << ", " << i1 << ", " << i2 << ", " << i3
01380             << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7
01381             << ", " << i8 << ", " << i9 << ")"
01382             << endl << "Lower bounds: " << storage_.base() << endl
01383             <<         "Length:       " << length_ << endl);
01384         return true;
01385     }
01386 
01387     bool assertInRange(int BZ_DEBUG_PARAM(i0), int BZ_DEBUG_PARAM(i1),
01388         int BZ_DEBUG_PARAM(i2), int BZ_DEBUG_PARAM(i3), int BZ_DEBUG_PARAM(i4),
01389         int BZ_DEBUG_PARAM(i5), int BZ_DEBUG_PARAM(i6), int BZ_DEBUG_PARAM(i7),
01390         int BZ_DEBUG_PARAM(i8), int BZ_DEBUG_PARAM(i9),
01391         int BZ_DEBUG_PARAM(i10)) const
01392     {
01393         BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10),
01394             "Array index out of range: ("
01395             << i0 << ", " << i1 << ", " << i2 << ", " << i3
01396             << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7
01397             << ", " << i8 << ", " << i9 << ", " << i10 << ")"
01398             << endl << "Lower bounds: " << storage_.base() << endl
01399             <<         "Length:       " << length_ << endl);
01400         return true;
01401     }
01402 
01404     // Subscripting operators
01406 
01407     template<int N_rank2>
01408     const T_numtype& restrict operator()(const TinyVector<int,N_rank2>& index) const
01409     {
01410         assertInRange(index);
01411         return data_[dot(index, stride_)];
01412     }
01413 
01414     template<int N_rank2>
01415     T_numtype& restrict operator()(const TinyVector<int,N_rank2>& index) 
01416     {
01417         assertInRange(index);
01418         return data_[dot(index, stride_)];
01419     }
01420 
01421     const T_numtype& restrict operator()(TinyVector<int,1> index) const
01422     {
01423         assertInRange(index[0]);
01424         return data_[index[0] * stride_[0]];
01425     }
01426 
01427     T_numtype& operator()(TinyVector<int,1> index)
01428     {
01429         assertInRange(index[0]);
01430         return data_[index[0] * stride_[0]];
01431     }
01432 
01433     const T_numtype& restrict operator()(TinyVector<int,2> index) const
01434     {
01435         assertInRange(index[0], index[1]);
01436         return data_[index[0] * stride_[0] + index[1] * stride_[1]];
01437     }
01438 
01439     T_numtype& operator()(TinyVector<int,2> index)
01440     {
01441         assertInRange(index[0], index[1]);
01442         return data_[index[0] * stride_[0] + index[1] * stride_[1]];
01443     }
01444 
01445     const T_numtype& restrict operator()(TinyVector<int,3> index) const
01446     {
01447         assertInRange(index[0], index[1], index[2]);
01448         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01449             + index[2] * stride_[2]];
01450     }
01451 
01452     T_numtype& operator()(TinyVector<int,3> index)
01453     {
01454         assertInRange(index[0], index[1], index[2]);
01455         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01456             + index[2] * stride_[2]];
01457     }
01458 
01459     const T_numtype& restrict operator()(const TinyVector<int,4>& index) const
01460     {
01461         assertInRange(index[0], index[1], index[2], index[3]);
01462         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01463             + index[2] * stride_[2] + index[3] * stride_[3]];
01464     }
01465 
01466     T_numtype& operator()(const TinyVector<int,4>& index)
01467     {
01468         assertInRange(index[0], index[1], index[2], index[3]);
01469         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01470             + index[2] * stride_[2] + index[3] * stride_[3]];
01471     }
01472 
01473     const T_numtype& restrict operator()(const TinyVector<int,5>& index) const
01474     {
01475         assertInRange(index[0], index[1], index[2], index[3],
01476             index[4]);
01477         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01478             + index[2] * stride_[2] + index[3] * stride_[3]
01479             + index[4] * stride_[4]];
01480     }
01481 
01482     T_numtype& operator()(const TinyVector<int,5>& index)
01483     {
01484         assertInRange(index[0], index[1], index[2], index[3],
01485             index[4]);
01486         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01487             + index[2] * stride_[2] + index[3] * stride_[3]
01488             + index[4] * stride_[4]];
01489     }
01490 
01491     const T_numtype& restrict operator()(const TinyVector<int,6>& index) const
01492     {
01493         assertInRange(index[0], index[1], index[2], index[3],
01494             index[4], index[5]);
01495         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01496             + index[2] * stride_[2] + index[3] * stride_[3]
01497             + index[4] * stride_[4] + index[5] * stride_[5]];
01498     }
01499 
01500     T_numtype& operator()(const TinyVector<int,6>& index)
01501     {
01502         assertInRange(index[0], index[1], index[2], index[3],
01503             index[4], index[5]);
01504         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01505             + index[2] * stride_[2] + index[3] * stride_[3]
01506             + index[4] * stride_[4] + index[5] * stride_[5]];
01507     }
01508 
01509     const T_numtype& restrict operator()(const TinyVector<int,7>& index) const
01510     {
01511         assertInRange(index[0], index[1], index[2], index[3],
01512             index[4], index[5], index[6]);
01513         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01514             + index[2] * stride_[2] + index[3] * stride_[3]
01515             + index[4] * stride_[4] + index[5] * stride_[5]
01516             + index[6] * stride_[6]];
01517     }
01518 
01519     T_numtype& operator()(const TinyVector<int,7>& index)
01520     {
01521         assertInRange(index[0], index[1], index[2], index[3],
01522             index[4], index[5], index[6]);
01523         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01524             + index[2] * stride_[2] + index[3] * stride_[3]
01525             + index[4] * stride_[4] + index[5] * stride_[5]
01526             + index[6] * stride_[6]];
01527     }
01528 
01529     const T_numtype& restrict operator()(const TinyVector<int,8>& index) const
01530     {
01531         assertInRange(index[0], index[1], index[2], index[3],
01532             index[4], index[5], index[6], index[7]);
01533         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01534             + index[2] * stride_[2] + index[3] * stride_[3]
01535             + index[4] * stride_[4] + index[5] * stride_[5]
01536             + index[6] * stride_[6] + index[7] * stride_[7]];
01537     }
01538 
01539     T_numtype& operator()(const TinyVector<int,8>& index)
01540     {
01541         assertInRange(index[0], index[1], index[2], index[3],
01542             index[4], index[5], index[6], index[7]);
01543         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01544             + index[2] * stride_[2] + index[3] * stride_[3]
01545             + index[4] * stride_[4] + index[5] * stride_[5]
01546             + index[6] * stride_[6] + index[7] * stride_[7]];
01547     }
01548 
01549     const T_numtype& restrict operator()(const TinyVector<int,9>& index) const
01550     {
01551         assertInRange(index[0], index[1], index[2], index[3],
01552             index[4], index[5], index[6], index[7], index[8]);
01553         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01554             + index[2] * stride_[2] + index[3] * stride_[3]
01555             + index[4] * stride_[4] + index[5] * stride_[5]
01556             + index[6] * stride_[6] + index[7] * stride_[7]
01557             + index[8] * stride_[8]];
01558     }
01559 
01560     T_numtype& operator()(const TinyVector<int,9>& index)
01561     {
01562         assertInRange(index[0], index[1], index[2], index[3],
01563             index[4], index[5], index[6], index[7], index[8]);
01564         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01565             + index[2] * stride_[2] + index[3] * stride_[3]
01566             + index[4] * stride_[4] + index[5] * stride_[5]
01567             + index[6] * stride_[6] + index[7] * stride_[7]
01568             + index[8] * stride_[8]];
01569     }
01570 
01571     const T_numtype& restrict operator()(const TinyVector<int,10>& index) const
01572     {
01573         assertInRange(index[0], index[1], index[2], index[3],
01574             index[4], index[5], index[6], index[7], index[8], index[9]);
01575         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01576             + index[2] * stride_[2] + index[3] * stride_[3]
01577             + index[4] * stride_[4] + index[5] * stride_[5]
01578             + index[6] * stride_[6] + index[7] * stride_[7]
01579             + index[8] * stride_[8] + index[9] * stride_[9]];
01580     }
01581 
01582     T_numtype& operator()(const TinyVector<int,10>& index)
01583     {
01584         assertInRange(index[0], index[1], index[2], index[3],
01585             index[4], index[5], index[6], index[7], index[8], index[9]);
01586         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01587             + index[2] * stride_[2] + index[3] * stride_[3]
01588             + index[4] * stride_[4] + index[5] * stride_[5]
01589             + index[6] * stride_[6] + index[7] * stride_[7]
01590             + index[8] * stride_[8] + index[9] * stride_[9]];
01591     }
01592 
01593     const T_numtype& restrict operator()(const TinyVector<int,11>& index) const
01594     {
01595         assertInRange(index[0], index[1], index[2], index[3],
01596             index[4], index[5], index[6], index[7], index[8], index[9],
01597             index[10]);
01598         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01599             + index[2] * stride_[2] + index[3] * stride_[3]
01600             + index[4] * stride_[4] + index[5] * stride_[5]
01601             + index[6] * stride_[6] + index[7] * stride_[7]
01602             + index[8] * stride_[8] + index[9] * stride_[9]
01603             + index[10] * stride_[10]];
01604     }
01605 
01606     T_numtype& operator()(const TinyVector<int,11>& index)
01607     {
01608         assertInRange(index[0], index[1], index[2], index[3],
01609             index[4], index[5], index[6], index[7], index[8], index[9],
01610             index[10]);
01611         return data_[index[0] * stride_[0] + index[1] * stride_[1]
01612             + index[2] * stride_[2] + index[3] * stride_[3]
01613             + index[4] * stride_[4] + index[5] * stride_[5]
01614             + index[6] * stride_[6] + index[7] * stride_[7]
01615             + index[8] * stride_[8] + index[9] * stride_[9]
01616             + index[10] * stride_[10]];
01617     }
01618 
01619     const T_numtype& restrict operator()(int i0) const
01620     { 
01621         assertInRange(i0);
01622         return data_[i0 * stride_[0]]; 
01623     }
01624 
01625     T_numtype& restrict operator()(int i0) 
01626     {
01627         assertInRange(i0);
01628         return data_[i0 * stride_[0]];
01629     }
01630 
01631     const T_numtype& restrict operator()(int i0, int i1) const
01632     { 
01633         assertInRange(i0, i1);
01634         return data_[i0 * stride_[0] + i1 * stride_[1]];
01635     }
01636 
01637     T_numtype& restrict operator()(int i0, int i1)
01638     {
01639         assertInRange(i0, i1);
01640         return data_[i0 * stride_[0] + i1 * stride_[1]];
01641     }
01642 
01643     const T_numtype& restrict operator()(int i0, int i1, int i2) const
01644     {
01645         assertInRange(i0, i1, i2);
01646         return data_[i0 * stride_[0] + i1 * stride_[1]
01647             + i2 * stride_[2]];
01648     }
01649 
01650     T_numtype& restrict operator()(int i0, int i1, int i2) 
01651     {
01652         assertInRange(i0, i1, i2);
01653         return data_[i0 * stride_[0] + i1 * stride_[1]
01654             + i2 * stride_[2]];
01655     }
01656 
01657     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3) const
01658     {
01659         assertInRange(i0, i1, i2, i3);
01660         return data_[i0 * stride_[0] + i1 * stride_[1]
01661             + i2 * stride_[2] + i3 * stride_[3]];
01662     }
01663 
01664     T_numtype& restrict operator()(int i0, int i1, int i2, int i3)
01665     {
01666         assertInRange(i0, i1, i2, i3);
01667         return data_[i0 * stride_[0] + i1 * stride_[1]
01668             + i2 * stride_[2] + i3 * stride_[3]];
01669     }
01670 
01671     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01672         int i4) const
01673     {
01674         assertInRange(i0, i1, i2, i3, i4);
01675         return data_[i0 * stride_[0] + i1 * stride_[1]
01676             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]];
01677     }
01678 
01679     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01680         int i4)
01681     {
01682         assertInRange(i0, i1, i2, i3, i4);
01683         return data_[i0 * stride_[0] + i1 * stride_[1]
01684             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]];
01685     }
01686 
01687     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01688         int i4, int i5) const
01689     {
01690         assertInRange(i0, i1, i2, i3, i4, i5);
01691         return data_[i0 * stride_[0] + i1 * stride_[1]
01692             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01693             + i5 * stride_[5]];
01694     }
01695 
01696     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01697         int i4, int i5)
01698     {
01699         assertInRange(i0, i1, i2, i3, i4, i5);
01700         return data_[i0 * stride_[0] + i1 * stride_[1]
01701             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01702             + i5 * stride_[5]];
01703     }
01704 
01705     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01706         int i4, int i5, int i6) const
01707     {
01708         assertInRange(i0, i1, i2, i3, i4, i5, i6);
01709         return data_[i0 * stride_[0] + i1 * stride_[1]
01710             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01711             + i5 * stride_[5] + i6 * stride_[6]];
01712     }
01713 
01714     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01715         int i4, int i5, int i6)
01716     {
01717         assertInRange(i0, i1, i2, i3, i4, i5, i6);
01718         return data_[i0 * stride_[0] + i1 * stride_[1]
01719             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01720             + i5 * stride_[5] + i6 * stride_[6]];
01721     }
01722 
01723     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01724         int i4, int i5, int i6, int i7) const
01725     {
01726         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7);
01727         return data_[i0 * stride_[0] + i1 * stride_[1]
01728             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01729             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]];
01730     }
01731 
01732     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01733         int i4, int i5, int i6, int i7)
01734     {
01735         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7);
01736         return data_[i0 * stride_[0] + i1 * stride_[1]
01737             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01738             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]];
01739     }
01740 
01741     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01742         int i4, int i5, int i6, int i7, int i8) const
01743     {
01744         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8);
01745         return data_[i0 * stride_[0] + i1 * stride_[1]
01746             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01747             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
01748             + i8 * stride_[8]];
01749     }
01750 
01751     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01752         int i4, int i5, int i6, int i7, int i8)
01753     {
01754         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8);
01755         return data_[i0 * stride_[0] + i1 * stride_[1]
01756             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01757             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
01758             + i8 * stride_[8]];
01759     }
01760 
01761     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01762         int i4, int i5, int i6, int i7, int i8, int i9) const
01763     {
01764         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);
01765         return data_[i0 * stride_[0] + i1 * stride_[1]
01766             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01767             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
01768             + i8 * stride_[8] + i9 * stride_[9]];
01769     }
01770 
01771     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01772         int i4, int i5, int i6, int i7, int i8, int i9)
01773     {
01774         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);
01775         return data_[i0 * stride_[0] + i1 * stride_[1]
01776             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01777             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
01778             + i8 * stride_[8] + i9 * stride_[9]];
01779     }
01780 
01781     const T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01782         int i4, int i5, int i6, int i7, int i8, int i9, int i10) const
01783     {
01784         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, 
01785             i9, i10);
01786         return data_[i0 * stride_[0] + i1 * stride_[1]
01787             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01788             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
01789             + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]];
01790     }
01791 
01792     T_numtype& restrict operator()(int i0, int i1, int i2, int i3,
01793         int i4, int i5, int i6, int i7, int i8, int i9, int i10)
01794     {
01795         assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, 
01796             i9, i10);
01797         return data_[i0 * stride_[0] + i1 * stride_[1]
01798             + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
01799             + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
01800             + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]];
01801     }
01802 
01803     /*
01804      * Slicing to produce subarrays.  If the number of Range arguments is
01805      * fewer than N_rank, then missing arguments are treated like Range::all().
01806      */
01807 
01808     T_array& noConst() const
01809     { return const_cast<T_array&>(*this); }
01810 
01811     T_array operator()(const RectDomain<N_rank>& subdomain) const
01812     {
01813         return T_array(noConst(), subdomain);
01814     }
01815 
01816     /* Operator added by Julian Cummings */
01817     T_array operator()(const StridedDomain<N_rank>& subdomain) const
01818     {
01819         return T_array(noConst(), subdomain);
01820     }
01821 
01822     T_array operator()(Range r0) const
01823     {
01824         return T_array(noConst(), r0);
01825     }
01826 
01827     T_array operator()(Range r0, Range r1) const
01828     {
01829         return T_array(noConst(), r0, r1);
01830     }
01831 
01832     T_array operator()(Range r0, Range r1, Range r2) const
01833     {
01834         return T_array(noConst(), r0, r1, r2);
01835     }
01836 
01837     T_array operator()(Range r0, Range r1, Range r2, Range r3) const
01838     {
01839         return T_array(noConst(), r0, r1, r2, r3);
01840     }
01841 
01842     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4) const
01843     {
01844         return T_array(noConst(), r0, r1, r2, r3, r4);
01845     }
01846 
01847     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
01848         Range r5) const
01849     {
01850         return T_array(noConst(), r0, r1, r2, r3, r4, r5);
01851     }
01852 
01853     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
01854         Range r5, Range r6) const
01855     {
01856         return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6);
01857     }
01858 
01859     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
01860         Range r5, Range r6, Range r7) const
01861     {
01862         return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7);
01863     }
01864 
01865     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
01866         Range r5, Range r6, Range r7, Range r8) const
01867     {
01868         return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7, r8);
01869     }
01870 
01871     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
01872         Range r5, Range r6, Range r7, Range r8, Range r9) const
01873     {
01874         return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7, r8, r9);
01875     }
01876 
01877     T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
01878         Range r5, Range r6, Range r7, Range r8, Range r9, Range r10) const
01879     {
01880         return T_array(noConst(), r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10);
01881     }
01882 
01883     // Allow any mixture of Range, int and Vector<int> objects as
01884     // operands for operator():   A(Range(3,7), 5, Range(2,4))
01885 
01886     /*
01887      * These versions of operator() allow any combination of int
01888      * and Range operands to be used.  Each int operand reduces
01889      * the rank of the resulting array by one.  
01890      *
01891      * e.g.  Array<int,4> A(20,20,20,20);
01892      *       Array<int,2> B = A(Range(5,15), 3, 5, Range(8,9));
01893      *
01894      * SliceInfo is a helper class defined in <blitz/arrayslice.h>.
01895      * It counts the number of Range vs. int arguments and does some
01896      * other helpful things.
01897      *
01898      * Once partial specialization becomes widely implemented, these
01899      * operators may be expanded to accept Vector<int> arguments
01900      * and produce ArrayPick<T,N> objects.
01901      *
01902      * This operator() is not provided with a single argument because
01903      * the appropriate cases exist above.
01904      */
01905 
01906 #ifdef BZ_HAVE_PARTIAL_ORDERING
01907 
01908     template<typename T1, typename T2>
01909     typename SliceInfo<T_numtype,T1,T2>::T_slice
01910     operator()(T1 r1, T2 r2) const
01911     {
01912         typedef typename SliceInfo<T_numtype,T1,T2>::T_slice slice;
01913         return slice(noConst(), r1, r2, nilArraySection(), nilArraySection(), nilArraySection(),
01914             nilArraySection(), nilArraySection(), nilArraySection(),
01915             nilArraySection(), nilArraySection(), nilArraySection());
01916     }
01917 
01918     template<typename T1, typename T2, typename T3>
01919     typename SliceInfo<T_numtype,T1,T2,T3>::T_slice 
01920     operator()(T1 r1, T2 r2, T3 r3) const
01921     {
01922         typedef typename SliceInfo<T_numtype,T1,T2,T3>::T_slice slice;
01923         return slice(noConst(), r1, r2, r3, nilArraySection(), nilArraySection(), nilArraySection(),
01924             nilArraySection(), nilArraySection(), nilArraySection(),
01925             nilArraySection(), nilArraySection());
01926     }
01927 
01928     template<typename T1, typename T2, typename T3, typename T4>
01929     typename SliceInfo<T_numtype,T1,T2,T3,T4>::T_slice
01930     operator()(T1 r1, T2 r2, T3 r3, T4 r4) const
01931     {
01932         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4>::T_slice slice;
01933         return slice(noConst(), r1, r2, r3, r4, nilArraySection(), nilArraySection(),
01934             nilArraySection(), nilArraySection(), nilArraySection(),
01935             nilArraySection(), nilArraySection());
01936     }
01937 
01938     template<typename T1, typename T2, typename T3, typename T4, typename T5>
01939     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5>::T_slice
01940     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5) const
01941     {
01942         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5>::T_slice slice;
01943         return slice(noConst(), r1, r2, r3, r4, r5, nilArraySection(),
01944             nilArraySection(), nilArraySection(), nilArraySection(),
01945             nilArraySection(), nilArraySection());
01946     }
01947 
01948     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
01949     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6>::T_slice
01950     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6) const
01951     {
01952         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6>::T_slice slice;
01953         return slice(noConst(), r1, r2, r3, r4, r5, r6, nilArraySection(), nilArraySection(), nilArraySection(),
01954             nilArraySection(), nilArraySection());
01955     }
01956 
01957     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
01958         typename T7>
01959     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7>::T_slice
01960     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7) const
01961     {
01962         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7>::T_slice slice;
01963         return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, nilArraySection(), nilArraySection(),
01964             nilArraySection(), nilArraySection());
01965     }
01966 
01967     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
01968         typename T7, typename T8>
01969     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8>::T_slice
01970     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8) const
01971     {
01972         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8>::T_slice slice;
01973         return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8,
01974             nilArraySection(), nilArraySection(), nilArraySection());
01975     }
01976 
01977     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
01978         typename T7, typename T8, typename T9>
01979     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9>::T_slice
01980     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9) const
01981     {
01982         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9>::T_slice slice;
01983         return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, r9, nilArraySection(), nilArraySection());
01984     }
01985 
01986     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
01987         typename T7, typename T8, typename T9, typename T10>
01988     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::T_slice
01989     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10) const
01990     {
01991         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::T_slice slice;
01992         return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, nilArraySection());
01993     }
01994 
01995     template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6,
01996         typename T7, typename T8, typename T9, typename T10, typename T11>
01997     typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice
01998     operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const
01999     {
02000         typedef typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11>::T_slice slice;
02001         return slice(noConst(), r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11);
02002     }
02003 
02004 #endif // BZ_HAVE_PARTIAL_ORDERING
02005 
02006     /*
02007      * These versions of operator() are provided to support tensor-style
02008      * array notation, e.g.
02009      *
02010      * Array<float, 2> A, B;
02011      * firstIndex i;
02012      * secondIndex j;
02013      * thirdIndex k;
02014      * Array<float, 3> C = A(i,j) * B(j,k);
02015      */
02016 
02017     template<int N0>
02018     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0> >
02019     operator()(IndexPlaceholder<N0>) const
02020     { 
02021         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0> >
02022             (noConst());
02023     }
02024 
02025     template<int N0, int N1>
02026     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1> >
02027     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>) const
02028     {
02029         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02030             N1> >(noConst());
02031     } 
02032 
02033     template<int N0, int N1, int N2>
02034     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2> >
02035     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02036         IndexPlaceholder<N2>) const
02037     {
02038         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02039             N1, N2> >(noConst());
02040     }
02041 
02042     template<int N0, int N1, int N2, int N3>
02043     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3> >
02044     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02045         IndexPlaceholder<N2>, IndexPlaceholder<N3>) const
02046     {
02047         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02048             N1, N2, N3> >(noConst());
02049     }
02050 
02051     template<int N0, int N1, int N2, int N3, int N4>
02052     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, N4> >
02053     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02054         IndexPlaceholder<N2>, IndexPlaceholder<N3>, 
02055         IndexPlaceholder<N4>) const
02056     {
02057         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02058             N1, N2, N3, N4> >(noConst());
02059     }
02060 
02061     template<int N0, int N1, int N2, int N3, int N4, int N5>
02062     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, 
02063         N4, N5> >
02064     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02065         IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
02066         IndexPlaceholder<N5>) const
02067     {
02068         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02069             N1, N2, N3, N4, N5> >(noConst());
02070     }
02071 
02072     template<int N0, int N1, int N2, int N3, int N4, int N5, int N6>
02073     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
02074         N4, N5, N6> >
02075     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02076         IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
02077         IndexPlaceholder<N5>, IndexPlaceholder<N6>) const
02078     {
02079         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02080             N1, N2, N3, N4, N5, N6> >(noConst());
02081     }
02082 
02083     template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
02084         int N7>
02085     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
02086         N4, N5, N6, N7> >
02087     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02088         IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
02089         IndexPlaceholder<N5>, IndexPlaceholder<N6>, 
02090         IndexPlaceholder<N7>) const
02091     {
02092         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02093             N1, N2, N3, N4, N5, N6, N7> >(noConst());
02094     }
02095 
02096     template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
02097         int N7, int N8>
02098     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
02099         N4, N5, N6, N7, N8> >
02100     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02101         IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
02102         IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>,
02103         IndexPlaceholder<N8>) const
02104     {
02105         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02106             N1, N2, N3, N4, N5, N6, N7, N8> >(noConst());
02107     }
02108 
02109     template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
02110         int N7, int N8, int N9>
02111     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
02112         N4, N5, N6, N7, N8, N9> >
02113     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02114         IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
02115         IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>,
02116         IndexPlaceholder<N8>, IndexPlaceholder<N9>) const
02117     {
02118         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02119             N1, N2, N3, N4, N5, N6, N7, N8, N9> >(noConst());
02120     }
02121 
02122     template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
02123         int N7, int N8, int N9, int N10>
02124     _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
02125         N4, N5, N6, N7, N8, N9, N10> >
02126     operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
02127         IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
02128         IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>,
02129         IndexPlaceholder<N8>, IndexPlaceholder<N9>, 
02130         IndexPlaceholder<N10>) const
02131     {
02132         return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
02133             N1, N2, N3, N4, N5, N6, N7, N8, N9, N10> >(noConst());
02134     }
02135 
02137     // Support for multicomponent arrays
02139 
02140     /*
02141      * See <blitz/array/multi.h> for an explanation of the traits class
02142      * multicomponent_traits.
02143      */
02144 
02145     Array<typename multicomponent_traits<T_numtype>::T_element,N_rank>
02146     operator[](const unsigned component) {
02147         typedef typename multicomponent_traits<T_numtype>::T_element T_compType;
02148 
02149         return extractComponent(T_compType(),component,
02150                                 multicomponent_traits<T_numtype>::numComponents);
02151     }
02152 
02153     const Array<typename multicomponent_traits<T_numtype>::T_element,N_rank>
02154     operator[](const unsigned component) const {
02155         typedef typename multicomponent_traits<T_numtype>::T_element T_compType;
02156 
02157         return extractComponent(T_compType(),component,
02158                                 multicomponent_traits<T_numtype>::numComponents);
02159     }
02160 
02161     Array<typename multicomponent_traits<T_numtype>::T_element,N_rank>
02162     operator[](const int component) {
02163         return operator[](static_cast<unsigned>(component));
02164     }
02165 
02166     const Array<typename multicomponent_traits<T_numtype>::T_element,N_rank>
02167     operator[](const int component) const {
02168         return operator[](static_cast<unsigned>(component));
02169     }
02170 
02172     // Indirection
02174  
02175     template<typename T_indexContainer>
02176     IndirectArray<T_array, T_indexContainer>
02177     operator[](const T_indexContainer& index)
02178     {
02179         return IndirectArray<T_array, T_indexContainer>(*this,
02180             const_cast<T_indexContainer&>(index));
02181     }
02182  
02184     // Assignment Operators
02186 
02187     // Scalar operand
02188     // NEEDS_WORK : need a precondition check on
02189     // isStorageContiguous when operator, is used.
02190     ListInitializationSwitch<T_array,T_numtype*> operator=(T_numtype x)
02191     {
02192         return ListInitializationSwitch<T_array,T_numtype*>(*this, x);
02193     }
02194 
02195     T_array& initialize(T_numtype);
02196 
02197     // Was:
02198     // T_array& operator=(T_numtype);
02199 
02200 #ifdef BZ_NEW_EXPRESSION_TEMPLATES
02201     template<typename T_expr>
02202     T_array& operator=(const ETBase<T_expr>&);
02203     T_array& operator=(const Array<T_numtype,N_rank>&);
02204 
02205     template<typename T> T_array& operator+=(const T&);
02206     template<typename T> T_array& operator-=(const T&);
02207     template<typename T> T_array& operator*=(const T&);
02208     template<typename T> T_array& operator/=(const T&);
02209     template<typename T> T_array& operator%=(const T&);
02210     template<typename T> T_array& operator^=(const T&);
02211     template<typename T> T_array& operator&=(const T&);
02212     template<typename T> T_array& operator|=(const T&);
02213     template<typename T> T_array& operator>>=(const T&);
02214     template<typename T> T_array& operator<<=(const T&);
02215 
02216 #else
02217     T_array& operator+=(T_numtype);
02218     T_array& operator-=(T_numtype);
02219     T_array& operator*=(T_numtype);
02220     T_array& operator/=(T_numtype);
02221     T_array& operator%=(T_numtype);
02222     T_array& operator^=(T_numtype);
02223     T_array& operator&=(T_numtype);
02224     T_array& operator|=(T_numtype);
02225     T_array& operator>>=(T_numtype);
02226     T_array& operator<<=(T_numtype);
02227 
02228     // Array operands
02229     T_array& operator=(const Array<T_numtype,N_rank>&);
02230 
02231     template<typename P_numtype2> 
02232     T_array& operator=(const Array<P_numtype2,N_rank>&);
02233     template<typename P_numtype2>
02234     T_array& operator+=(const Array<P_numtype2,N_rank>&);
02235     template<typename P_numtype2>
02236     T_array& operator-=(const Array<P_numtype2,N_rank>&);
02237     template<typename P_numtype2>
02238     T_array& operator*=(const Array<P_numtype2,N_rank>&);
02239     template<typename P_numtype2>
02240     T_array& operator/=(const Array<P_numtype2,N_rank>&);
02241     template<typename P_numtype2>
02242     T_array& operator%=(const Array<P_numtype2,N_rank>&);
02243     template<typename P_numtype2>
02244     T_array& operator^=(const Array<P_numtype2,N_rank>&);
02245     template<typename P_numtype2>
02246     T_array& operator&=(const Array<P_numtype2,N_rank>&);
02247     template<typename P_numtype2>
02248     T_array& operator|=(const Array<P_numtype2,N_rank>&);
02249     template<typename P_numtype2>
02250     T_array& operator>>=(const Array<P_numtype2,N_rank>&);
02251     template<typename P_numtype2>
02252     T_array& operator<<=(const Array<P_numtype2,N_rank>&);
02253 
02254     // Array expression operands
02255     template<typename T_expr>
02256     inline T_array& operator=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02257     template<typename T_expr>
02258     inline T_array& operator+=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02259     template<typename T_expr>
02260     inline T_array& operator-=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02261     template<typename T_expr>
02262     inline T_array& operator*=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02263     template<typename T_expr>
02264     inline T_array& operator/=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02265     template<typename T_expr>
02266     inline T_array& operator%=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02267     template<typename T_expr>
02268     inline T_array& operator^=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02269     template<typename T_expr>
02270     inline T_array& operator&=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02271     template<typename T_expr>
02272     inline T_array& operator|=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02273     template<typename T_expr>
02274     inline T_array& operator>>=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02275     template<typename T_expr>
02276     inline T_array& operator<<=(BZ_ETPARM(_bz_ArrayExpr<T_expr>) expr);
02277 
02278     // NEEDS_WORK -- Index placeholder operand
02279 
02280     // NEEDS_WORK -- Random operand
02281 #endif
02282 
02283 public:
02284     // Undocumented implementation routines
02285 
02286     template<typename T_expr, typename T_update>
02287     inline T_array& evaluate(T_expr expr, T_update);
02288 
02289 #ifdef BZ_HAVE_STD
02290 #ifdef BZ_ARRAY_SPACE_FILLING_TRAVERSAL
02291     template<typename T_expr, typename T_update>
02292     inline T_array& evaluateWithFastTraversal(
02293         const TraversalOrder<N_rank - 1>& order, 
02294         T_expr expr, T_update);
02295 #endif // BZ_ARRAY_SPACE_FILLING_TRAVERSAL
02296 #endif
02297 
02298 #ifdef BZ_ARRAY_2D_STENCIL_TILING
02299     template<typename T_expr, typename T_update>
02300     inline T_array& evaluateWithTiled2DTraversal(
02301         T_expr expr, T_update);
02302 #endif
02303 
02304     template<typename T_expr, typename T_update>
02305     inline T_array& evaluateWithIndexTraversal1(
02306         T_expr expr, T_update);
02307 
02308     template<typename T_expr, typename T_update>
02309     inline T_array& evaluateWithIndexTraversalN(
02310         T_expr expr, T_update);
02311 
02312     template<typename T_expr, typename T_update>
02313     inline T_array& evaluateWithStackTraversal1(
02314         T_expr expr, T_update);
02315 
02316     template<typename T_expr, typename T_update>
02317     inline T_array& evaluateWithStackTraversalN(
02318         T_expr expr, T_update);
02319 
02320 
02321     T_numtype* restrict getInitializationIterator() { return dataFirst(); }
02322 
02323     bool canCollapse(int outerRank, int innerRank) const { 
02324 #ifdef BZ_DEBUG_TRAVERSE
02325         BZ_DEBUG_MESSAGE("stride(" << innerRank << ")=" << stride(innerRank)
02326           << ", extent()=" << extent(innerRank) << ", stride(outerRank)="
02327           << stride(outerRank));
02328 #endif
02329         return (stride(innerRank) * extent(innerRank) == stride(outerRank)); 
02330     }
02331 
02332 protected:
02334     // Implementation routines
02336 
02337     _bz_inline2 void computeStrides();
02338     _bz_inline2 void setupStorage(int rank);
02339     void constructSubarray(Array<T_numtype, N_rank>& array, 
02340         const RectDomain<N_rank>&);
02341     void constructSubarray(Array<T_numtype, N_rank>& array,
02342         const StridedDomain<N_rank>&);
02343     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0);
02344     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0, Range r1);
02345     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02346         Range r1, Range r2);
02347     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02348         Range r1, Range r2, Range r3);
02349     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02350         Range r1, Range r2, Range r3, Range r4);
02351     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02352         Range r1, Range r2, Range r3, Range r4, Range r5);
02353     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02354         Range r1, Range r2, Range r3, Range r4, Range r5, Range r6);
02355     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02356         Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
02357         Range r7);
02358     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02359         Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
02360         Range r7, Range r8);
02361     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02362         Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
02363         Range r7, Range r8, Range r9);
02364     void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
02365         Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
02366         Range r7, Range r8, Range r9, Range r10);
02367 
02368     void calculateZeroOffset();
02369 
02370     template<int N_rank2, typename R0, typename R1, typename R2, typename R3, typename R4, 
02371         typename R5, typename R6, typename R7, typename R8, typename R9, typename R10>
02372     void constructSlice(Array<T_numtype, N_rank2>& array, R0 r0, R1 r1, R2 r2, 
02373         R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10);
02374 
02375     template<int N_rank2>
02376     void slice(int& setRank, Range r, Array<T_numtype,N_rank2>& array,
02377         TinyVector<int,N_rank2>& rankMap, int sourceRank);
02378 
02379     template<int N_rank2>
02380     void slice(int& setRank, int i, Array<T_numtype,N_rank2>& array,
02381         TinyVector<int,N_rank2>& rankMap, int sourceRank);
02382 
02383     template<int N_rank2>
02384     void slice(int&, nilArraySection, Array<T_numtype,N_rank2>&,
02385         TinyVector<int,N_rank2>&, int)
02386     { }
02387 
02388     void doTranspose(int destRank, int sourceRank, T_array& array);
02389 
02390 protected:
02392     // Data members
02394 
02395     // NB: adding new data members may require changes to ctors, reference()
02396 
02397     /*
02398      * For a description of the storage_ members, see the comments for class 
02399      * GeneralArrayStorage<N_rank> above.
02400      *
02401      * length_[] contains the extent of each rank.  E.g. a 10x20x30 array
02402      *           would have length_ = { 10, 20, 30}.
02403      * stride_[] contains the stride to move to the next element along each
02404      *           rank.
02405      * zeroOffset_ is the distance from the first element in the array 
02406      *           to the point (0,0,...,0).  If base_ is zero and all ranks are 
02407      *           stored ascending, then zeroOffset_ is zero.  This value
02408      *           is needed because to speed up indexing, the data_ member
02409      *           (inherited from MemoryBlockReference) always refers to
02410      *           (0,0,...,0).
02411      */
02412     GeneralArrayStorage<N_rank> storage_;
02413     TinyVector<int, N_rank> length_;
02414     TinyVector<int, N_rank> stride_;
02415     int zeroOffset_;
02416 };
02417 
02418 /*
02419  * Rank numbers start with zero, which may be confusing to users coming
02420  * from Fortran.  To make code more readable, the following constants
02421  * may help.  Example: instead of
02422  * 
02423  * int firstRankExtent = A.extent(0);
02424  *
02425  * One can write:
02426  *
02427  * int firstRankExtent = A.extent(firstRank);
02428  */
02429 
02430 const int firstRank    = 0;
02431 const int secondRank   = 1;
02432 const int thirdRank    = 2;
02433 const int fourthRank   = 3;
02434 const int fifthRank    = 4;
02435 const int sixthRank    = 5;
02436 const int seventhRank  = 6;
02437 const int eighthRank   = 7;
02438 const int ninthRank    = 8;
02439 const int tenthRank    = 9;
02440 const int eleventhRank = 10;
02441 
02442 const int firstDim    = 0;
02443 const int secondDim   = 1;
02444 const int thirdDim    = 2;
02445 const int fourthDim   = 3;
02446 const int fifthDim    = 4;
02447 const int sixthDim    = 5;
02448 const int seventhDim  = 6;
02449 const int eighthDim   = 7;
02450 const int ninthDim    = 8;
02451 const int tenthDim    = 9;
02452 const int eleventhDim = 10;
02453 
02454 /*
02455  * Global Functions
02456  */
02457 
02458 template<typename T_numtype>
02459 ostream& operator<<(ostream&, const Array<T_numtype,1>&);
02460 
02461 template<typename T_numtype>
02462 ostream& operator<<(ostream&, const Array<T_numtype,2>&);
02463 
02464 template<typename T_numtype, int N_rank>
02465 ostream& operator<<(ostream&, const Array<T_numtype,N_rank>&);
02466 
02467 template<typename T_numtype, int N_rank>
02468 istream& operator>>(istream& is, Array<T_numtype,N_rank>& x);
02469 
02470 template <typename P_numtype,int N_rank>
02471 void swap(Array<P_numtype,N_rank>& a,Array<P_numtype,N_rank>& b) {
02472     Array<P_numtype,N_rank> c(a);
02473     a.reference(b);
02474     b.reference(c);
02475 }
02476 
02477 template <typename P_expr>
02478 void find(Array<TinyVector<int,P_expr::rank>,1>& indices,
02479           const _bz_ArrayExpr<P_expr>& expr) {
02480     find(indices,
02481          static_cast< Array<typename P_expr::T_numtype,P_expr::rank> >(expr));
02482 }
02483 
02484 template <typename P_numtype, int N_rank>
02485 void find(Array<TinyVector<int,N_rank>,1>& indices,
02486           const Array<P_numtype,N_rank>& exprVals) {
02487     indices.resize(exprVals.size());
02488     typename Array<P_numtype,N_rank>::const_iterator it, end = exprVals.end();
02489     int j=0; 
02490     for (it = exprVals.begin(); it != end; ++it)
02491         if (*it) 
02492             indices(j++) = it.position();
02493     if (j) 
02494         indices.resizeAndPreserve(j);
02495     else 
02496         indices.free();
02497     return;
02498 }
02499 
02500 
02501 BZ_NAMESPACE_END
02502 
02503 /*
02504  * Include implementations of the member functions and some additional
02505  * global functions.
02506  */
02507 
02508 #include <blitz/array/iter.h>       // Array iterators
02509 #include <blitz/array/fastiter.h>   // Fast Array iterators (for et)
02510 #include <blitz/array/expr.h>       // Array expression objects
02511 #include <blitz/array/methods.cc>   // Member functions
02512 #include <blitz/array/eval.cc>      // Array expression evaluation
02513 #include <blitz/array/ops.cc>       // Assignment operators
02514 #include <blitz/array/io.cc>        // Output formatting
02515 #include <blitz/array/et.h>         // Expression templates
02516 #include <blitz/array/reduce.h>     // Array reduction expression templates
02517 #include <blitz/array/interlace.cc> // Allocation of interlaced arrays
02518 #include <blitz/array/resize.cc>    // Array resize, resizeAndPreserve
02519 #include <blitz/array/slicing.cc>   // Slicing and subarrays
02520 #include <blitz/array/cycle.cc>     // Cycling arrays
02521 #include <blitz/array/complex.cc>   // Special support for complex arrays
02522 #include <blitz/array/zip.h>        // Zipping multicomponent types
02523 #include <blitz/array/where.h>      // where(X,Y,Z)
02524 #include <blitz/array/indirect.h>   // Indirection
02525 #include <blitz/array/stencils.h>   // Stencil objects
02526 
02527 #endif // BZ_ARRAY_H

Generated on Wed Oct 17 17:57:14 2007 for blitz by  doxygen 1.5.2