OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Array2D.h
Go to the documentation of this file.
1 #ifndef CLASSIC_Array2D_HH
2 #define CLASSIC_Array2D_HH
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: Array2D.h,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.1.1.1 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template class: Array2D
13 //
14 // ------------------------------------------------------------------------
15 // Class category: Algebra
16 // ------------------------------------------------------------------------
17 //
18 // $Date: 2000/03/27 09:32:32 $
19 // $Author: fci $
20 //
21 // ------------------------------------------------------------------------
22 
23 #include "Algebra/Array1D.h"
24 #include "Algebra/SliceIterator.h"
25 #include "Utilities/CLRangeError.h"
26 #include "Utilities/SizeError.h"
27 #include <algorithm>
28 #include <iosfwd>
29 
30 
31 // Template class Array2D<T>
32 // ------------------------------------------------------------------------
34 // A templated representation for 2-dimensional arrays.
35 // This class implements storage management and component access,
36 // as well as access to rows and columns, but contains no arithmetic
37 // operations.
38 
39 template<class T>
40 class Array2D {
41 
42 public:
43 
45  typedef T value_type;
46 
48  typedef T *iterator;
49 
51  // of a constant array.
52  typedef const T *const_iterator;
53 
55  typedef T *row_iterator;
56 
58  typedef const T *const_row_iterator;
59 
62 
65 
67  // Constructs array of zero rows and zero columns.
68  Array2D();
69 
71  // Reserves [b]rows[/b] times [b]cols[/b] elements and leaves
72  // them undefined.
73  Array2D(int rows, int cols);
74 
76  // Reserves [b]rows[/b] x [b]cols[/b] elements and sets them to [b]t[/b].
77  Array2D(int rows, int cols, const T &t);
78 
79  Array2D(const Array2D &);
80  ~Array2D();
82 
84  // Return a reference to element in row [b]r[/b] and column [b]c[/b].
85  T &operator()(int r, int c);
86 
88  // Return the value of element in row [b]r[/b] and column [b]c[/b].
89  const T &operator()(int r, int c) const;
90 
92  int nrows() const;
93 
95  int ncols() const;
96 
98  int size() const;
99 
100 
102  // Treat the array as one-dimensional.
103  // Version for non-constant objects.
104  iterator begin();
105 
107  // Treat the array as one-dimensional.
108  // Version for non-constant objects.
109  iterator end();
110 
112  // Treat the array as one-dimensional.
113  // Version for constant objects.
114  const_iterator begin() const;
115 
117  // Treat the array as one-dimensional.
118  // Version for constant objects.
119  const_iterator end() const;
120 
121 
123  // Return pointer to beginning of row r.
124  // Throw RangeError, if row is out of range.
125  // Version for non-constant objects.
126  row_iterator row_begin(int r);
127 
129  // Return pointer past end of row r.
130  // Throw RangeError, if row is out of range.
131  // Version for non-constant objects.
132  row_iterator row_end(int r);
133 
135  // Return pointer to beginning of constant row r.
136  // Throws RangeError, if row is out of range.
137  // Version for constant objects.
138  const_row_iterator row_begin(int r) const;
139 
141  // Return pointer past end of constant row r.
142  // Throws RangeError, if row is out of range.
143  // Version for constant objects.
144  const_row_iterator row_end(int r) const;
145 
146 
148  // Return pointer to beginning of row r.
149  // Result is undefined, if r is out of range.
150  // Version for non-constant objects.
151  row_iterator operator[](int r);
152 
154  // Return pointer to beginning of row r.
155  // Result is undefined, if r is out of range.
156  // Version for constant objects.
157  const_row_iterator operator[](int r) const;
158 
159 
161  // Return pointer to beginning of column c.
162  // Throw RangeError if c is out of range.
163  // Version for non-constant objects.
164  col_iterator col_begin(int c);
165 
167  // Return pointer past end of column c.
168  // Throw RangeError if c is out of range.
169  // Version for non-constant objects.
170  col_iterator col_end(int c);
171 
173  // Return pointer to beginning of column c.
174  // Throw RangeError if c is out of range.
175  // Version for constant objects.
176  const_col_iterator col_begin(int c) const;
177 
179  // Return pointer past end of column c.
180  // Throw RangeError if c is out of range.
181  // Version for constant objects.
182  const_col_iterator col_end(int c) const;
183 
184 
186  // Store the column [b]c[/b] into the array [b]toArray[/b].
187  // Throw RangeError if c is out of range.
188  void getColumn(Array1D<T> &toArray, int c) const;
189 
191  // Store the row [b]r[/b] into the array [b]toArray[/b].
192  // Throw RangeError if r is out of range.
193  void getRow(Array1D<T> &toArray, int r) const;
194 
196  // Fill the column [b]c[/b] from the array [b]fromArray[/b].
197  // Throw RangeError if c is out of range.
198  void putColumn(const Array1D<T> &fromArray, int c);
199 
201  // Fill the row [b]r[/b] from the array [b]fromArray[/b].
202  // Throw RangeError if r is out of range.
203  void putRow(const Array1D<T> &fromArray, int r);
204 
206  // Exchange the columns [b]c1[/b] and [b]c2[/b].
207 
208 
209  // Throw RangeError, if either index is out of range.
210  void swapColumns(int c1, int c2);
211 
213  // Exchange the rows [b]r1[/b] and [b]r2[/b].
214  // Throw RangeError, if either index is out of range.
215  void swapRows(int row1, int row2);
216 
217 protected:
218 
219  // Array dimensions.
220  int rows;
221  int cols;
222  int len; // rows * cols
223 
224  // Array data.
225  T *data;
226 };
227 
228 
229 // Template implementation.
230 // ------------------------------------------------------------------------
231 
232 template <class T>
234  rows(0), cols(0), len(0), data(0)
235 {}
236 
237 
238 template <class T>
239 inline Array2D<T>::Array2D(const Array2D<T>& array):
240  rows(array.rows), cols(array.cols), len(array.len), data(new T[len]) {
241  std::copy(array.begin(), array.end(), begin());
242 }
243 
244 
245 template <class T>
246 inline Array2D<T>::Array2D(int r, int c):
247  rows(r), cols(c), len(r *c), data(new T[len])
248 {}
249 
250 
251 template <class T>
252 inline Array2D<T>::Array2D(int r, int c, const T &val):
253  rows(r), cols(c), len(r *c), data(new T[len]) {
254  std::fill(begin(), end(), val);
255 }
256 
257 
258 template <class T>
260  delete [] data;
261 }
262 
263 
264 template <class T>
266 
267 {
268  if(this != &rhs) {
269  if(rhs.len > len) {
270  delete [] data;
271  data = new T[rhs.len];
272  }
273  rows = rhs.rows;
274  cols = rhs.cols;
275  len = rhs.len;
276  std::copy(rhs.begin(), rhs.end(), begin());
277  }
278  return *this;
279 }
280 
281 
282 template <class T>
283 inline T &Array2D<T>::operator()(int r, int c) {
284  if(r < 0 || r >= rows || c < 0 || c >= ncols()) {
285  throw CLRangeError("Array2d::operator()", "Index out of range.");
286  }
287  return data[cols*r+c];
288 }
289 
290 
291 template <class T>
292 inline const T &Array2D<T>::operator()(int r, int c) const {
293  if(r < 0 || r >= rows || c < 0 || c >= ncols()) {
294  throw CLRangeError("Array2d::operator()", "Index out of range.");
295  }
296  return data[cols*r+c];
297 }
298 
299 
300 template <class T>
301 inline int Array2D<T>::nrows() const {
302  return rows;
303 }
304 
305 
306 template <class T>
307 inline int Array2D<T>::ncols() const {
308  return cols;
309 }
310 
311 
312 template <class T>
313 inline int Array2D<T>::size() const {
314  return len;
315 }
316 
317 
318 template <class T>
320  return data;
321 }
322 
323 
324 template <class T>
326  return data + len;
327 }
328 
329 
330 template <class T>
332  return data;
333 }
334 
335 
336 template <class T>
338  return data + len;
339 }
340 
341 
342 template <class T>
344  if(r >= rows) {
345  throw CLRangeError("Array2D::row_begin()", "Row index out of range.");
346  }
347  return &data[cols*r];
348 }
349 
350 
351 template <class T>
353  if(r >= rows) {
354  throw CLRangeError("Array2D::row_end()", "Row index out of range.");
355  }
356  return &data[cols*(r+1)];
357 }
358 
359 
360 template <class T>
362  if(r >= rows) {
363  throw CLRangeError("Array2D::row_begin()", "Row index out of range.");
364  }
365  return &data[cols*r];
366 }
367 
368 
369 template <class T>
371  if(r >= rows) {
372  throw CLRangeError("Array2D::row_end()", "Row index out of range.");
373  }
374  return &data[cols*(r+1)];
375 }
376 
377 
378 template <class T>
380  return &data[cols*r];
381 }
382 
383 
384 template <class T>
386  return &data[cols*r];
387 }
388 
389 
390 template <class T>
392  if(c >= cols) {
393  throw CLRangeError("Array2D::col_begin()", "Column index out of range.");
394  }
395  return col_iterator(data + c, cols);
396 }
397 
398 
399 template <class T>
401  if(c >= cols) {
402  throw CLRangeError("Array2D::col_end()", "Column index out of range.");
403  }
404  return col_iterator(data + len + c, cols);
405 }
406 
407 
408 template <class T>
410  if(c >= cols) {
411  throw CLRangeError("Array2D::col_begin()", "Column index out of range.");
412  }
413  return const_col_iterator(data + c, cols);
414 }
415 
416 
417 template <class T>
419  if(c >= cols) {
420  throw CLRangeError("Array2D::col_end()", "Column index out of range.");
421  }
422  return const_col_iterator(data + len + c, cols);
423 }
424 
425 
426 template <class T>
427 void Array2D<T>::getColumn(Array1D<T> &toArray, int c) const {
428  if(toArray.size() != rows) toArray = Array1D<T>(rows);
429  std::copy(col_begin(c), col_end(c), toArray.begin());
430 }
431 
432 
433 template <class T>
434 void Array2D<T>::getRow(Array1D<T> &toArray, int r) const {
435  if(toArray.size() != cols) toArray = Array1D<T>(cols);
436  std::copy(row_begin(r), row_end(r), toArray.begin());
437 }
438 
439 
440 template <class T>
441 void Array2D<T>::putColumn(const Array1D<T> &fromArray, int c) {
442  if(fromArray.size() != rows) {
443  throw SizeError("Array2D::putColumn()", "Dimensions inconsistent.");
444  }
445  std::copy(fromArray.begin(), fromArray.end(), col_begin(c));
446 }
447 
448 
449 template <class T>
450 void Array2D<T>::putRow(const Array1D<T> &fromArray, int r) {
451  if(fromArray.size() != cols) {
452  throw SizeError("Array2D::putRow()", "Dimensions inconsistent.");
453  }
454  std::copy(fromArray.begin(), fromArray.end(), row_begin(r));
455 }
456 
457 
458 template <class T>
459 void Array2D<T>::swapColumns(int col1, int col2) {
460  std::swap_ranges(col_begin(col1), col_end(col1), col_begin(col2));
461 }
462 
463 
464 template <class T>
465 void Array2D<T>::swapRows(int row1, int row2) {
466  std::swap_ranges(row_begin(row1), row_end(row1), row_begin(row2));
467 }
468 
469 
470 template <class T>
471 std::ostream &operator<<(std::ostream &os, const Array2D<T> &v) {
472  for(int i = 0; i < v.nrows(); ++i) {
473  for(int j = 0; j < v.ncols(); ++j) {
474  os << v(i, j) << " ";
475  }
476  os << std::endl;
477  }
478  return os;
479 }
480 
481 
482 #endif // CLASSIC_Array2D_HH
T * row_iterator
The iterator type for access by rows.
Definition: Array2D.h:55
void swapColumns(int c1, int c2)
Exchange columns.
Definition: Array2D.h:459
Array2D< T > & operator=(const Array2D< T > &)
Definition: Array2D.h:265
iterator begin()
Get pointer to beginning of data.
Definition: Array2D.h:319
int rows
Definition: Array2D.h:220
Iterator for array slice.
Definition: SliceIterator.h:32
Definition: rbendmap.h:8
col_iterator col_begin(int c)
Get column iterator.
Definition: Array2D.h:391
Size error exception.
Definition: SizeError.h:33
iterator end()
Get end of data.
Definition: Array1D.h:210
int ncols() const
Get number of columns.
Definition: Array2D.h:307
T * data
Definition: Array2D.h:225
col_iterator col_end(int c)
Get column iterator.
Definition: Array2D.h:400
int size() const
Get array size.
Definition: Array1D.h:228
const T * const_row_iterator
The iterator type for access by rows for a constant array.
Definition: Array2D.h:58
void putRow(const Array1D< T > &fromArray, int r)
Store row.
Definition: Array2D.h:450
T * iterator
The iterator type for sequential access to all elements.
Definition: Array2D.h:48
const T * const_iterator
The iterator type for sequential access to all elements.
Definition: Array2D.h:52
SliceIterator< T > col_iterator
The iterator type for access by columns.
Definition: Array2D.h:61
iterator begin()
Get beginning of data.
Definition: Array1D.h:204
T value_type
The value type of the array.
Definition: Array2D.h:45
Iterator for array slice.
int len
Definition: Array2D.h:222
Two-dimensional array.
Definition: Array2D.h:40
row_iterator row_begin(int r)
Get row iterator.
Definition: Array2D.h:343
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
void getColumn(Array1D< T > &toArray, int c) const
Fetch column.
Definition: Array2D.h:427
iterator end()
Get pointer past end of data.
Definition: Array2D.h:325
T & operator()(int r, int c)
Get element reference.
Definition: Array2D.h:283
~Array2D()
Definition: Array2D.h:259
int size() const
Get total size (rows times columns).
Definition: Array2D.h:313
int cols
Definition: Array2D.h:221
Range error.
Definition: CLRangeError.h:33
One-dimensional array.
Definition: Array1D.h:36
ConstSliceIterator< T > const_col_iterator
The iterator type for access by columns for a constant array.
Definition: Array2D.h:64
void getRow(Array1D< T > &toArray, int r) const
Fetch row.
Definition: Array2D.h:434
Array2D()
Default constructor.
Definition: Array2D.h:233
row_iterator row_end(int r)
Get row iterator.
Definition: Array2D.h:352
int nrows() const
Get number of rows.
Definition: Array2D.h:301
void swapRows(int row1, int row2)
Exchange rows.
Definition: Array2D.h:465
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
row_iterator operator[](int r)
Get row iterator.
Definition: Array2D.h:379
void putColumn(const Array1D< T > &fromArray, int c)
Store column.
Definition: Array2D.h:441