blitz Version 0.9
|
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