source: Sophya/trunk/Poubelle/DPC:FitsIOServer/Blitz/blitz/array.h

Last change on this file was 658, checked in by ansari, 26 years ago

no message

File size: 90.2 KB
Line 
1/***************************************************************************
2 * blitz/array.h Declaration of the Array<P_numtype, N_rank> class
3 *
4 * $Id: array.h,v 1.1.1.1 1999-11-26 16:37:02 ansari Exp $
5 *
6 * Copyright (C) 1997,1998 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * Suggestions: blitz-suggest@cybervision.com
19 * Bugs: blitz-bugs@cybervision.com
20 *
21 * For more information, please see the Blitz++ Home Page:
22 * http://seurat.uwaterloo.ca/blitz/
23 *
24 ***************************************************************************
25 * $Log: not supported by cvs2svn $
26 * Revision 1.1.1.1 1999/04/09 17:59:01 ansari
27 * Creation module DPC/Blitz (blitz 0.4) Reza 09/04/99
28 *
29 * Revision 1.2 1998/03/14 00:04:47 tveldhui
30 * 0.2-alpha-05
31 *
32 * Revision 1.1 1997/07/16 14:51:20 tveldhui
33 * Update: Alpha release 0.2 (Arrays)
34 *
35 */
36
37/*
38 * Wish list for array classes.
39 * - Arrays whose dimensions are unknown at compile time.
40 * - where()/elsewhere()/elsewhere() as in Dan Quinlan's implementation
41 * - block reduction operations
42 * - conversion to/from matrix & vector
43 * - apply(T func(T))
44 * - apply(T func(const T&))
45 * - apply<T func(T)>
46 */
47
48#ifndef BZ_ARRAY_H
49#define BZ_ARRAY_H
50
51#ifndef BZ_BLITZ_H
52 #include <blitz/blitz.h>
53#endif
54
55#ifndef BZ_MEMBLOCK_H
56 #include <blitz/memblock.h>
57#endif
58
59#ifndef BZ_RANGE_H
60 #include <blitz/range.h>
61#endif
62
63#ifndef BZ_TINYVEC_H
64 #include <blitz/tinyvec.h>
65#endif
66
67#ifndef BZ_TRAVERSAL_H
68 #include <blitz/traversal.h>
69#endif
70
71#ifndef BZ_INDEXEXPR_H
72 #include <blitz/indexexpr.h>
73#endif
74
75#ifndef BZ_PRETTYPRINT_H
76 #include <blitz/prettyprint.h>
77#endif
78
79#include <blitz/array/slice.h> // Subarrays and slicing
80#include <blitz/array/map.h> // Tensor index notation
81#include <blitz/array/multi.h> // Multicomponent arrays
82#include <blitz/array/domain.h> // RectDomain class
83
84BZ_NAMESPACE(blitz)
85
86/*
87 * Forward declarations
88 */
89
90template<class T_numtype, int N_rank>
91class ArrayIterator;
92
93template<class P_expr>
94class _bz_ArrayExpr;
95
96#ifdef BZ_NEW_EXPRESSION_TEMPLATES
97template<class T>
98class ETBase { };
99#endif
100
101template<class T_array, class T_index>
102class IndirectArray;
103
104/*
105 * Declaration of class GeneralStorage<N_rank>
106 *
107 * This class describes a storage format for an N-dimensional array.
108 * The dimensions can be stored in an arbitrary order (for example, as
109 * a C-style row major array or Fortran-style column major array, or
110 * something else entirely). Each dimension can be stored in either
111 * ascending (the most common) or descending order. Each dimension
112 * can have its own base (starting index value: e.g. 0 for C-style arrays,
113 * 1 for Fortran arrays).
114 *
115 * GeneralArrayStorage<N> defaults to C-style arrays. To implement
116 * other storage formats, subclass and modify the constructor. The
117 * class FortranArray, below, is an example.
118 *
119 * Objects inheriting from GeneralArrayStorage<N> can be passed as
120 * an optional constructor argument to Array objects.
121 * e.g. Array<int,3> A(16,16,16, FortranArray<3>());
122 * will create a 3-dimensional 16x16x16 Fortran-style array.
123 */
124
125template<int N_rank>
126class GeneralArrayStorage {
127public:
128 class noInitializeFlag { };
129
130 GeneralArrayStorage(noInitializeFlag)
131 { }
132
133 GeneralArrayStorage()
134 {
135 ordering_ = Range(N_rank - 1, 0, -1);
136 ascendingFlag_ = 1;
137 base_ = 0;
138 }
139
140 GeneralArrayStorage(const GeneralArrayStorage<N_rank>& x)
141 : ordering_(x.ordering_), ascendingFlag_(x.ascendingFlag_),
142 base_(x.base_)
143 {
144 }
145
146 ~GeneralArrayStorage()
147 { }
148
149 TinyVector<int, N_rank>& ordering()
150 { return ordering_; }
151
152 const TinyVector<int, N_rank>& ordering() const
153 { return ordering_; }
154
155 int ordering(int i) const
156 { return ordering_[i]; }
157
158 void setOrdering(int i, int order)
159 { ordering_[i] = order; }
160
161 _bz_bool allRanksStoredAscending() const
162 {
163 _bz_bool result = _bz_true;
164 for (int i=0; i < N_rank; ++i)
165 result &= ascendingFlag_[i];
166 return result;
167 }
168
169 _bz_bool isRankStoredAscending(int i) const
170 { return ascendingFlag_[i]; }
171
172 TinyVector<bool, N_rank>& ascendingFlag()
173 { return ascendingFlag_; }
174
175 const TinyVector<bool, N_rank>& ascendingFlag() const
176 { return ascendingFlag_; }
177
178 void setAscendingFlag(int i, int ascendingFlag)
179 { ascendingFlag_[i] = ascendingFlag; }
180
181 TinyVector<int, N_rank>& base()
182 { return base_; }
183
184 const TinyVector<int, N_rank>& base() const
185 { return base_; }
186
187 int base(int i) const
188 { return base_[i]; }
189
190 void setBase(int i, int base)
191 { base_[i] = base; }
192
193 void setBase(const TinyVector<int, N_rank>& base)
194 { base_ = base; }
195
196protected:
197 /*
198 * ordering_[] specifies the order in which the array is stored in
199 * memory. For a newly allocated array, ordering_(0) will give the
200 * rank with unit stride, and ordering_(N_rank-1) will be the rank
201 * with largest stride. An order like [2, 1, 0] corresponds to
202 * C-style array storage; an order like [0, 1, 2] corresponds to
203 * Fortran array storage.
204 *
205 * ascendingFlag_[] indicates whether the data in a rank is stored
206 * in ascending or descending order. Most of the time these values
207 * will all be true (indicating ascending order). Some peculiar
208 * formats (e.g. MS-Windows BMP image format) store the data in
209 * descending order.
210 *
211 * base_[] gives the first valid index for each rank. For a C-style
212 * array, all the base_ elements will be zero; for a Fortran-style
213 * array, they will be one. base_[] can be set arbitrarily using
214 * the Array constructor which takes a Range argument, e.g.
215 * Array<float,2> A(Range(30,40),Range(23,33));
216 * will create an array with base_[] = { 30, 23 }.
217 */
218 TinyVector<int, N_rank> ordering_;
219 TinyVector<bool, N_rank> ascendingFlag_;
220 TinyVector<int, N_rank> base_;
221};
222
223/*
224 * Class FortranArray specializes GeneralArrayStorage to provide Fortran
225 * style arrays (column major ordering, base of 1). The noInitializeFlag()
226 * passed to the base constructor indicates that the subclass will take
227 * care of initializing the ordering_, ascendingFlag_ and base_ members.
228 */
229
230template<int N_rank>
231class FortranArray : public GeneralArrayStorage<N_rank> {
232public:
233 FortranArray()
234 : GeneralArrayStorage<N_rank>(noInitializeFlag())
235 {
236 ordering_ = Range(0, N_rank - 1);
237 ascendingFlag_ = 1;
238 base_ = 1;
239 }
240};
241
242/*
243 * Class ColumnMajorArray specializes GeneralArrayStorage to provide column
244 * major arrays (column major ordering, base of 0).
245 */
246
247template<int N_rank>
248class ColumnMajorArray : public GeneralArrayStorage<N_rank> {
249public:
250 ColumnMajorArray()
251 : GeneralArrayStorage<N_rank>(noInitializeFlag())
252 {
253 ordering_ = Range(0, N_rank - 1);
254 ascendingFlag_ = 1;
255 base_ = 0;
256 }
257};
258
259/*
260 * Declaration of class Array
261 */
262
263// NEEDS_WORK: Array should inherit protected from MemoryBlockReference.
264// To make this work, need to expose MemoryBlockReference::numReferences()
265// and make Array<P,N2> a friend of Array<P,N> for slicing.
266
267template<class P_numtype, int N_rank>
268class Array : public MemoryBlockReference<P_numtype>
269#ifdef BZ_NEW_EXPRESSION_TEMPLATES
270 , public ETBase<Array<P_numtype,N_rank> >
271#endif
272{
273
274public:
275 //////////////////////////////////////////////
276 // Public Types
277 //////////////////////////////////////////////
278
279 /*
280 * T_numtype is the numeric type stored in the array.
281 * T_index is a vector type which can be used to access elements
282 * of many-dimensional arrays.
283 * T_array is the array type itself -- Array<T_numtype, N_rank>
284 * T_iterator is an iterator for the array.
285 */
286
287 typedef P_numtype T_numtype;
288 typedef TinyVector<int, N_rank> T_index;
289 typedef Array<T_numtype, N_rank> T_array;
290 typedef ArrayIterator<T_numtype, N_rank> T_iterator;
291
292 enum { _bz_rank = N_rank };
293
294 //////////////////////////////////////////////
295 // Constructors //
296 //////////////////////////////////////////////
297
298
299 /*
300 * Construct an array from an array expression.
301 */
302
303 template<class T_expr>
304 Array(_bz_ArrayExpr<T_expr> expr);
305
306 /*
307 * Any missing length arguments will have their value taken from the
308 * last argument. For example,
309 * Array<int,3> A(32,64);
310 * will create a 32x64x64 array. This is handled by setupStorage().
311 */
312
313 Array(GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
314 : storage_(storage)
315 {
316 length_ = 0;
317 stride_ = 0;
318 zeroOffset_ = 0;
319 storageContiguous_ = false;
320 }
321
322 _bz_explicit Array(int length0,
323 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
324 : storage_(storage)
325 {
326 length_[0] = length0;
327 setupStorage(0);
328 }
329
330 Array(int length0, int length1,
331 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
332 : storage_(storage)
333 {
334 BZPRECONDITION(N_rank >= 2);
335 TAU_TYPE_STRING(p1, "Array<T,N>::Array() [T="
336 + CT(T_numtype) + ",N=" + CT(N_rank) + "]");
337 TAU_PROFILE(p1, "void (int,int)", TAU_BLITZ);
338
339 length_[0] = length0;
340 length_[1] = length1;
341 setupStorage(1);
342 }
343
344 Array(int length0, int length1, int length2,
345 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
346 : storage_(storage)
347 {
348 BZPRECONDITION(N_rank >= 3);
349 length_[0] = length0;
350 length_[1] = length1;
351 length_[2] = length2;
352 setupStorage(2);
353 }
354
355 Array(int length0, int length1, int length2, int length3,
356 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
357 : storage_(storage)
358 {
359 BZPRECONDITION(N_rank >= 4);
360 length_[0] = length0;
361 length_[1] = length1;
362 length_[2] = length2;
363 length_[3] = length3;
364 setupStorage(3);
365 }
366
367 Array(int length0, int length1, int length2, int length3, int length4,
368 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
369 : storage_(storage)
370 {
371 BZPRECONDITION(N_rank >= 5);
372 length_[0] = length0;
373 length_[1] = length1;
374 length_[2] = length2;
375 length_[3] = length3;
376 length_[4] = length4;
377 setupStorage(4);
378 }
379
380 Array(int length0, int length1, int length2, int length3, int length4,
381 int length5,
382 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
383 : storage_(storage)
384 {
385 BZPRECONDITION(N_rank >= 6);
386 length_[0] = length0;
387 length_[1] = length1;
388 length_[2] = length2;
389 length_[3] = length3;
390 length_[4] = length4;
391 length_[5] = length5;
392 setupStorage(5);
393 }
394
395 Array(int length0, int length1, int length2, int length3, int length4,
396 int length5, int length6,
397 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
398 : storage_(storage)
399 {
400 BZPRECONDITION(N_rank >= 7);
401 length_[0] = length0;
402 length_[1] = length1;
403 length_[2] = length2;
404 length_[3] = length3;
405 length_[4] = length4;
406 length_[5] = length5;
407 length_[6] = length6;
408 setupStorage(6);
409 }
410
411 Array(int length0, int length1, int length2, int length3, int length4,
412 int length5, int length6, int length7,
413 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
414 : storage_(storage)
415 {
416 BZPRECONDITION(N_rank >= 8);
417 length_[0] = length0;
418 length_[1] = length1;
419 length_[2] = length2;
420 length_[3] = length3;
421 length_[4] = length4;
422 length_[5] = length5;
423 length_[6] = length6;
424 length_[7] = length7;
425 setupStorage(7);
426 }
427
428 Array(int length0, int length1, int length2, int length3, int length4,
429 int length5, int length6, int length7, int length8,
430 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
431 : storage_(storage)
432 {
433 BZPRECONDITION(N_rank >= 9);
434 length_[0] = length0;
435 length_[1] = length1;
436 length_[2] = length2;
437 length_[3] = length3;
438 length_[4] = length4;
439 length_[5] = length5;
440 length_[6] = length6;
441 length_[7] = length7;
442 length_[8] = length8;
443 setupStorage(8);
444 }
445
446 Array(int length0, int length1, int length2, int length3, int length4,
447 int length5, int length6, int length7, int length8, int length9,
448 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
449 : storage_(storage)
450 {
451 BZPRECONDITION(N_rank >= 10);
452 length_[0] = length0;
453 length_[1] = length1;
454 length_[2] = length2;
455 length_[3] = length3;
456 length_[4] = length4;
457 length_[5] = length5;
458 length_[6] = length6;
459 length_[7] = length7;
460 length_[8] = length8;
461 length_[9] = length9;
462 setupStorage(9);
463 }
464
465 Array(int length0, int length1, int length2, int length3, int length4,
466 int length5, int length6, int length7, int length8, int length9,
467 int length10,
468 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
469 : storage_(storage)
470 {
471 BZPRECONDITION(N_rank >= 11);
472 length_[0] = length0;
473 length_[1] = length1;
474 length_[2] = length2;
475 length_[3] = length3;
476 length_[4] = length4;
477 length_[5] = length5;
478 length_[6] = length6;
479 length_[7] = length7;
480 length_[8] = length8;
481 length_[9] = length9;
482 length_[10] = length10;
483 setupStorage(10);
484 }
485
486 /*
487 * Construct an array from an existing block of memory. Ownership
488 * is not acquired (i.e. the memory block will not be freed by Blitz++).
489 */
490 Array(T_numtype* _bz_restrict dataFirst, TinyVector<int, N_rank> shape,
491 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
492 : MemoryBlockReference<T_numtype>(product(shape), dataFirst),
493 storage_(storage)
494 {
495 BZPRECONDITION(dataFirst != 0);
496
497 length_ = shape;
498 computeStrides();
499 data_ += zeroOffset_;
500 storageContiguous_ = _bz_true;
501 }
502
503 /*
504 * Construct an array from an existing block of memory, with a
505 * given set of strides. Ownership is not acquired (i.e. the memory
506 * block will not be freed by Blitz++).
507 */
508 Array(T_numtype* _bz_restrict dataFirst, TinyVector<int, N_rank> shape,
509 TinyVector<int, N_rank> stride,
510 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
511 : MemoryBlockReference<T_numtype>(product(shape), dataFirst),
512 storage_(storage)
513 {
514 BZPRECONDITION(dataFirst != 0);
515
516 length_ = shape;
517 stride_ = stride;
518 calculateZeroOffset();
519 data_ += zeroOffset_;
520
521 // NEEDS_WORK: the setting of storageContiguous should be determined
522 // by inspecting the strides.
523 storageContiguous_ = _bz_false;
524 }
525
526 /*
527 * This constructor takes an extent (length) vector and storage format.
528 */
529
530 Array(const TinyVector<int, N_rank>& extent,
531 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
532 : storage_(storage)
533 {
534 length_ = extent;
535 setupStorage(N_rank - 1);
536 }
537
538 /*
539 * This construct takes a vector of bases (lbounds) and a vector of
540 * extents.
541 */
542
543 Array(const TinyVector<int, N_rank>& lbounds,
544 const TinyVector<int, N_rank>& extent,
545 const GeneralArrayStorage<N_rank>& storage);
546
547 /*
548 * These constructors allow arbitrary bases (starting indices) to be set.
549 * e.g. Array<int,2> A(Range(10,20), Range(20,30))
550 * will create an 11x11 array whose indices are 10..20 and 20..30
551 */
552 Array(Range r0,
553 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
554 : storage_(storage)
555 {
556 BZPRECONDITION(r0.isAscendingContiguous());
557
558 length_[0] = r0.length();
559 storage_.setBase(0, r0.first());
560 setupStorage(0);
561 }
562
563 Array(Range r0, Range r1,
564 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
565 : storage_(storage)
566 {
567 BZPRECONDITION(r0.isAscendingContiguous() &&
568 r1.isAscendingContiguous());
569
570 length_[0] = r0.length();
571 storage_.setBase(0, r0.first());
572 length_[1] = r1.length();
573 storage_.setBase(1, r1.first());
574
575 setupStorage(1);
576 }
577
578 Array(Range r0, Range r1, Range r2,
579 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
580 : storage_(storage)
581 {
582 BZPRECONDITION(r0.isAscendingContiguous() &&
583 r1.isAscendingContiguous() && r2.isAscendingContiguous());
584
585 length_[0] = r0.length();
586 storage_.setBase(0, r0.first());
587 length_[1] = r1.length();
588 storage_.setBase(1, r1.first());
589 length_[2] = r2.length();
590 storage_.setBase(2, r2.first());
591
592 setupStorage(2);
593 }
594
595 Array(Range r0, Range r1, Range r2, Range r3,
596 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
597 : storage_(storage)
598 {
599 BZPRECONDITION(r0.isAscendingContiguous() &&
600 r1.isAscendingContiguous() && r2.isAscendingContiguous()
601 && r3.isAscendingContiguous());
602
603 length_[0] = r0.length();
604 storage_.setBase(0, r0.first());
605 length_[1] = r1.length();
606 storage_.setBase(1, r1.first());
607 length_[2] = r2.length();
608 storage_.setBase(2, r2.first());
609 length_[3] = r3.length();
610 storage_.setBase(3, r3.first());
611
612 setupStorage(3);
613 }
614
615 Array(Range r0, Range r1, Range r2, Range r3, Range r4,
616 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
617 : storage_(storage)
618 {
619 BZPRECONDITION(r0.isAscendingContiguous() &&
620 r1.isAscendingContiguous() && r2.isAscendingContiguous()
621 && r3.isAscendingContiguous() && r4.isAscendingContiguous());
622
623 length_[0] = r0.length();
624 storage_.setBase(0, r0.first());
625 length_[1] = r1.length();
626 storage_.setBase(1, r1.first());
627 length_[2] = r2.length();
628 storage_.setBase(2, r2.first());
629 length_[3] = r3.length();
630 storage_.setBase(3, r3.first());
631 length_[4] = r4.length();
632 storage_.setBase(4, r4.first());
633
634 setupStorage(4);
635 }
636
637 Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
638 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
639 : storage_(storage)
640 {
641 BZPRECONDITION(r0.isAscendingContiguous() &&
642 r1.isAscendingContiguous() && r2.isAscendingContiguous()
643 && r3.isAscendingContiguous() && r4.isAscendingContiguous()
644 && r5.isAscendingContiguous());
645
646 length_[0] = r0.length();
647 storage_.setBase(0, r0.first());
648 length_[1] = r1.length();
649 storage_.setBase(1, r1.first());
650 length_[2] = r2.length();
651 storage_.setBase(2, r2.first());
652 length_[3] = r3.length();
653 storage_.setBase(3, r3.first());
654 length_[4] = r4.length();
655 storage_.setBase(4, r4.first());
656 length_[5] = r5.length();
657 storage_.setBase(5, r5.first());
658
659 setupStorage(5);
660 }
661
662 Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
663 Range r6,
664 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
665 : storage_(storage)
666 {
667 BZPRECONDITION(r0.isAscendingContiguous() &&
668 r1.isAscendingContiguous() && r2.isAscendingContiguous()
669 && r3.isAscendingContiguous() && r4.isAscendingContiguous()
670 && r5.isAscendingContiguous() && r6.isAscendingContiguous());
671
672 length_[0] = r0.length();
673 storage_.setBase(0, r0.first());
674 length_[1] = r1.length();
675 storage_.setBase(1, r1.first());
676 length_[2] = r2.length();
677 storage_.setBase(2, r2.first());
678 length_[3] = r3.length();
679 storage_.setBase(3, r3.first());
680 length_[4] = r4.length();
681 storage_.setBase(4, r4.first());
682 length_[5] = r5.length();
683 storage_.setBase(5, r5.first());
684 length_[6] = r6.length();
685 storage_.setBase(6, r6.first());
686
687 setupStorage(6);
688 }
689
690 Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
691 Range r6, Range r7,
692 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
693 : storage_(storage)
694 {
695 BZPRECONDITION(r0.isAscendingContiguous() &&
696 r1.isAscendingContiguous() && r2.isAscendingContiguous()
697 && r3.isAscendingContiguous() && r4.isAscendingContiguous()
698 && r5.isAscendingContiguous() && r6.isAscendingContiguous()
699 && r7.isAscendingContiguous());
700
701 length_[0] = r0.length();
702 storage_.setBase(0, r0.first());
703 length_[1] = r1.length();
704 storage_.setBase(1, r1.first());
705 length_[2] = r2.length();
706 storage_.setBase(2, r2.first());
707 length_[3] = r3.length();
708 storage_.setBase(3, r3.first());
709 length_[4] = r4.length();
710 storage_.setBase(4, r4.first());
711 length_[5] = r5.length();
712 storage_.setBase(5, r5.first());
713 length_[6] = r6.length();
714 storage_.setBase(6, r6.first());
715 length_[7] = r7.length();
716 storage_.setBase(7, r7.first());
717
718 setupStorage(7);
719 }
720
721 Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
722 Range r6, Range r7, Range r8,
723 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
724 : storage_(storage)
725 {
726 BZPRECONDITION(r0.isAscendingContiguous() &&
727 r1.isAscendingContiguous() && r2.isAscendingContiguous()
728 && r3.isAscendingContiguous() && r4.isAscendingContiguous()
729 && r5.isAscendingContiguous() && r6.isAscendingContiguous()
730 && r7.isAscendingContiguous() && r8.isAscendingContiguous());
731
732 length_[0] = r0.length();
733 storage_.setBase(0, r0.first());
734 length_[1] = r1.length();
735 storage_.setBase(1, r1.first());
736 length_[2] = r2.length();
737 storage_.setBase(2, r2.first());
738 length_[3] = r3.length();
739 storage_.setBase(3, r3.first());
740 length_[4] = r4.length();
741 storage_.setBase(4, r4.first());
742 length_[5] = r5.length();
743 storage_.setBase(5, r5.first());
744 length_[6] = r6.length();
745 storage_.setBase(6, r6.first());
746 length_[7] = r7.length();
747 storage_.setBase(7, r7.first());
748 length_[8] = r8.length();
749 storage_.setBase(8, r8.first());
750
751 setupStorage(8);
752 }
753
754 Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
755 Range r6, Range r7, Range r8, Range r9,
756 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
757 : storage_(storage)
758 {
759 BZPRECONDITION(r0.isAscendingContiguous() &&
760 r1.isAscendingContiguous() && r2.isAscendingContiguous()
761 && r3.isAscendingContiguous() && r4.isAscendingContiguous()
762 && r5.isAscendingContiguous() && r6.isAscendingContiguous()
763 && r7.isAscendingContiguous() && r8.isAscendingContiguous()
764 && r9.isAscendingContiguous());
765
766 length_[0] = r0.length();
767 storage_.setBase(0, r0.first());
768 length_[1] = r1.length();
769 storage_.setBase(1, r1.first());
770 length_[2] = r2.length();
771 storage_.setBase(2, r2.first());
772 length_[3] = r3.length();
773 storage_.setBase(3, r3.first());
774 length_[4] = r4.length();
775 storage_.setBase(4, r4.first());
776 length_[5] = r5.length();
777 storage_.setBase(5, r5.first());
778 length_[6] = r6.length();
779 storage_.setBase(6, r6.first());
780 length_[7] = r7.length();
781 storage_.setBase(7, r7.first());
782 length_[8] = r8.length();
783 storage_.setBase(8, r8.first());
784 length_[9] = r9.length();
785 storage_.setBase(9, r9.first());
786
787 setupStorage(9);
788 }
789
790 Array(Range r0, Range r1, Range r2, Range r3, Range r4, Range r5,
791 Range r6, Range r7, Range r8, Range r9, Range r10,
792 GeneralArrayStorage<N_rank> storage = GeneralArrayStorage<N_rank>())
793 : storage_(storage)
794 {
795 BZPRECONDITION(r0.isAscendingContiguous() &&
796 r1.isAscendingContiguous() && r2.isAscendingContiguous()
797 && r3.isAscendingContiguous() && r4.isAscendingContiguous()
798 && r5.isAscendingContiguous() && r6.isAscendingContiguous()
799 && r7.isAscendingContiguous() && r8.isAscendingContiguous()
800 && r9.isAscendingContiguous() && r10.isAscendingContiguous());
801
802 length_[0] = r0.length();
803 storage_.setBase(0, r0.first());
804 length_[1] = r1.length();
805 storage_.setBase(1, r1.first());
806 length_[2] = r2.length();
807 storage_.setBase(2, r2.first());
808 length_[3] = r3.length();
809 storage_.setBase(3, r3.first());
810 length_[4] = r4.length();
811 storage_.setBase(4, r4.first());
812 length_[5] = r5.length();
813 storage_.setBase(5, r5.first());
814 length_[6] = r6.length();
815 storage_.setBase(6, r6.first());
816 length_[7] = r7.length();
817 storage_.setBase(7, r7.first());
818 length_[8] = r8.length();
819 storage_.setBase(8, r8.first());
820 length_[9] = r9.length();
821 storage_.setBase(9, r9.first());
822 length_[10] = r10.length();
823 storage_.setBase(10, r10.first());
824
825 setupStorage(10);
826 }
827
828 /*
829 * Create a reference of another array
830 */
831 Array(const Array<T_numtype, N_rank>& array)
832 {
833 // NEEDS_WORK: this const_cast is a tad ugly.
834 reference(const_cast<T_array&>(array));
835 }
836
837 /*
838 * These constructors are used for creating interlaced arrays (see
839 * <blitz/arrayshape.h>
840 */
841 Array(const TinyVector<int,N_rank-1>& shape,
842 int lastExtent, const GeneralArrayStorage<N_rank>& storage);
843 //Array(const TinyVector<Range,N_rank-1>& shape,
844 // int lastExtent, const GeneralArrayStorage<N_rank>& storage);
845
846 /*
847 * These constructors make the array a view of a subportion of another
848 * array. If there fewer than N_rank Range arguments provided, no
849 * slicing is performed in the unspecified ranks.
850 * e.g. Array<int,3> A(20,20,20);
851 * Array<int,3> B(A, Range(5,15));
852 * is equivalent to:
853 * Array<int,3> B(A, Range(5,15), Range::all(), Range::all());
854 */
855 Array(Array<T_numtype, N_rank>& array, Range r0)
856 {
857 constructSubarray(array, r0);
858 }
859
860 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1)
861 {
862 constructSubarray(array, r0, r1);
863 }
864
865 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2)
866 {
867 constructSubarray(array, r0, r1, r2);
868 }
869
870 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
871 Range r3)
872 {
873 constructSubarray(array, r0, r1, r2, r3);
874 }
875
876 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
877 Range r3, Range r4)
878 {
879 constructSubarray(array, r0, r1, r2, r3, r4);
880 }
881
882 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
883 Range r3, Range r4, Range r5)
884 {
885 constructSubarray(array, r0, r1, r2, r3, r4, r5);
886 }
887
888 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
889 Range r3, Range r4, Range r5, Range r6)
890 {
891 constructSubarray(array, r0, r1, r2, r3, r4, r5, r6);
892 }
893
894 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
895 Range r3, Range r4, Range r5, Range r6, Range r7)
896 {
897 constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7);
898 }
899
900 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
901 Range r3, Range r4, Range r5, Range r6, Range r7, Range r8)
902 {
903 constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8);
904 }
905
906 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
907 Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9)
908 {
909 constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9);
910 }
911
912 Array(Array<T_numtype, N_rank>& array, Range r0, Range r1, Range r2,
913 Range r3, Range r4, Range r5, Range r6, Range r7, Range r8, Range r9,
914 Range r10)
915 {
916 constructSubarray(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10);
917 }
918
919 Array(Array<T_numtype, N_rank>& array,
920 const RectDomain<N_rank>& subdomain)
921 {
922 constructSubarray(array, subdomain);
923 }
924
925 /*
926 * This constructor is invoked by the operator()'s which take
927 * a combination of integer and Range arguments. It's not intended
928 * for end-user use.
929 */
930 template<int N_rank2, class R0, class R1, class R2, class R3, class R4,
931 class R5, class R6, class R7, class R8, class R9, class R10>
932 Array(Array<T_numtype,N_rank2>& array, R0 r0, R1 r1, R2 r2,
933 R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10)
934 {
935 constructSlice(array, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10);
936 }
937
938 //////////////////////////////////////////////
939 // Member functions
940 //////////////////////////////////////////////
941
942 const TinyVector<int, N_rank>& base() const
943 { return storage_.base(); }
944
945 int base(int rank) const
946 { return storage_.base(rank); }
947
948 T_iterator begin() const
949 { return T_iterator(*this); }
950
951 // Deprecated: now extractComponent(...)
952 template<class T_numtype2>
953 Array<T_numtype2,N_rank> chopComponent(T_numtype2 a, int compNum,
954 int numComponents)
955 { return extractComponent(a, compNum, numComponents); }
956
957 int cols() const
958 { return length_[1]; }
959
960 int columns() const
961 { return length_[1]; }
962
963 T_array copy() const;
964
965 // data_ always refers to the point (0,0,...,0) which may
966 // not be in the array if the base is not zero in each rank.
967 // These data() routines return a pointer to the first
968 // element in the array (but note that it may not be
969 // stored first in memory if some ranks are stored descending).
970
971 const T_numtype* _bz_restrict data() const
972 { return data_ + dot(storage_.base(), stride_); }
973
974 T_numtype* _bz_restrict data()
975 { return data_ + dot(storage_.base(), stride_); }
976
977 // These dataZero() routines refer to the point (0,0,...,0)
978 // which may not be in the array if the bases are nonzero.
979
980 const T_numtype* _bz_restrict dataZero() const
981 { return data_; }
982
983 T_numtype* _bz_restrict dataZero()
984 { return data_; }
985
986 // These dataFirst() routines refer to the element in the
987 // array which falls first in memory.
988
989 const T_numtype* _bz_restrict dataFirst() const
990 {
991 return data_ + dot(storage_.base()
992 + (1 - storage_.ascendingFlag()) * (length_ - 1), stride_);
993 }
994
995 T_numtype* _bz_restrict dataFirst()
996 {
997 return data_ + dot(storage_.base()
998 + (1 - storage_.ascendingFlag()) * (length_ - 1), stride_);
999 }
1000
1001 int depth() const
1002 { return length_[2]; }
1003
1004 int dimensions() const
1005 { return N_rank; }
1006
1007 RectDomain<N_rank> domain() const
1008 {
1009 return RectDomain<N_rank>(lbound(), ubound());
1010 }
1011
1012 void dumpStructureInformation(ostream& os = cout) const;
1013
1014 // NEEDS_WORK -- end()
1015
1016 int extent(int rank) const
1017 { return length_[rank]; }
1018
1019 const TinyVector<int,N_rank>& extent() const
1020 { return length_; }
1021
1022 template<class T_numtype2>
1023 Array<T_numtype2,N_rank> extractComponent(T_numtype2, int compNum,
1024 int numComponents);
1025
1026 void free()
1027 {
1028 changeToNullBlock();
1029 length_ = 0;
1030 }
1031
1032 _bz_bool isMajorRank(int rank) const
1033 { return storage_.ordering(rank) == 0; }
1034
1035 _bz_bool isMinorRank(int rank) const
1036 { return storage_.ordering(rank) != 0; }
1037
1038 _bz_bool isRankStoredAscending(int rank) const
1039 { return storage_.isRankStoredAscending(rank); }
1040
1041 _bz_bool isStorageContiguous() const
1042 { return storageContiguous_; }
1043
1044 int lbound(int rank) const
1045 { return base(rank); }
1046
1047 TinyVector<int,N_rank> lbound() const
1048 {
1049 return base();
1050 }
1051
1052 int length(int rank) const
1053 { return length_[rank]; }
1054
1055 const TinyVector<int, N_rank>& length() const
1056 { return length_; }
1057
1058 void makeUnique();
1059
1060 int numElements() const
1061 { return product(length_); }
1062
1063 // NEEDS_WORK -- Expose the numReferences() method
1064 // MemoryBlockReference<T_numtype>::numReferences;
1065
1066 // The storage_.ordering_ array is a list of dimensions from
1067 // the most minor (stride 1) to major dimension. Generally,
1068 // ordering(0) will return the dimension which has the smallest
1069 // stride, and ordering(N_rank-1) will return the dimension with
1070 // the largest stride.
1071 int ordering(int storageRankIndex) const
1072 { return storage_.ordering(storageRankIndex); }
1073
1074 const TinyVector<int, N_rank>& ordering() const
1075 { return storage_.ordering(); }
1076
1077 void transposeSelf(int r0, int r1, int r2=0,
1078 int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int
1079 r9=0, int r10=0);
1080 T_array transpose(int r0, int r1, int r2=0,
1081 int r3=0, int r4=0, int r5=0, int r6=0, int r7=0, int r8=0, int
1082 r9=0, int r10=0);
1083
1084 int rank() const
1085 { return N_rank; }
1086
1087 void reference(T_array&);
1088
1089 void resize(int extent);
1090 void resize(int extent1, int extent2);
1091 void resize(int extent1, int extent2,
1092 int extent3);
1093 void resize(int extent1, int extent2,
1094 int extent3, int extent4);
1095 void resize(int extent1, int extent2,
1096 int extent3, int extent4, int extent5);
1097 void resize(int extent1, int extent2,
1098 int extent3, int extent4, int extent5,
1099 int extent6);
1100 void resize(int extent1, int extent2,
1101 int extent3, int extent4, int extent5,
1102 int extent6, int extent7);
1103 void resize(int extent1, int extent2,
1104 int extent3, int extent4, int extent5,
1105 int extent6, int extent7, int extent8);
1106 void resize(int extent1, int extent2,
1107 int extent3, int extent4, int extent5,
1108 int extent6, int extent7, int extent8,
1109 int extent9);
1110 void resize(int extent1, int extent2,
1111 int extent3, int extent4, int extent5,
1112 int extent6, int extent7, int extent8,
1113 int extent9, int extent10);
1114 void resize(int extent1, int extent2,
1115 int extent3, int extent4, int extent5,
1116 int extent6, int extent7, int extent8,
1117 int extent9, int extent10,
1118 int extent11);
1119
1120
1121 void resize(Range r1);
1122 void resize(Range r1, Range r2);
1123 void resize(Range r1, Range r2, Range r3);
1124 void resize(Range r1, Range r2, Range r3,
1125 Range r4);
1126 void resize(Range r1, Range r2, Range r3,
1127 Range r4, Range r5);
1128 void resize(Range r1, Range r2, Range r3,
1129 Range r4, Range r5, Range r6);
1130 void resize(Range r1, Range r2, Range r3,
1131 Range r4, Range r5, Range r6,
1132 Range r7);
1133 void resize(Range r1, Range r2, Range r3,
1134 Range r4, Range r5, Range r6,
1135 Range r7, Range r8);
1136 void resize(Range r1, Range r2, Range r3,
1137 Range r4, Range r5, Range r6,
1138 Range r7, Range r8, Range r9);
1139 void resize(Range r1, Range r2, Range r3,
1140 Range r4, Range r5, Range r6,
1141 Range r7, Range r8, Range r9,
1142 Range r10);
1143 void resize(Range r1, Range r2, Range r3,
1144 Range r4, Range r5, Range r6,
1145 Range r7, Range r8, Range r9,
1146 Range r10, Range r11);
1147
1148 void resize(const TinyVector<int,N_rank>&);
1149
1150
1151 void resizeAndPreserve(int extent);
1152 void resizeAndPreserve(int extent1,
1153 int extent2);
1154 void resizeAndPreserve(int extent1,
1155 int extent2, int extent3);
1156 void resizeAndPreserve(int extent1,
1157 int extent2, int extent3, int extent4);
1158 void resizeAndPreserve(int extent1,
1159 int extent2, int extent3, int extent4,
1160 int extent5);
1161 void resizeAndPreserve(int extent1,
1162 int extent2, int extent3, int extent4,
1163 int extent5, int extent6);
1164 void resizeAndPreserve(int extent1,
1165 int extent2, int extent3, int extent4,
1166 int extent5, int extent6, int extent7);
1167 void resizeAndPreserve(int extent1,
1168 int extent2, int extent3, int extent4,
1169 int extent5, int extent6, int extent7,
1170 int extent8);
1171 void resizeAndPreserve(int extent1,
1172 int extent2, int extent3, int extent4,
1173 int extent5, int extent6, int extent7,
1174 int extent8, int extent9);
1175 void resizeAndPreserve(int extent1,
1176 int extent2, int extent3, int extent4,
1177 int extent5, int extent6, int extent7,
1178 int extent8, int extent9,
1179 int extent10);
1180 void resizeAndPreserve(int extent1,
1181 int extent2, int extent3, int extent4,
1182 int extent5, int extent6, int extent7,
1183 int extent8, int extent9, int extent10,
1184 int extent11);
1185
1186 // NEEDS_WORK -- resizeAndPreserve(Range,...)
1187 // NEEDS_WORK -- resizeAndPreserve(const TinyVector<int,N_rank>&);
1188 // NEEDS_WORK -- resizeAndPreserve(const Domain<N_rank>&);
1189
1190 T_array reverse(int rank);
1191 void reverseSelf(int rank);
1192
1193 int rows() const
1194 { return length_[0]; }
1195
1196 void slice(int rank, Range r);
1197
1198 const TinyVector<int, N_rank>& shape() const
1199 { return length_; }
1200
1201 int size() const
1202 { return numElements(); }
1203
1204 const TinyVector<int, N_rank>& stride() const
1205 { return stride_; }
1206
1207 int stride(int rank) const
1208 { return stride_[rank]; }
1209
1210 int ubound(int rank) const
1211 { return base(rank) + length_(rank) - 1; }
1212
1213 TinyVector<int, N_rank> ubound() const
1214 {
1215 TinyVector<int, N_rank> ub;
1216 ub = base() + extent() - 1;
1217 return ub;
1218 }
1219
1220 int zeroOffset() const
1221 { return zeroOffset_; }
1222
1223 //////////////////////////////////////////////
1224 // Debugging routines
1225 //////////////////////////////////////////////
1226
1227 _bz_bool isInRange(int i0) const
1228 {
1229 return unsigned(i0 - base(0)) < length_[0];
1230 }
1231
1232 _bz_bool isInRange(int i0, int i1) const
1233 {
1234 return unsigned(i0 - base(0)) < length_[0]
1235 && unsigned(i1 - base(1)) < length_[1];
1236 }
1237
1238 _bz_bool isInRange(int i0, int i1, int i2) const
1239 {
1240 return unsigned(i0 - base(0)) < length_[0]
1241 && unsigned(i1 - base(1)) < length_[1]
1242 && unsigned(i2 - base(2)) < length_[2];
1243 }
1244
1245 _bz_bool isInRange(int i0, int i1, int i2, int i3) const
1246 {
1247 return unsigned(i0 - base(0)) < length_[0]
1248 && unsigned(i1 - base(1)) < length_[1]
1249 && unsigned(i2 - base(2)) < length_[2]
1250 && unsigned(i3 - base(3)) < length_[3];
1251 }
1252
1253 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4) const
1254 {
1255 return unsigned(i0 - base(0)) < length_[0]
1256 && unsigned(i1 - base(1)) < length_[1]
1257 && unsigned(i2 - base(2)) < length_[2]
1258 && unsigned(i3 - base(3)) < length_[3]
1259 && unsigned(i4 - base(4)) < length_[4];
1260 }
1261
1262 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4,
1263 int i5) const
1264 {
1265 return unsigned(i0 - base(0)) < length_[0]
1266 && unsigned(i1 - base(1)) < length_[1]
1267 && unsigned(i2 - base(2)) < length_[2]
1268 && unsigned(i3 - base(3)) < length_[3]
1269 && unsigned(i4 - base(4)) < length_[4]
1270 && unsigned(i5 - base(5)) < length_[5];
1271 }
1272
1273 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4,
1274 int i5, int i6) const
1275 {
1276 return unsigned(i0 - base(0)) < length_[0]
1277 && unsigned(i1 - base(1)) < length_[1]
1278 && unsigned(i2 - base(2)) < length_[2]
1279 && unsigned(i3 - base(3)) < length_[3]
1280 && unsigned(i4 - base(4)) < length_[4]
1281 && unsigned(i5 - base(5)) < length_[5]
1282 && unsigned(i6 - base(6)) < length_[6];
1283 }
1284
1285 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4,
1286 int i5, int i6, int i7) const
1287 {
1288 return unsigned(i0 - base(0)) < length_[0]
1289 && unsigned(i1 - base(1)) < length_[1]
1290 && unsigned(i2 - base(2)) < length_[2]
1291 && unsigned(i3 - base(3)) < length_[3]
1292 && unsigned(i4 - base(4)) < length_[4]
1293 && unsigned(i5 - base(5)) < length_[5]
1294 && unsigned(i6 - base(6)) < length_[6]
1295 && unsigned(i7 - base(7)) < length_[7];
1296 }
1297
1298 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4,
1299 int i5, int i6, int i7, int i8) const
1300 {
1301 return unsigned(i0 - base(0)) < length_[0]
1302 && unsigned(i1 - base(1)) < length_[1]
1303 && unsigned(i2 - base(2)) < length_[2]
1304 && unsigned(i3 - base(3)) < length_[3]
1305 && unsigned(i4 - base(4)) < length_[4]
1306 && unsigned(i5 - base(5)) < length_[5]
1307 && unsigned(i6 - base(6)) < length_[6]
1308 && unsigned(i7 - base(7)) < length_[7]
1309 && unsigned(i8 - base(8)) < length_[8];
1310 }
1311
1312 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4,
1313 int i5, int i6, int i7, int i8, int i9) const
1314 {
1315 return unsigned(i0 - base(0)) < length_[0]
1316 && unsigned(i1 - base(1)) < length_[1]
1317 && unsigned(i2 - base(2)) < length_[2]
1318 && unsigned(i3 - base(3)) < length_[3]
1319 && unsigned(i4 - base(4)) < length_[4]
1320 && unsigned(i5 - base(5)) < length_[5]
1321 && unsigned(i6 - base(6)) < length_[6]
1322 && unsigned(i7 - base(7)) < length_[7]
1323 && unsigned(i8 - base(8)) < length_[8]
1324 && unsigned(i9 - base(9)) < length_[9];
1325 }
1326
1327 _bz_bool isInRange(int i0, int i1, int i2, int i3, int i4,
1328 int i5, int i6, int i7, int i8, int i9, int i10) const
1329 {
1330 return unsigned(i0 - base(0)) < length_[0]
1331 && unsigned(i1 - base(1)) < length_[1]
1332 && unsigned(i2 - base(2)) < length_[2]
1333 && unsigned(i3 - base(3)) < length_[3]
1334 && unsigned(i4 - base(4)) < length_[4]
1335 && unsigned(i5 - base(5)) < length_[5]
1336 && unsigned(i6 - base(6)) < length_[6]
1337 && unsigned(i7 - base(7)) < length_[7]
1338 && unsigned(i8 - base(8)) < length_[8]
1339 && unsigned(i9 - base(9)) < length_[9]
1340 && unsigned(i10 - base(10)) < length_[10];
1341 }
1342
1343 _bz_bool isInRange(const T_index& index) const
1344 {
1345 for (int i=0; i < N_rank; ++i)
1346 if (unsigned(index[i] - base(i)) >= length_[i])
1347 return _bz_false;
1348
1349 return _bz_true;
1350 }
1351
1352 _bz_bool assertInRange(const T_index& index) const
1353 {
1354 BZPRECHECK(isInRange(index), "Array index out of range: " << index
1355 << endl << "Lower bounds: " << storage_.base() << endl
1356 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1357 return _bz_true;
1358 }
1359
1360 _bz_bool assertInRange(int i0) const
1361 {
1362 BZPRECHECK(isInRange(i0), "Array index out of range: " << i0
1363 << endl << "Lower bounds: " << storage_.base() << endl
1364 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1365 return _bz_true;
1366 }
1367
1368 _bz_bool assertInRange(int i0, int i1) const
1369 {
1370 BZPRECHECK(isInRange(i0,i1), "Array index out of range: ("
1371 << i0 << ", " << i1 << ")"
1372 << endl << "Lower bounds: " << storage_.base() << endl
1373 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1374 return _bz_true;
1375 }
1376
1377 _bz_bool assertInRange(int i0, int i1, int i2) const
1378 {
1379 BZPRECHECK(isInRange(i0,i1,i2), "Array index out of range: ("
1380 << i0 << ", " << i1 << ", " << i2 << ")"
1381 << endl << "Lower bounds: " << storage_.base() << endl
1382 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1383 return _bz_true;
1384 }
1385
1386 _bz_bool assertInRange(int i0, int i1, int i2, int i3) const
1387 {
1388 BZPRECHECK(isInRange(i0,i1,i2,i3), "Array index out of range: ("
1389 << i0 << ", " << i1 << ", " << i2 << ", " << i3 << ")"
1390 << endl << "Lower bounds: " << storage_.base() << endl
1391 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1392 return _bz_true;
1393 }
1394
1395 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4) const
1396 {
1397 BZPRECHECK(isInRange(i0,i1,i2,i3,i4), "Array index out of range: ("
1398 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1399 << ", " << i4 << ")"
1400 << endl << "Lower bounds: " << storage_.base() << endl
1401 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1402 return _bz_true;
1403 }
1404
1405 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4,
1406 int i5) const
1407 {
1408 BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5), "Array index out of range: ("
1409 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1410 << ", " << i4 << ", " << i5 << ")"
1411 << endl << "Lower bounds: " << storage_.base() << endl
1412 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1413 return _bz_true;
1414 }
1415
1416 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4,
1417 int i5, int i6) const
1418 {
1419 BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6),
1420 "Array index out of range: ("
1421 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1422 << ", " << i4 << ", " << i5 << ", " << i6 << ")"
1423 << endl << "Lower bounds: " << storage_.base() << endl
1424 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1425 return _bz_true;
1426 }
1427
1428 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4,
1429 int i5, int i6, int i7) const
1430 {
1431 BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7),
1432 "Array index out of range: ("
1433 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1434 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7 << ")"
1435 << endl << "Lower bounds: " << storage_.base() << endl
1436 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1437 return _bz_true;
1438 }
1439
1440 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4,
1441 int i5, int i6, int i7, int i8) const
1442 {
1443 BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8),
1444 "Array index out of range: ("
1445 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1446 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7
1447 << ", " << i8 << ")"
1448 << endl << "Lower bounds: " << storage_.base() << endl
1449 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1450 return _bz_true;
1451 }
1452
1453 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4,
1454 int i5, int i6, int i7, int i8, int i9) const
1455 {
1456 BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8,i9),
1457 "Array index out of range: ("
1458 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1459 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7
1460 << ", " << i8 << ", " << i9 << ")"
1461 << endl << "Lower bounds: " << storage_.base() << endl
1462 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1463 return _bz_true;
1464 }
1465
1466 _bz_bool assertInRange(int i0, int i1, int i2, int i3, int i4,
1467 int i5, int i6, int i7, int i8, int i9, int i10) const
1468 {
1469 BZPRECHECK(isInRange(i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10),
1470 "Array index out of range: ("
1471 << i0 << ", " << i1 << ", " << i2 << ", " << i3
1472 << ", " << i4 << ", " << i5 << ", " << i6 << ", " << i7
1473 << ", " << i8 << ", " << i9 << ", " << i10 << ")"
1474 << endl << "Lower bounds: " << storage_.base() << endl
1475 << "Upper bounds: " << (storage_.base() + length_ - 1) << endl);
1476 return _bz_true;
1477 }
1478
1479 //////////////////////////////////////////////
1480 // Subscripting operators
1481 //////////////////////////////////////////////
1482
1483 template<int N_rank2>
1484 T_numtype operator()(const TinyVector<int,N_rank2>& index) const
1485 {
1486 assertInRange(index);
1487 return data_[dot(index, stride_)];
1488 }
1489
1490 template<int N_rank2>
1491 T_numtype& _bz_restrict operator()(const TinyVector<int,N_rank2>& index)
1492 {
1493 assertInRange(index);
1494 return data_[dot(index, stride_)];
1495 }
1496
1497 T_numtype operator()(TinyVector<int,1> index) const
1498 {
1499 assertInRange(index[0]);
1500 return data_[index[0] * stride_[0]];
1501 }
1502
1503 T_numtype& operator()(TinyVector<int,1> index)
1504 {
1505 assertInRange(index[0]);
1506 return data_[index[0] * stride_[0]];
1507 }
1508
1509 T_numtype operator()(TinyVector<int,2> index) const
1510 {
1511 assertInRange(index[0], index[1]);
1512 return data_[index[0] * stride_[0] + index[1] * stride_[1]];
1513 }
1514
1515 T_numtype& operator()(TinyVector<int,2> index)
1516 {
1517 assertInRange(index[0], index[1]);
1518 return data_[index[0] * stride_[0] + index[1] * stride_[1]];
1519 }
1520
1521 T_numtype operator()(TinyVector<int,3> index) const
1522 {
1523 assertInRange(index[0], index[1], index[2]);
1524 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1525 + index[2] * stride_[2]];
1526 }
1527
1528 T_numtype& operator()(TinyVector<int,3> index)
1529 {
1530 assertInRange(index[0], index[1], index[2]);
1531 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1532 + index[2] * stride_[2]];
1533 }
1534
1535 T_numtype operator()(const TinyVector<int,4>& index) const
1536 {
1537 assertInRange(index[0], index[1], index[2], index[3]);
1538 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1539 + index[2] * stride_[2] + index[3] * stride_[3]];
1540 }
1541
1542 T_numtype& operator()(const TinyVector<int,4>& index)
1543 {
1544 assertInRange(index[0], index[1], index[2], index[3]);
1545 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1546 + index[2] * stride_[2] + index[3] * stride_[3]];
1547 }
1548
1549 T_numtype operator()(const TinyVector<int,5>& index) const
1550 {
1551 assertInRange(index[0], index[1], index[2], index[3],
1552 index[4]);
1553 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1554 + index[2] * stride_[2] + index[3] * stride_[3]
1555 + index[4] * stride_[4]];
1556 }
1557
1558 T_numtype& operator()(const TinyVector<int,5>& index)
1559 {
1560 assertInRange(index[0], index[1], index[2], index[3],
1561 index[4]);
1562 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1563 + index[2] * stride_[2] + index[3] * stride_[3]
1564 + index[4] * stride_[4]];
1565 }
1566
1567 T_numtype operator()(const TinyVector<int,6>& index) const
1568 {
1569 assertInRange(index[0], index[1], index[2], index[3],
1570 index[4], index[5]);
1571 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1572 + index[2] * stride_[2] + index[3] * stride_[3]
1573 + index[4] * stride_[4] + index[5] * stride_[5]];
1574 }
1575
1576 T_numtype& operator()(const TinyVector<int,6>& index)
1577 {
1578 assertInRange(index[0], index[1], index[2], index[3],
1579 index[4], index[5]);
1580 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1581 + index[2] * stride_[2] + index[3] * stride_[3]
1582 + index[4] * stride_[4] + index[5] * stride_[5]];
1583 }
1584
1585 T_numtype operator()(const TinyVector<int,7>& index) const
1586 {
1587 assertInRange(index[0], index[1], index[2], index[3],
1588 index[4], index[5], index[6]);
1589 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1590 + index[2] * stride_[2] + index[3] * stride_[3]
1591 + index[4] * stride_[4] + index[5] * stride_[5]
1592 + index[6] * stride_[6]];
1593 }
1594
1595 T_numtype& operator()(const TinyVector<int,7>& index)
1596 {
1597 assertInRange(index[0], index[1], index[2], index[3],
1598 index[4], index[5], index[6]);
1599 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1600 + index[2] * stride_[2] + index[3] * stride_[3]
1601 + index[4] * stride_[4] + index[5] * stride_[5]
1602 + index[6] * stride_[6]];
1603 }
1604
1605 T_numtype operator()(const TinyVector<int,8>& index) const
1606 {
1607 assertInRange(index[0], index[1], index[2], index[3],
1608 index[4], index[5], index[6], index[7]);
1609 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1610 + index[2] * stride_[2] + index[3] * stride_[3]
1611 + index[4] * stride_[4] + index[5] * stride_[5]
1612 + index[6] * stride_[6] + index[7] * stride_[7]];
1613 }
1614
1615 T_numtype& operator()(const TinyVector<int,8>& index)
1616 {
1617 assertInRange(index[0], index[1], index[2], index[3],
1618 index[4], index[5], index[6], index[7]);
1619 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1620 + index[2] * stride_[2] + index[3] * stride_[3]
1621 + index[4] * stride_[4] + index[5] * stride_[5]
1622 + index[6] * stride_[6] + index[7] * stride_[7]];
1623 }
1624
1625 T_numtype operator()(const TinyVector<int,9>& index) const
1626 {
1627 assertInRange(index[0], index[1], index[2], index[3],
1628 index[4], index[5], index[6], index[7], index[8]);
1629 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1630 + index[2] * stride_[2] + index[3] * stride_[3]
1631 + index[4] * stride_[4] + index[5] * stride_[5]
1632 + index[6] * stride_[6] + index[7] * stride_[7]
1633 + index[8] * stride_[8]];
1634 }
1635
1636 T_numtype& operator()(const TinyVector<int,9>& index)
1637 {
1638 assertInRange(index[0], index[1], index[2], index[3],
1639 index[4], index[5], index[6], index[7], index[8]);
1640 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1641 + index[2] * stride_[2] + index[3] * stride_[3]
1642 + index[4] * stride_[4] + index[5] * stride_[5]
1643 + index[6] * stride_[6] + index[7] * stride_[7]
1644 + index[8] * stride_[8]];
1645 }
1646
1647 T_numtype operator()(const TinyVector<int,10>& index) const
1648 {
1649 assertInRange(index[0], index[1], index[2], index[3],
1650 index[4], index[5], index[6], index[7], index[8], index[9]);
1651 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1652 + index[2] * stride_[2] + index[3] * stride_[3]
1653 + index[4] * stride_[4] + index[5] * stride_[5]
1654 + index[6] * stride_[6] + index[7] * stride_[7]
1655 + index[8] * stride_[8] + index[9] * stride_[9]];
1656 }
1657
1658 T_numtype& operator()(const TinyVector<int,10>& index)
1659 {
1660 assertInRange(index[0], index[1], index[2], index[3],
1661 index[4], index[5], index[6], index[7], index[8], index[9]);
1662 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1663 + index[2] * stride_[2] + index[3] * stride_[3]
1664 + index[4] * stride_[4] + index[5] * stride_[5]
1665 + index[6] * stride_[6] + index[7] * stride_[7]
1666 + index[8] * stride_[8] + index[9] * stride_[9]];
1667 }
1668
1669 T_numtype operator()(const TinyVector<int,11>& index) const
1670 {
1671 assertInRange(index[0], index[1], index[2], index[3],
1672 index[4], index[5], index[6], index[7], index[8], index[9],
1673 index[10]);
1674 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1675 + index[2] * stride_[2] + index[3] * stride_[3]
1676 + index[4] * stride_[4] + index[5] * stride_[5]
1677 + index[6] * stride_[6] + index[7] * stride_[7]
1678 + index[8] * stride_[8] + index[9] * stride_[9]
1679 + index[10] * stride_[10]];
1680 }
1681
1682 T_numtype& operator()(const TinyVector<int,11>& index)
1683 {
1684 assertInRange(index[0], index[1], index[2], index[3],
1685 index[4], index[5], index[6], index[7], index[8], index[9],
1686 index[10]);
1687 return data_[index[0] * stride_[0] + index[1] * stride_[1]
1688 + index[2] * stride_[2] + index[3] * stride_[3]
1689 + index[4] * stride_[4] + index[5] * stride_[5]
1690 + index[6] * stride_[6] + index[7] * stride_[7]
1691 + index[8] * stride_[8] + index[9] * stride_[9]
1692 + index[10] * stride_[10]];
1693 }
1694
1695 T_numtype operator()(int i0) const
1696 {
1697 assertInRange(i0);
1698 return data_[i0 * stride_[0]];
1699 }
1700
1701 T_numtype& _bz_restrict operator()(int i0)
1702 {
1703 assertInRange(i0);
1704 return data_[i0 * stride_[0]];
1705 }
1706
1707 T_numtype operator()(int i0, int i1) const
1708 {
1709 assertInRange(i0, i1);
1710 return data_[i0 * stride_[0] + i1 * stride_[1]];
1711 }
1712
1713 T_numtype& _bz_restrict operator()(int i0, int i1)
1714 {
1715 assertInRange(i0, i1);
1716 return data_[i0 * stride_[0] + i1 * stride_[1]];
1717 }
1718
1719 T_numtype operator()(int i0, int i1, int i2) const
1720 {
1721 assertInRange(i0, i1, i2);
1722 return data_[i0 * stride_[0] + i1 * stride_[1]
1723 + i2 * stride_[2]];
1724 }
1725
1726 T_numtype& _bz_restrict operator()(int i0, int i1, int i2)
1727 {
1728 assertInRange(i0, i1, i2);
1729 return data_[i0 * stride_[0] + i1 * stride_[1]
1730 + i2 * stride_[2]];
1731 }
1732
1733 T_numtype operator()(int i0, int i1, int i2, int i3) const
1734 {
1735 assertInRange(i0, i1, i2, i3);
1736 return data_[i0 * stride_[0] + i1 * stride_[1]
1737 + i2 * stride_[2] + i3 * stride_[3]];
1738 }
1739
1740 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3)
1741 {
1742 assertInRange(i0, i1, i2, i3);
1743 return data_[i0 * stride_[0] + i1 * stride_[1]
1744 + i2 * stride_[2] + i3 * stride_[3]];
1745 }
1746
1747 T_numtype operator()(int i0, int i1, int i2, int i3,
1748 int i4) const
1749 {
1750 assertInRange(i0, i1, i2, i3, i4);
1751 return data_[i0 * stride_[0] + i1 * stride_[1]
1752 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]];
1753 }
1754
1755 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1756 int i4)
1757 {
1758 assertInRange(i0, i1, i2, i3, i4);
1759 return data_[i0 * stride_[0] + i1 * stride_[1]
1760 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]];
1761 }
1762
1763 T_numtype operator()(int i0, int i1, int i2, int i3,
1764 int i4, int i5) const
1765 {
1766 assertInRange(i0, i1, i2, i3, i4, i5);
1767 return data_[i0 * stride_[0] + i1 * stride_[1]
1768 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1769 + i5 * stride_[5]];
1770 }
1771
1772 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1773 int i4, int i5)
1774 {
1775 assertInRange(i0, i1, i2, i3, i4, i5);
1776 return data_[i0 * stride_[0] + i1 * stride_[1]
1777 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1778 + i5 * stride_[5]];
1779 }
1780
1781 T_numtype operator()(int i0, int i1, int i2, int i3,
1782 int i4, int i5, int i6) const
1783 {
1784 assertInRange(i0, i1, i2, i3, i4, i5, i6);
1785 return data_[i0 * stride_[0] + i1 * stride_[1]
1786 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1787 + i5 * stride_[5] + i6 * stride_[6]];
1788 }
1789
1790 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1791 int i4, int i5, int i6)
1792 {
1793 assertInRange(i0, i1, i2, i3, i4, i5, i6);
1794 return data_[i0 * stride_[0] + i1 * stride_[1]
1795 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1796 + i5 * stride_[5] + i6 * stride_[6]];
1797 }
1798
1799 T_numtype operator()(int i0, int i1, int i2, int i3,
1800 int i4, int i5, int i6, int i7) const
1801 {
1802 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7);
1803 return data_[i0 * stride_[0] + i1 * stride_[1]
1804 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1805 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]];
1806 }
1807
1808 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1809 int i4, int i5, int i6, int i7)
1810 {
1811 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7);
1812 return data_[i0 * stride_[0] + i1 * stride_[1]
1813 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1814 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]];
1815 }
1816
1817 T_numtype operator()(int i0, int i1, int i2, int i3,
1818 int i4, int i5, int i6, int i7, int i8) const
1819 {
1820 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8);
1821 return data_[i0 * stride_[0] + i1 * stride_[1]
1822 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1823 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
1824 + i8 * stride_[8]];
1825 }
1826
1827 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1828 int i4, int i5, int i6, int i7, int i8)
1829 {
1830 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8);
1831 return data_[i0 * stride_[0] + i1 * stride_[1]
1832 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1833 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
1834 + i8 * stride_[8]];
1835 }
1836
1837 T_numtype operator()(int i0, int i1, int i2, int i3,
1838 int i4, int i5, int i6, int i7, int i8, int i9) const
1839 {
1840 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);
1841 return data_[i0 * stride_[0] + i1 * stride_[1]
1842 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1843 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
1844 + i8 * stride_[8] + i9 * stride_[9]];
1845 }
1846
1847 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1848 int i4, int i5, int i6, int i7, int i8, int i9)
1849 {
1850 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9);
1851 return data_[i0 * stride_[0] + i1 * stride_[1]
1852 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1853 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
1854 + i8 * stride_[8] + i9 * stride_[9]];
1855 }
1856
1857 T_numtype operator()(int i0, int i1, int i2, int i3,
1858 int i4, int i5, int i6, int i7, int i8, int i9, int i10) const
1859 {
1860 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8,
1861 i9, i10);
1862 return data_[i0 * stride_[0] + i1 * stride_[1]
1863 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1864 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
1865 + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]];
1866 }
1867
1868 T_numtype& _bz_restrict operator()(int i0, int i1, int i2, int i3,
1869 int i4, int i5, int i6, int i7, int i8, int i9, int i10)
1870 {
1871 assertInRange(i0, i1, i2, i3, i4, i5, i6, i7, i8,
1872 i9, i10);
1873 return data_[i0 * stride_[0] + i1 * stride_[1]
1874 + i2 * stride_[2] + i3 * stride_[3] + i4 * stride_[4]
1875 + i5 * stride_[5] + i6 * stride_[6] + i7 * stride_[7]
1876 + i8 * stride_[8] + i9 * stride_[9] + i10 * stride_[10]];
1877 }
1878
1879 /*
1880 * Slicing to produce subarrays. If the number of Range arguments is
1881 * fewer than N_rank, then missing arguments are treated like Range::all().
1882 */
1883
1884 T_array operator()(const RectDomain<N_rank>& subdomain)
1885 {
1886 return T_array(*this, subdomain);
1887 }
1888
1889 T_array operator()(Range r0)
1890 {
1891 return T_array(*this, r0);
1892 }
1893
1894 T_array operator()(Range r0, Range r1)
1895 {
1896 return T_array(*this, r0, r1);
1897 }
1898
1899 T_array operator()(Range r0, Range r1, Range r2)
1900 {
1901 return T_array(*this, r0, r1, r2);
1902 }
1903
1904 T_array operator()(Range r0, Range r1, Range r2, Range r3)
1905 {
1906 return T_array(*this, r0, r1, r2, r3);
1907 }
1908
1909 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4)
1910 {
1911 return T_array(*this, r0, r1, r2, r3, r4);
1912 }
1913
1914 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
1915 Range r5)
1916 {
1917 return T_array(*this, r0, r1, r2, r3, r4, r5);
1918 }
1919
1920 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
1921 Range r5, Range r6)
1922 {
1923 return T_array(*this, r0, r1, r2, r3, r4, r5, r6);
1924 }
1925
1926 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
1927 Range r5, Range r6, Range r7)
1928 {
1929 return T_array(*this, r0, r1, r2, r3, r4, r5, r6, r7);
1930 }
1931
1932 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
1933 Range r5, Range r6, Range r7, Range r8)
1934 {
1935 return T_array(*this, r0, r1, r2, r3, r4, r5, r6, r7, r8);
1936 }
1937
1938 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
1939 Range r5, Range r6, Range r7, Range r8, Range r9)
1940 {
1941 return T_array(*this, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9);
1942 }
1943
1944 T_array operator()(Range r0, Range r1, Range r2, Range r3, Range r4,
1945 Range r5, Range r6, Range r7, Range r8, Range r9, Range r10)
1946 {
1947 return T_array(*this, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10);
1948 }
1949
1950 // Allow any mixture of Range, int and Vector<int> objects as
1951 // operands for operator(): A(Range(3,7), 5, Range(2,4))
1952
1953 /*
1954 * These versions of operator() allow any combination of int
1955 * and Range operands to be used. Each int operand reduces
1956 * the rank of the resulting array by one.
1957 *
1958 * e.g. Array<int,4> A(20,20,20,20);
1959 * Array<int,2> B = A(Range(5,15), 3, 5, Range(8,9));
1960 *
1961 * SliceInfo is a helper class defined in <blitz/arrayslice.h>.
1962 * It counts the number of Range vs. int arguments and does some
1963 * other helpful things.
1964 *
1965 * Once partial specialization becomes widely implemented, these
1966 * operators may be expanded to accept Vector<int> arguments
1967 * and produce ArrayPick<T,N> objects.
1968 *
1969 * This operator() is not provided with a single argument because
1970 * the appropriate cases exist above.
1971 */
1972
1973#ifdef BZ_PARTIAL_ORDERING
1974
1975 template<class T1, class T2>
1976 _bz_typename SliceInfo<T_numtype,T1,T2>::T_slice
1977 operator()(T1 r1, T2 r2)
1978 {
1979 return SliceInfo<T_numtype,T1,T2>::T_slice(*this, r1, r2,
1980 nilArraySection(), nilArraySection(), nilArraySection(),
1981 nilArraySection(), nilArraySection(), nilArraySection(),
1982 nilArraySection(), nilArraySection(), nilArraySection());
1983 }
1984
1985 template<class T1, class T2, class T3>
1986 _bz_typename SliceInfo<T_numtype,T1,T2,T3>::T_slice
1987 operator()(T1 r1, T2 r2, T3 r3)
1988 {
1989 return SliceInfo<T_numtype,T1,T2,T3>::T_slice(*this, r1, r2, r3,
1990 nilArraySection(), nilArraySection(), nilArraySection(),
1991 nilArraySection(), nilArraySection(), nilArraySection(),
1992 nilArraySection(), nilArraySection());
1993 }
1994
1995 template<class T1, class T2, class T3, class T4>
1996 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4>::T_slice
1997 operator()(T1 r1, T2 r2, T3 r3, T4 r4)
1998 {
1999 return SliceInfo<T_numtype,T1,T2,T3,T4>::T_slice(*this, r1, r2, r3,
2000 r4, nilArraySection(), nilArraySection(),
2001 nilArraySection(), nilArraySection(), nilArraySection(),
2002 nilArraySection(), nilArraySection());
2003 }
2004
2005 template<class T1, class T2, class T3, class T4, class T5>
2006 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5>::T_slice
2007 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5)
2008 {
2009 return SliceInfo<T_numtype,T1,T2,T3,T4,T5>::T_slice(*this, r1, r2, r3,
2010 r4, r5, nilArraySection(),
2011 nilArraySection(), nilArraySection(), nilArraySection(),
2012 nilArraySection(), nilArraySection());
2013 }
2014
2015 template<class T1, class T2, class T3, class T4, class T5, class T6>
2016 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6>::T_slice
2017 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6)
2018 {
2019 return SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6>::T_slice(*this, r1, r2,
2020 r3, r4, r5, r6,
2021 nilArraySection(), nilArraySection(), nilArraySection(),
2022 nilArraySection(), nilArraySection());
2023 }
2024
2025 template<class T1, class T2, class T3, class T4, class T5, class T6,
2026 class T7>
2027 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7>::T_slice
2028 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7)
2029 {
2030 return SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7>::T_slice(*this, r1,
2031 r2, r3, r4, r5, r6, r7,
2032 nilArraySection(), nilArraySection(),
2033 nilArraySection(), nilArraySection());
2034 }
2035
2036 template<class T1, class T2, class T3, class T4, class T5, class T6,
2037 class T7, class T8>
2038 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8>::T_slice
2039 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8)
2040 {
2041 return SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8>::T_slice(*this,
2042 r1, r2, r3, r4, r5, r6, r7, r8,
2043 nilArraySection(), nilArraySection(), nilArraySection());
2044 }
2045
2046 template<class T1, class T2, class T3, class T4, class T5, class T6,
2047 class T7, class T8, class T9>
2048 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9>::T_slice
2049 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8,
2050 T9 r9)
2051 {
2052 return SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9>::T_slice(*this,
2053 r1, r2, r3, r4, r5, r6, r7, r8, r9,
2054 nilArraySection(), nilArraySection());
2055 }
2056
2057 template<class T1, class T2, class T3, class T4, class T5, class T6,
2058 class T7, class T8, class T9, class T10>
2059 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10>::T_slice
2060 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8,
2061 T9 r9, T10 r10)
2062 {
2063 return SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,
2064 T10>::T_slice(*this, r1, r2, r3, r4, r5, r6, r7, r8,
2065 r9, r10, nilArraySection());
2066 }
2067
2068 template<class T1, class T2, class T3, class T4, class T5, class T6,
2069 class T7, class T8, class T9, class T10, class T11>
2070 _bz_typename SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,
2071 T11>::T_slice
2072 operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8,
2073 T9 r9, T10 r10, T11 r11)
2074 {
2075 return SliceInfo<T_numtype,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,
2076 T11>::T_slice(*this, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11);
2077 }
2078
2079#endif // BZ_PARTIAL_ORDERING
2080
2081 /*
2082 * These versions of operator() are provided to support tensor-style
2083 * array notation, e.g.
2084 *
2085 * Array<float, 2> A, B;
2086 * firstIndex i;
2087 * secondIndex j;
2088 * thirdIndex k;
2089 * Array<float, 3> C = A(i,j) * B(j,k);
2090 */
2091
2092 template<int N0>
2093 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0> >
2094 operator()(IndexPlaceholder<N0>)
2095 {
2096 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0> >(*this);
2097 }
2098
2099 template<int N0, int N1>
2100 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1> >
2101 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>)
2102 {
2103 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2104 N1> >(*this);
2105 }
2106
2107 template<int N0, int N1, int N2>
2108 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2> >
2109 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2110 IndexPlaceholder<N2>)
2111 {
2112 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2113 N1, N2> >(*this);
2114 }
2115
2116 template<int N0, int N1, int N2, int N3>
2117 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3> >
2118 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2119 IndexPlaceholder<N2>, IndexPlaceholder<N3>)
2120 {
2121 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2122 N1, N2, N3> >(*this);
2123 }
2124
2125 template<int N0, int N1, int N2, int N3, int N4>
2126 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3, N4> >
2127 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2128 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>)
2129 {
2130 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2131 N1, N2, N3, N4> >(*this);
2132 }
2133
2134 template<int N0, int N1, int N2, int N3, int N4, int N5>
2135 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
2136 N4, N5> >
2137 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2138 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
2139 IndexPlaceholder<N5>)
2140 {
2141 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2142 N1, N2, N3, N4, N5> >(*this);
2143 }
2144
2145 template<int N0, int N1, int N2, int N3, int N4, int N5, int N6>
2146 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
2147 N4, N5, N6> >
2148 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2149 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
2150 IndexPlaceholder<N5>, IndexPlaceholder<N6>)
2151 {
2152 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2153 N1, N2, N3, N4, N5, N6> >(*this);
2154 }
2155
2156 template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
2157 int N7>
2158 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
2159 N4, N5, N6, N7> >
2160 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2161 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
2162 IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>)
2163 {
2164 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2165 N1, N2, N3, N4, N5, N6, N7> >(*this);
2166 }
2167
2168 template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
2169 int N7, int N8>
2170 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
2171 N4, N5, N6, N7, N8> >
2172 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2173 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
2174 IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>,
2175 IndexPlaceholder<N8>)
2176 {
2177 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2178 N1, N2, N3, N4, N5, N6, N7, N8> >(*this);
2179 }
2180
2181 template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
2182 int N7, int N8, int N9>
2183 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
2184 N4, N5, N6, N7, N8, N9> >
2185 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2186 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
2187 IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>,
2188 IndexPlaceholder<N8>, IndexPlaceholder<N9>)
2189 {
2190 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2191 N1, N2, N3, N4, N5, N6, N7, N8, N9> >(*this);
2192 }
2193
2194 template<int N0, int N1, int N2, int N3, int N4, int N5, int N6,
2195 int N7, int N8, int N9, int N10>
2196 _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0, N1, N2, N3,
2197 N4, N5, N6, N7, N8, N9, N10> >
2198 operator()(IndexPlaceholder<N0>, IndexPlaceholder<N1>,
2199 IndexPlaceholder<N2>, IndexPlaceholder<N3>, IndexPlaceholder<N4>,
2200 IndexPlaceholder<N5>, IndexPlaceholder<N6>, IndexPlaceholder<N7>,
2201 IndexPlaceholder<N8>, IndexPlaceholder<N9>, IndexPlaceholder<N10>)
2202 {
2203 return _bz_ArrayExpr<ArrayIndexMapping<T_numtype, N_rank, N0,
2204 N1, N2, N3, N4, N5, N6, N7, N8, N9, N10> >(*this);
2205 }
2206
2207 //////////////////////////////////////////////
2208 // Support for multicomponent arrays
2209 //////////////////////////////////////////////
2210
2211 /*
2212 * See <blitz/array/multi.h> for an explanation of the traits class
2213 * multicomponent_traits.
2214 */
2215 Array<_bz_typename multicomponent_traits<T_numtype>::T_element,N_rank>
2216 operator[](int component)
2217 {
2218 typedef _bz_typename multicomponent_traits<T_numtype>::T_element
2219 T_compType;
2220
2221 return extractComponent(T_compType(),
2222 component, multicomponent_traits<T_numtype>::numComponents);
2223 }
2224
2225 //////////////////////////////////////////////
2226 // Indirection
2227 //////////////////////////////////////////////
2228
2229 template<class T_indexContainer>
2230 IndirectArray<T_array, T_indexContainer>
2231 operator[](const T_indexContainer& index)
2232 {
2233 return IndirectArray<T_array, T_indexContainer>(*this,
2234 const_cast<T_indexContainer&>(index));
2235 }
2236
2237 //////////////////////////////////////////////
2238 // Assignment Operators
2239 //////////////////////////////////////////////
2240
2241 // Scalar operand
2242 // NEEDS_WORK : need a precondition check on
2243 // isStorageContiguous when operator, is used.
2244 ListInitializationSwitch<T_array> operator=(T_numtype x)
2245 {
2246 return ListInitializationSwitch<T_array>(*this, x);
2247 }
2248
2249 T_array& initialize(T_numtype);
2250
2251 // Was:
2252 // T_array& operator=(T_numtype);
2253
2254 T_array& operator+=(T_numtype);
2255 T_array& operator-=(T_numtype);
2256 T_array& operator*=(T_numtype);
2257 T_array& operator/=(T_numtype);
2258 T_array& operator%=(T_numtype);
2259 T_array& operator^=(T_numtype);
2260 T_array& operator&=(T_numtype);
2261 T_array& operator|=(T_numtype);
2262 T_array& operator>>=(T_numtype);
2263 T_array& operator<<=(T_numtype);
2264
2265 // Array operands
2266 T_array& operator=(const Array<T_numtype,N_rank>&);
2267
2268 template<class T_numtype2>
2269 T_array& operator=(const Array<T_numtype2,N_rank>&);
2270 template<class T_numtype2>
2271 T_array& operator+=(const Array<T_numtype2,N_rank>&);
2272 template<class T_numtype2>
2273 T_array& operator-=(const Array<T_numtype2,N_rank>&);
2274 template<class T_numtype2>
2275 T_array& operator*=(const Array<T_numtype2,N_rank>&);
2276 template<class T_numtype2>
2277 T_array& operator/=(const Array<T_numtype2,N_rank>&);
2278 template<class T_numtype2>
2279 T_array& operator%=(const Array<T_numtype2,N_rank>&);
2280 template<class T_numtype2>
2281 T_array& operator^=(const Array<T_numtype2,N_rank>&);
2282 template<class T_numtype2>
2283 T_array& operator&=(const Array<T_numtype2,N_rank>&);
2284 template<class T_numtype2>
2285 T_array& operator|=(const Array<T_numtype2,N_rank>&);
2286 template<class T_numtype2>
2287 T_array& operator>>=(const Array<T_numtype2,N_rank>&);
2288 template<class T_numtype2>
2289 T_array& operator<<=(const Array<T_numtype2,N_rank>&);
2290
2291 // Array expression operands
2292 template<class T_expr>
2293 inline T_array& operator=(_bz_ArrayExpr<T_expr> expr);
2294 template<class T_expr>
2295 inline T_array& operator+=(_bz_ArrayExpr<T_expr> expr);
2296 template<class T_expr>
2297 inline T_array& operator-=(_bz_ArrayExpr<T_expr> expr);
2298 template<class T_expr>
2299 inline T_array& operator*=(_bz_ArrayExpr<T_expr> expr);
2300 template<class T_expr>
2301 inline T_array& operator/=(_bz_ArrayExpr<T_expr> expr);
2302 template<class T_expr>
2303 inline T_array& operator%=(_bz_ArrayExpr<T_expr> expr);
2304 template<class T_expr>
2305 inline T_array& operator^=(_bz_ArrayExpr<T_expr> expr);
2306 template<class T_expr>
2307 inline T_array& operator&=(_bz_ArrayExpr<T_expr> expr);
2308 template<class T_expr>
2309 inline T_array& operator|=(_bz_ArrayExpr<T_expr> expr);
2310 template<class T_expr>
2311 inline T_array& operator>>=(_bz_ArrayExpr<T_expr> expr);
2312 template<class T_expr>
2313 inline T_array& operator<<=(_bz_ArrayExpr<T_expr> expr);
2314
2315 // NEEDS_WORK -- Index placeholder operand
2316
2317 // NEEDS_WORK -- Random operand
2318
2319
2320public:
2321 // Undocumented implementation routines
2322
2323 template<class T_expr, class T_update>
2324 inline T_array& evaluate(_bz_ArrayExpr<T_expr> expr,
2325 T_update);
2326
2327#ifdef BZ_HAVE_STD
2328 template<class T_expr, class T_update>
2329 inline T_array& evaluateWithFastTraversal(
2330 const TraversalOrder<N_rank - 1>& order, _bz_ArrayExpr<T_expr> expr,
2331 T_update);
2332#endif
2333
2334#ifdef BZ_ARRAY_2D_STENCIL_TILING
2335 template<class T_expr, class T_update>
2336 inline T_array& evaluateWithTiled2DTraversal(_bz_ArrayExpr<T_expr> expr,
2337 T_update);
2338#endif
2339
2340 template<class T_expr, class T_update>
2341 inline T_array& evaluateWithIndexTraversal1(_bz_ArrayExpr<T_expr> expr,
2342 T_update);
2343
2344 template<class T_expr, class T_update>
2345 inline T_array& evaluateWithIndexTraversalN(_bz_ArrayExpr<T_expr> expr,
2346 T_update);
2347
2348 template<class T_expr, class T_update>
2349 inline T_array& evaluateWithStackTraversal1(_bz_ArrayExpr<T_expr> expr,
2350 T_update);
2351
2352 template<class T_expr, class T_update>
2353 inline T_array& evaluateWithStackTraversalN(_bz_ArrayExpr<T_expr> expr,
2354 T_update);
2355
2356 T_numtype* _bz_restrict getInitializationIterator()
2357 { return dataFirst(); }
2358
2359 _bz_bool canCollapse(int outerRank, int innerRank) const
2360 {
2361#ifdef BZ_DEBUG_TRAVERSE
2362 BZ_DEBUG_MESSAGE("stride(" << innerRank << ")=" << stride(innerRank)
2363 << ", extent()=" << extent(innerRank) << ", stride(outerRank)="
2364 << stride(outerRank));
2365#endif
2366 return (stride(innerRank) * extent(innerRank) == stride(outerRank));
2367 }
2368
2369protected:
2370 //////////////////////////////////////////////
2371 // Implementation routines
2372 //////////////////////////////////////////////
2373
2374 _bz_inline2 void computeStrides();
2375 _bz_inline2 void setupStorage(int rank);
2376 void constructSubarray(Array<T_numtype, N_rank>& array,
2377 const RectDomain<N_rank>&);
2378 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0);
2379 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0, Range r1);
2380 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2381 Range r1, Range r2);
2382 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2383 Range r1, Range r2, Range r3);
2384 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2385 Range r1, Range r2, Range r3, Range r4);
2386 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2387 Range r1, Range r2, Range r3, Range r4, Range r5);
2388 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2389 Range r1, Range r2, Range r3, Range r4, Range r5, Range r6);
2390 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2391 Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
2392 Range r7);
2393 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2394 Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
2395 Range r7, Range r8);
2396 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2397 Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
2398 Range r7, Range r8, Range r9);
2399 void constructSubarray(Array<T_numtype, N_rank>& array, Range r0,
2400 Range r1, Range r2, Range r3, Range r4, Range r5, Range r6,
2401 Range r7, Range r8, Range r9, Range r10);
2402
2403 void calculateZeroOffset();
2404
2405 template<int N_rank2, class R0, class R1, class R2, class R3, class R4,
2406 class R5, class R6, class R7, class R8, class R9, class R10>
2407 void constructSlice(Array<T_numtype, N_rank2>& array, R0 r0, R1 r1, R2 r2,
2408 R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10);
2409
2410 template<int N_rank2>
2411 void slice(int& setRank, Range r, Array<T_numtype,N_rank2>& array,
2412 TinyVector<int,N_rank2>& rankMap, int sourceRank);
2413
2414 template<int N_rank2>
2415 void slice(int& setRank, int i, Array<T_numtype,N_rank2>& array,
2416 TinyVector<int,N_rank2>& rankMap, int sourceRank);
2417
2418 template<int N_rank2>
2419 void slice(int& setRank, nilArraySection, Array<T_numtype,N_rank2>& array,
2420 TinyVector<int,N_rank2>& rankMap, int sourceRank)
2421 { }
2422
2423 void doTranspose(int destRank, int sourceRank, T_array& array);
2424
2425protected:
2426 //////////////////////////////////////////////
2427 // Data members
2428 //////////////////////////////////////////////
2429
2430 // NB: adding new data members may require changes to ctors, reference()
2431
2432 /*
2433 * For a description of the storage_ members, see the comments for class
2434 * GeneralArrayStorage<N_rank> above.
2435 *
2436 * length_[] contains the extent of each rank. E.g. a 10x20x30 array
2437 * would have length_ = { 10, 20, 30}.
2438 * stride_[] contains the stride to move to the next element along each
2439 * rank.
2440 * zeroOffset_ is the distance from the first element in the array
2441 * to the point (0,0,...,0). If base_ is zero and all ranks are
2442 * stored ascending, then zeroOffset_ is zero. This value
2443 * is needed because to speed up indexing, the data_ member
2444 * (inherited from MemoryBlockReference) always refers to
2445 * (0,0,...,0).
2446 * storageContiguous_ is true if all the elements in the array are
2447 * stored contiguously in memory. If this is true, then
2448 * the array can be converted to a one-dimensional array.
2449 * If the array is sliced, then this becomes false.
2450 */
2451 GeneralArrayStorage<N_rank> storage_;
2452 TinyVector<int, N_rank> length_;
2453 TinyVector<int, N_rank> stride_;
2454 int zeroOffset_;
2455 _bz_bool storageContiguous_;
2456};
2457
2458/*
2459 * Rank numbers start with zero, which may be confusing to users coming
2460 * from Fortran. To make code more readable, the following constants
2461 * may help. Example: instead of
2462 *
2463 * int firstRankExtent = A.extent(0);
2464 *
2465 * One can write:
2466 *
2467 * int firstRankExtent = A.extent(firstRank);
2468 */
2469
2470const int firstRank = 0;
2471const int secondRank = 1;
2472const int thirdRank = 2;
2473const int fourthRank = 3;
2474const int fifthRank = 4;
2475const int sixthRank = 5;
2476const int seventhRank = 6;
2477const int eighthRank = 7;
2478const int ninthRank = 8;
2479const int tenthRank = 9;
2480const int eleventhRank = 10;
2481
2482const int firstDim = 0;
2483const int secondDim = 1;
2484const int thirdDim = 2;
2485const int fourthDim = 3;
2486const int fifthDim = 4;
2487const int sixthDim = 5;
2488const int seventhDim = 6;
2489const int eighthDim = 7;
2490const int ninthDim = 8;
2491const int tenthDim = 9;
2492const int eleventhDim = 10;
2493
2494/*
2495 * Global Functions
2496 */
2497
2498template<class T_numtype>
2499ostream& operator<<(ostream&, const Array<T_numtype,1>&);
2500
2501template<class T_numtype>
2502ostream& operator<<(ostream&, const Array<T_numtype,2>&);
2503
2504// NEEDS_WORK -- output formatting for N > 2?
2505
2506BZ_NAMESPACE_END
2507
2508/*
2509 * Include implementations of the member functions and some additional
2510 * global functions.
2511 */
2512
2513#include <blitz/array/iter.h> // Array iterators
2514#include <blitz/array/expr.h> // Array expression objects
2515#include <blitz/array/methods.cc> // Member functions
2516#include <blitz/array/eval.cc> // Array expression evaluation
2517#include <blitz/array/ops.cc> // Assignment operators
2518#include <blitz/array/io.cc> // Output formatting
2519#include <blitz/array/bops.cc> // Expression templates, two operands
2520#include <blitz/array/uops.cc> // Expression templates, math functions
2521#include <blitz/array/misc.cc> // Expression templates, miscellaneous
2522#include <blitz/array/reduce.h> // Array reduction expression templates
2523#include <blitz/array/interlace.cc> // Allocation of interlaced arrays
2524#include <blitz/array/resize.cc> // Array resize, resizeAndPreserve
2525#include <blitz/array/slicing.cc> // Slicing and subarrays
2526#include <blitz/array/cycle.cc> // Cycling arrays
2527#include <blitz/array/complex.cc> // Special support for complex arrays
2528#include <blitz/array/zip.h> // Zipping multicomponent types
2529#include <blitz/array/where.h> // where(X,Y,Z)
2530#include <blitz/array/stencil.h> // Stencil objects
2531#include <blitz/array/indirect.h> // Indirection
2532
2533#endif // BZ_ARRAY_H
2534
Note: See TracBrowser for help on using the repository browser.