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