source: Sophya/trunk/SophyaExt/Blitz/blitz/array.h@ 3477

Last change on this file since 3477 was 221, checked in by ansari, 26 years ago

Creation module DPC/Blitz (blitz 0.4) Reza 09/04/99

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