1
/***************************************************************************
2
* blitz/array/storage.h Memory layout of Arrays.
4
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* Suggestions: blitz-dev@oonumerics.org
17
* Bugs: blitz-bugs@oonumerics.org
19
* For more information, please see the Blitz++ Home Page:
20
* http://oonumerics.org/blitz/
22
****************************************************************************/
23
#ifndef BZ_ARRAY_STORAGE_H
24
#define BZ_ARRAY_STORAGE_H
29
* Declaration of class GeneralStorage<N_rank>
31
* This class describes a storage format for an N-dimensional array.
32
* The dimensions can be stored in an arbitrary order (for example, as
33
* a C-style row major array or Fortran-style column major array, or
34
* something else entirely). Each dimension can be stored in either
35
* ascending (the most common) or descending order. Each dimension
36
* can have its own base (starting index value: e.g. 0 for C-style arrays,
37
* 1 for Fortran arrays).
39
* GeneralArrayStorage<N> defaults to C-style arrays. To implement
40
* other storage formats, subclass and modify the constructor. The
41
* class FortranArray, below, is an example.
43
* Objects inheriting from GeneralArrayStorage<N> can be passed as
44
* an optional constructor argument to Array objects.
45
* e.g. Array<int,3> A(16,16,16, FortranArray<3>());
46
* will create a 3-dimensional 16x16x16 Fortran-style array.
50
class GeneralArrayStorage {
52
class noInitializeFlag { };
54
GeneralArrayStorage(noInitializeFlag)
59
for (int i=0; i < N_rank; ++i)
60
ordering_(i) = N_rank - 1 - i;
61
ascendingFlag_ = true;
65
GeneralArrayStorage(const GeneralArrayStorage<N_rank>& x)
66
: ordering_(x.ordering_), ascendingFlag_(x.ascendingFlag_),
71
GeneralArrayStorage(TinyVector<int,N_rank> ordering,
72
TinyVector<bool,N_rank> ascendingFlag)
73
: ordering_(ordering), ascendingFlag_(ascendingFlag)
78
~GeneralArrayStorage()
81
GeneralArrayStorage<N_rank>& operator=(
82
const GeneralArrayStorage<N_rank>& rhs)
84
ordering_ = rhs.ordering();
85
ascendingFlag_ = rhs.ascendingFlag();
90
TinyVector<int, N_rank>& ordering()
93
const TinyVector<int, N_rank>& ordering() const
96
int ordering(int i) const
97
{ return ordering_[i]; }
99
void setOrdering(int i, int order)
100
{ ordering_[i] = order; }
102
bool allRanksStoredAscending() const
105
for (int i=0; i < N_rank; ++i)
106
result &= ascendingFlag_[i];
110
bool isRankStoredAscending(int i) const
111
{ return ascendingFlag_[i]; }
113
TinyVector<bool, N_rank>& ascendingFlag()
114
{ return ascendingFlag_; }
116
const TinyVector<bool, N_rank>& ascendingFlag() const
117
{ return ascendingFlag_; }
119
void setAscendingFlag(int i, bool ascendingFlag)
120
{ ascendingFlag_[i] = ascendingFlag; }
122
TinyVector<int, N_rank>& base()
125
const TinyVector<int, N_rank>& base() const
128
int base(int i) const
131
void setBase(int i, int base)
134
void setBase(const TinyVector<int, N_rank>& base)
139
* ordering_[] specifies the order in which the array is stored in
140
* memory. For a newly allocated array, ordering_(0) will give the
141
* rank with unit stride, and ordering_(N_rank-1) will be the rank
142
* with largest stride. An order like [2, 1, 0] corresponds to
143
* C-style array storage; an order like [0, 1, 2] corresponds to
144
* Fortran array storage.
146
* ascendingFlag_[] indicates whether the data in a rank is stored
147
* in ascending or descending order. Most of the time these values
148
* will all be true (indicating ascending order). Some peculiar
149
* formats (e.g. MS-Windows BMP image format) store the data in
152
* base_[] gives the first valid index for each rank. For a C-style
153
* array, all the base_ elements will be zero; for a Fortran-style
154
* array, they will be one. base_[] can be set arbitrarily using
155
* the Array constructor which takes a Range argument, e.g.
156
* Array<float,2> A(Range(30,40),Range(23,33));
157
* will create an array with base_[] = { 30, 23 }.
159
TinyVector<int, N_rank> ordering_;
160
TinyVector<bool, N_rank> ascendingFlag_;
161
TinyVector<int, N_rank> base_;
165
* Class FortranArray specializes GeneralArrayStorage to provide Fortran
166
* style arrays (column major ordering, base of 1). The noInitializeFlag()
167
* passed to the base constructor indicates that the subclass will take
168
* care of initializing the ordering_, ascendingFlag_ and base_ members.
172
class FortranArray : public GeneralArrayStorage<N_rank> {
174
typedef GeneralArrayStorage<N_rank> T_base;
175
typedef _bz_typename T_base::noInitializeFlag noInitializeFlag;
176
using T_base::ordering_;
177
using T_base::ascendingFlag_;
181
: GeneralArrayStorage<N_rank>(noInitializeFlag())
183
for (int i=0; i < N_rank; ++i)
185
ascendingFlag_ = true;
191
// This tag class can be used to provide a nicer notation for
192
// constructing Fortran-style arrays: instead of
193
// Array<int,2> A(3, 3, FortranArray<2>());
194
// one can simply write:
195
// Array<int,2> A(3, 3, fortranArray);
196
// where fortranArray is an object of type _bz_fortranTag.
198
class _bz_fortranTag {
200
operator GeneralArrayStorage<1>()
201
{ return FortranArray<1>(); }
203
operator GeneralArrayStorage<2>()
204
{ return FortranArray<2>(); }
206
operator GeneralArrayStorage<3>()
207
{ return FortranArray<3>(); }
209
operator GeneralArrayStorage<4>()
210
{ return FortranArray<4>(); }
212
operator GeneralArrayStorage<5>()
213
{ return FortranArray<5>(); }
215
operator GeneralArrayStorage<6>()
216
{ return FortranArray<6>(); }
218
operator GeneralArrayStorage<7>()
219
{ return FortranArray<7>(); }
221
operator GeneralArrayStorage<8>()
222
{ return FortranArray<8>(); }
224
operator GeneralArrayStorage<9>()
225
{ return FortranArray<9>(); }
227
operator GeneralArrayStorage<10>()
228
{ return FortranArray<10>(); }
230
operator GeneralArrayStorage<11>()
231
{ return FortranArray<11>(); }
234
// A global instance of this class will be placed in
235
// the blitz library (libblitz.a on unix machines).
237
_bz_global _bz_fortranTag fortranArray;
241
* Class ColumnMajorArray specializes GeneralArrayStorage to provide column
242
* major arrays (column major ordering, base of 0).
246
class ColumnMajorArray : public GeneralArrayStorage<N_rank> {
248
typedef GeneralArrayStorage<N_rank> T_base;
249
typedef _bz_typename T_base::noInitializeFlag noInitializeFlag;
250
using T_base::ordering_;
251
using T_base::ascendingFlag_;
255
: GeneralArrayStorage<N_rank>(noInitializeFlag())
257
ordering_ = Range(0, N_rank - 1);
258
ascendingFlag_ = true;
265
#endif // BZ_ARRAY_STORAGE_H