DUDS
Distributed Update of Data from Something
NddArray.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the DUDS project. It is subject to the BSD-style
3  * license terms in the LICENSE file found in the top-level directory of this
4  * distribution and at https://github.com/jjackowski/duds/blob/master/LICENSE.
5  * No part of DUDS, including this file, may be copied, modified, propagated,
6  * or distributed except according to the terms contained in the LICENSE file.
7  *
8  * Copyright (C) 2017 Jeff Jackowski
9  */
10 #ifndef NDDARRAY_HPP
11 #define NDDARRAY_HPP
12 
13 #include <vector>
14 #include <initializer_list>
15 #include <duds/general/Errors.hpp>
16 #include <boost/serialization/split_member.hpp>
17 #include <boost/serialization/nvp.hpp>
18 #include <boost/serialization/vector.hpp>
19 
20 namespace duds { namespace general {
21 
27 struct NddArrayError : virtual std::exception, virtual boost::exception { };
28 
33 
39 struct OutOfRangeError : NddArrayError /*, virtual std::out_of_range {
40  OutOfRangeError() : std::out_of_range("") { }
41 }; */ { };
42 
47 
52 
86 template <class T>
87 class NddArray {
88 public:
92  typedef std::size_t SizeType;
96  typedef std::vector<SizeType> DimVec;
101  typedef std::initializer_list<SizeType> DimList;
105  typedef T* iterator;
109  typedef const T* const_iterator;
110 private:
114  DimVec dsize;
118  T *array;
122  SizeType elems;
136  void makeArray() {
137  // work out the total number of elements
138  DimVec::const_iterator iter = dsize.begin();
139  elems = *(iter++);
140  while (iter != dsize.end()) {
141  elems *= *(iter++);
142  }
143  // check for a zero-size dimension
144  if (!elems) {
145  array = nullptr;
146  dsize.clear();
148  }
149  // allocate memory
150  array = new T[elems];
151  }
164  void copyElements(const NddArray &src) {
165  // is there something to copy?
166  if (elems) {
167  // would be nice if constructors could be avoided here and the copy
168  // constructor used instead of assignment in the first loop below
169  array = new T[elems];
170  T *t = array, *ot = src.array;
171  try {
172  // assign each element
173  for (SizeType i = elems; i > 0; --i, ++t, ++ot) {
174  *t = *ot;
175  }
176  } catch (...) {
177  // dismantle what has been built
178  clear();
179  throw;
180  }
181  } else {
182  // source is empty; array pointer could be anything
183  array = nullptr;
184  }
185  }
201  template <class Dim>
202  const T &indexArray(const Dim &pos) const {
203  // cannot index into an array with zero dimensions
204  if (dsize.empty()) {
206  }
207  // the position must have as many items as dimensions in the array
208  if (pos.size() != dsize.size()) {
210  }
211  typename Dim::const_iterator p = pos.begin();
212  DimVec::const_iterator d = dsize.begin();
213  SizeType index = 0, step = 1;
214  do {
215  // range check
216  if (*p >= *d) {
218  }
219  // advance index
220  index += *p * step;
221  // compute number of items to skip per unit in the next dimension
222  step *= *d;
223  // next position & dimension
224  ++p;
225  ++d;
226  } while (d != dsize.end());
227  // send back the requested elenent
228  return array[index];
229  }
230 public:
235  NddArray() : array(nullptr), elems(0) { }
240  NddArray(const DimList &dims) : dsize(dims) {
241  if (dims.size() > 0) {
242  makeArray();
243  }
244  }
249  NddArray(const DimVec &dims) : dsize(dims) {
250  if (!dims.empty()) {
251  makeArray();
252  }
253  }
260  template <class Dim>
261  NddArray(const Dim &dims) : dsize(dims.first(), dims.last()) {
262  if (!dsize.empty()) {
263  makeArray();
264  }
265  }
272  NddArray(const NddArray &ndda) : elems(ndda.elems), dsize(ndda.dsize) {
273  copyElements(ndda);
274  }
284  NddArray(NddArray &&ndda) noexcept :
285  elems(ndda.elems), dsize(std::move(ndda.dsize)) {
286  array = ndda.array;
287  ndda.array = nullptr;
288  ndda.elems = 0;
289  }
293  ~NddArray() noexcept {
294  clear();
295  }
304  NddArray &operator=(const NddArray &ndda) {
305  dsize = ndda.dsize;
306  elems = ndda.elems;
307  delete [] array;
308  copyElements(ndda);
309  return *this;
310  }
318  NddArray &operator=(NddArray &&ndda) noexcept {
319  elems = ndda.elems;
320  dsize = std::move(ndda.dsize);
321  delete [] array;
322  array = ndda.array;
323  ndda.array = nullptr;
324  ndda.elems = 0;
325  return *this;
326  }
339  template <class AV>
340  void copyFrom(const AV &av) {
341  // size the array to match the array/vector
342  remake({av.size()});
343  // copy elements
344  T *dest = array;
345  typename AV::const_iterator src = av.begin();
346  for (; src != av.end(); ++src, ++dest) {
347  *dest = *src;
348  }
349  }
362  template <std::size_t N>
363  void copyFrom(const std::array<T, N> &a) {
364  copyFrom< std::array< T, N > >(a);
365  }
377  void copyFrom(const std::vector<T> &v) {
378  copyFrom< std::vector< T > >(v);
379  }
392  template <std::size_t N>
393  void copyFrom(const T (&a)[N]) {
394  // size the array to match the array
395  remake({N});
396  // copy elements
397  T *dest = array;
398  const T *src = a;
399  for (std::size_t loop = N; loop; ++src, ++dest, --loop) {
400  *dest = *src;
401  }
402  }
416  template <std::size_t X, std::size_t Y>
417  void copyFrom(const T (&a)[X][Y]) {
418  // size the array to match the array
419  remake({X,Y});
420  // copy elements
421  T *dest = array;
422  std::size_t x, y = 0;
423  for (; y < Y; ++y) {
424  for (x = 0; x < X; ++dest, ++x) {
425  *dest = a[x][y];
426  }
427  }
428  }
441  template <std::size_t N>
442  NddArray &operator=(const std::array<T, N> &a) {
443  copyFrom< std::array< T, N > >(a);
444  return *this;
445  }
457  NddArray &operator=(const std::vector<T> &v) {
458  copyFrom< std::vector< T > >(v);
459  return *this;
460  }
473  template <std::size_t N>
474  NddArray &operator=(const T (&a)[N]) {
475  copyFrom<N>(a);
476  return *this;
477  }
491  template <std::size_t X, std::size_t Y>
492  NddArray &operator=(const T (&a)[X][Y]) {
493  copyFrom<X,Y>(a);
494  return *this;
495  }
509  template <std::size_t N>
510  void copyTo(std::array<T, N> &a) const {
511  // must be exactly one dimension
512  if (dsize.size() != 1) {
514  }
515  // copy elements
516  const T *src = array;
517  typename std::array<T, N>::iterator i = a.begin();
518  std::size_t loop = std::min(elems, a.size());
519  for (; loop; ++i, ++src, --loop) {
520  *i = *src;
521  }
522  }
532  void copyTo(std::vector<T> &v) const {
533  // must be exactly one dimension
534  if (dsize.size() != 1) {
536  }
537  // resize the vector to match
538  v.resize(elems);
539  // copy elements
540  const T *src = array;
541  typename std::vector<T>::iterator i = v.begin();
542  for (; i != v.end(); ++i, ++src) {
543  *i = *src;
544  }
545  }
559  template <std::size_t N>
560  void copyTo(T (&a)[N]) const {
561  // must be exactly one dimension
562  if (dsize.size() != 1) {
564  }
565  // copy elements
566  const T *src = array;
567  T *dest = a;
568  std::size_t loop = std::min(elems, N);
569  for (; loop; ++dest, ++src, --loop) {
570  *dest = *src;
571  }
572  }
586  template <std::size_t X, std::size_t Y>
587  void copyTo(T (&a)[X][Y]) const {
588  // must be exactly two dimensions
589  if (dsize.size() != 2) {
591  }
592  // copy elements
593  const T *src;
594  const std::size_t xs = std::min(X, dsize[0]);
595  const std::size_t ys = std::min(Y, dsize[1]);
596  std::size_t x, y = 0;
597  for (; y < ys; ++y) {
598  src = &at({0,y});
599  for (x = 0; x < xs; ++src, ++x) {
600  a[x][y] = *src;
601  }
602  }
603  }
616  template <class Dim>
617  T &operator()(const Dim &pos) {
618  // remove the const specifier from the return value of indexArray()
619  // to avoid writing the function twice
620  return const_cast<T&>(indexArray(pos));
621  }
632  T &operator()(const DimList &pos) {
633  // remove the const specifier from the return value of indexArray()
634  // to avoid writing the function twice
635  return const_cast<T&>(indexArray<DimList>(pos));
636  }
649  template <class Dim>
650  const T &operator()(const Dim &pos) const {
651  return indexArray(pos);
652  }
663  const T &operator()(const DimList &pos) const {
664  return indexArray<DimList>(pos);
665  }
678  template <class Dim>
679  T &at(const Dim &pos) {
680  // remove the const specifier from the return value of indexArray()
681  // to avoid writing the function twice
682  return const_cast<T&>(indexArray(pos));
683  }
694  T &at(const DimList &pos) {
695  // remove the const specifier from the return value of indexArray()
696  // to avoid writing the function twice
697  return const_cast<T&>(indexArray<DimList>(pos));
698  }
711  template <class Dim>
712  const T &at(const Dim &pos) const {
713  return indexArray(pos);
714  }
725  const T &at(const DimList &pos) const {
726  return indexArray<DimList>(pos);
727  }
733  T &front() {
734  if (!array) {
736  }
737  return *array;
738  }
744  const T &front() const {
745  if (!array) {
747  }
748  return *array;
749  }
756  T &back() {
757  if (!array) {
759  }
760  return array[elems - 1];
761  }
768  const T &back() const {
769  if (!array) {
771  }
772  return array[elems - 1];
773  }
783  T *begin() {
784  return array;
785  }
795  const T *begin() const {
796  return array;
797  }
807  const T *cbegin() const {
808  return array;
809  }
820  T *end() {
821  return array + elems;
822  }
833  const T *end() const {
834  return array + elems;
835  }
846  const T *cend() const {
847  return array + elems;
848  }
854  bool operator==(const NddArray &ndda) const {
855  // check dimensions
856  if ((elems != ndda.elems) || (dsize != ndda.dsize)) {
857  return false;
858  }
859  // same dimensions; check array elements
860  T *t = array, *o = ndda.array;
861  for (SizeType i = elems; i; --i, ++t, ++o) {
862  if (!(*t == *o)) {
863  return false;
864  }
865  }
866  // everything matches
867  return true;
868  }
874  bool operator!=(const NddArray &ndda) const {
875  // check dimensions
876  if ((elems != ndda.elems) || (dsize != ndda.dsize)) {
877  return true;
878  }
879  // same dimensions; check array elements
880  T *t = array, *o = ndda.array;
881  for (SizeType i = elems; i; --i, ++t, ++o) {
882  if (*t != *o) {
883  return true;
884  }
885  }
886  // everything matches
887  return false;
888  }
892  SizeType numdims() const {
893  return dsize.size();
894  }
901  SizeType dim(SizeType n) const {
902  if (n >= dsize.size()) {
904  }
905  return dsize[n];
906  }
910  const DimVec &dim() const {
911  return dsize;
912  }
917  SizeType numelems() const {
918  return elems;
919  }
923  bool empty() const {
924  return !array;
925  }
934  void clear() noexcept { // destructors must never throw
935  delete [] array;
936  array = nullptr;
937  dsize.clear();
938  elems = 0;
939  }
948  void remake(const DimList &dims) {
949  // no dimensions?
950  if (dims.size() == 0) {
951  // be empty
952  clear();
953  return;
954  }
955  // destroy existing elements
956  delete [] array;
957  // store new dimensions
958  dsize = dims;
959  // make stuff
960  makeArray();
961  }
970  void remake(const DimVec &dims) {
971  // no dimensions?
972  if (dims.empty()) {
973  // be empty
974  clear();
975  return;
976  }
977  // destroy existing elements
978  delete [] array;
979  // store new dimensions
980  dsize = dims;
981  // make stuff
982  makeArray();
983  }
998  template <class Dim>
999  NddArray makeWithNewSize(const Dim &dims) const {
1000  // no dimensions in new size?
1001  if (dims.size() == 0) {
1002  // empty
1003  return NddArray();
1004  }
1005  // no dimensions in current size?
1006  if (!array) {
1007  // make array of given size
1008  return NddArray(dims);
1009  }
1010  // new array for the new size
1011  NddArray na(dims); // may throw EmptyDimensionError
1012  // union of source & destination dimensions
1013  DimVec uniondim(std::min(dsize.size(), dims.size()));
1014  typename Dim::const_iterator diter = dims.begin();
1015  SizeType idx = 0; // dimension index
1016  do {
1017  // Find the length covered by old & new size. The result will be
1018  // greater than zero. If any length was zero, the construction of na
1019  // above threw an exception, so no need to check here.
1020  uniondim[idx] = (std::min(dsize[idx], *diter));
1021  ++diter;
1022  } while (++idx < uniondim.size());
1023  idx = 0;
1024  // position vectors for source & destination
1025  DimVec spos(numdims(), 0), dpos(na.numdims());
1026  // pointers to inside the arrays
1027  const T *sitm = array; // source
1028  T *ditm = na.array; // destination
1029  // loop to copy
1030  do {
1031  // copy element; first element can always be copied
1032  *ditm = *sitm;
1033  // loop to advance position
1034  do {
1035  // next position
1036  spos[idx] += 1;
1037  // check range on this dimension
1038  if (spos[idx] >= uniondim[idx]) {
1039  // went beyond; go back to start of this dimension
1040  spos[idx] = 0;
1041  } else {
1042  // in bounds; use this position
1043  break;
1044  }
1045  } while (++idx < uniondim.size());
1046  // modified 1st dimension only?
1047  if (!idx) {
1048  // The next element is the next in the 1D storage array. Advance
1049  // the pointers to quickly get to the next element.
1050  ++sitm;
1051  ++ditm;
1052  // modified more than one dimension in the position?
1053  } else if (idx < uniondim.size()) {
1054  // next time, start position advance at 1st dimension
1055  idx = 0;
1056  // new source address
1057  sitm = &at(spos);
1058  // set new destination position
1059  dpos = spos;
1060  dpos.resize(na.numdims());
1061  // new destination address
1062  ditm = &na.at(dpos);
1063  // modified all dimensions to zero?
1064  } else {
1065  // all done
1066  break;
1067  }
1068  } while (true);
1069  // return the new array
1070  return na;
1071  }
1086  NddArray makeWithNewSize(const DimList &dims) const {
1087  return makeWithNewSize<DimList>(dims);
1088  }
1110  template <class Dim>
1111  void resize(const Dim &dims) {
1112  *this = std::move(makeWithNewSize(dims));
1113  }
1135  void resize(const DimList &dims) {
1136  *this = std::move(makeWithNewSize<DimList>(dims));
1137  }
1141  SizeType size() const {
1142  return elems;
1143  }
1151  void swap(NddArray &other) {
1152  dsize.swap(other.dsize);
1153  std::swap(array, other.array);
1154  std::swap(elems, other.elems);
1155  };
1156 private:
1157  // serialization support
1158  friend class boost::serialization::access;
1159  BOOST_SERIALIZATION_SPLIT_MEMBER();
1163  template <class A>
1164  void save(A &a, const unsigned int) const {
1165  // store the dimensions
1166  a & BOOST_SERIALIZATION_NVP(dsize);
1167  // store more only if not empty
1168  if (!dsize.empty()) {
1169  // write out elements
1170  const T *t = array;
1171  for (SizeType i = elems; i > 0; --i, ++t) {
1172  a & boost::serialization::make_nvp("item", *t);
1173  }
1174  }
1175  }
1179  template <class A>
1180  void load(A &a, const unsigned int) {
1181  // destroy existing contents
1182  if (array) {
1183  clear();
1184  }
1185  // recover the dimensions
1186  a & BOOST_SERIALIZATION_NVP(dsize);
1187  // there is only more if the array isn't empty
1188  if (!dsize.empty()) {
1189  try {
1190  // allocate space
1191  makeArray();
1192  // read in elements
1193  T *t = array;
1194  for (SizeType i = elems; i > 0; --i, ++t) {
1195  a & boost::serialization::make_nvp("item", *t);
1196  }
1197  } catch (...) {
1198  // not sure if this is needed
1199  clear();
1200  throw;
1201  }
1202  }
1203  }
1204 };
1205 
1210 template <class T>
1211 void swap(NddArray<T> &one, NddArray<T> &two) {
1212  one.swap(two);
1213 }
1214 
1215 } }
1216 
1217 #endif // #ifndef NDDARRAY_HPP
1218 
T & front()
The first element of the array.
Definition: NddArray.hpp:733
void copyFrom(const T(&a)[X][Y])
Copies from a two dimensional array type into this array object.
Definition: NddArray.hpp:417
void makeArray()
Computes the new total number of elements and allocates space for the elements.
Definition: NddArray.hpp:136
void copyTo(T(&a)[N]) const
Copies the contents of this object into a one dimensional array.
Definition: NddArray.hpp:560
void swap(NddArray &other)
Swaps array contents.
Definition: NddArray.hpp:1151
N-Dimensional Dynamic Array.
Definition: NddArray.hpp:87
NddArray makeWithNewSize(const DimList &dims) const
Makes a new array with a new size and copies elements who&#39;s position is within bounds of the new arra...
Definition: NddArray.hpp:1086
NddArray makeWithNewSize(const Dim &dims) const
Makes a new array with a new size and copies elements who&#39;s position is within bounds of the new arra...
Definition: NddArray.hpp:999
NddArray & operator=(const NddArray &ndda)
Copy assignment; uses the assignment operator of T.
Definition: NddArray.hpp:304
const T & indexArray(const Dim &pos) const
Finds the location in array that holds the element for the given n-dimensional array position and ret...
Definition: NddArray.hpp:202
const T & operator()(const DimList &pos) const
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:663
NddArray(const DimVec &dims)
Makes an array of the given size.
Definition: NddArray.hpp:249
DimVec dsize
The lengths of each dimension within the array.
Definition: NddArray.hpp:114
void swap(NddArray< T > &one, NddArray< T > &two)
Makes NddAray meet the requirements of Swappable to assist in using std::swap().
Definition: NddArray.hpp:1211
void clear() noexcept
Destroys the contents of the array.
Definition: NddArray.hpp:934
T & back()
The last element of the array.
Definition: NddArray.hpp:756
SizeType numelems() const
Returns the total number of elements within the array.
Definition: NddArray.hpp:917
move_impl move(unsigned int c, unsigned int r)
Display stream manipulator that moves the display cursor to the given location.
void copyTo(std::array< T, N > &a) const
Copies the contents of this object into a std::array.
Definition: NddArray.hpp:510
NddArray(NddArray &&ndda) noexcept
Move constructor; the elements are not copied.
Definition: NddArray.hpp:284
SizeType dim(SizeType n) const
Returns the size of dimension n.
Definition: NddArray.hpp:901
std::initializer_list< SizeType > DimList
A type that can specify the dimensions of the array, or a position of an element. ...
Definition: NddArray.hpp:101
T * array
The array&#39;s element storage.
Definition: NddArray.hpp:118
SizeType numdims() const
Returns the number of dimensions in the array.
Definition: NddArray.hpp:892
void load(A &a, const unsigned int)
Boost serialization support.
Definition: NddArray.hpp:1180
Base class for exceptions thrown by NddArray.
Definition: NddArray.hpp:27
T & operator()(const Dim &pos)
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:617
void copyTo(T(&a)[X][Y]) const
Copies the contents of this object into a two dimensional array.
Definition: NddArray.hpp:587
std::vector< SizeType > DimVec
The type used to store the dimensions of the array.
Definition: NddArray.hpp:96
bool empty() const
True if the array has zero dimensions.
Definition: NddArray.hpp:923
void copyFrom(const T(&a)[N])
Copies from a one dimensional array type into this array object.
Definition: NddArray.hpp:393
const T & back() const
The last element of the array.
Definition: NddArray.hpp:768
A specified dimension is beyond the range of the array.
Definition: NddArray.hpp:39
T & at(const Dim &pos)
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:679
const T * cend() const
An iterator (really just a pointer) to one past the last element of the array.
Definition: NddArray.hpp:846
void copyFrom(const AV &av)
Copies from a one dimensional container into this array.
Definition: NddArray.hpp:340
std::size_t SizeType
The type used to store dimension lengths and the total number of elements.
Definition: NddArray.hpp:92
NddArray & operator=(NddArray &&ndda) noexcept
Move assignment; the elements are not copied.
Definition: NddArray.hpp:318
An empty array, one with zero dimensions, cannot be indexed.
Definition: NddArray.hpp:51
void remake(const DimList &dims)
Clears the array and allocates a new one of the given dimensions.
Definition: NddArray.hpp:948
void copyFrom(const std::array< T, N > &a)
Copies from a std::array into this array.
Definition: NddArray.hpp:363
NddArray(const DimList &dims)
Makes an array of the given size.
Definition: NddArray.hpp:240
std::basic_ostream< Char, Traits > & clear(std::basic_ostream< Char, Traits > &os)
Display stream manipulator that clears all text from the display and places the cursor in the upper l...
T * begin()
An iterator (really just a pointer) to the first element of the array.
Definition: NddArray.hpp:783
void copyElements(const NddArray &src)
Alloactes space for and copies the elements of the array.
Definition: NddArray.hpp:164
void save(A &a, const unsigned int) const
Boost serialization support.
Definition: NddArray.hpp:1164
NddArray()
Makes an empty array.
Definition: NddArray.hpp:235
SizeType size() const
Returns the number of elements stored in the array.
Definition: NddArray.hpp:1141
const T * end() const
An iterator (really just a pointer) to one past the last element of the array.
Definition: NddArray.hpp:833
NddArray(const NddArray &ndda)
Copy constructor; uses the assignment operator of T.
Definition: NddArray.hpp:272
void resize(const DimList &dims)
Resizes the array and keeps elements who&#39;s position is within bounds of the new dimensions.
Definition: NddArray.hpp:1135
T & operator()(const DimList &pos)
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:632
bool operator!=(const NddArray &ndda) const
Inequality operator; uses the inequality operator of T.
Definition: NddArray.hpp:874
void remake(const DimVec &dims)
Clears the array and allocates a new one of the given dimensions.
Definition: NddArray.hpp:970
const DimVec & dim() const
Provides access to the vector containing the array dimensions.
Definition: NddArray.hpp:910
T & at(const DimList &pos)
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:694
NddArray & operator=(const std::vector< T > &v)
Copies from a std::vector into this array.
Definition: NddArray.hpp:457
NddArray & operator=(const T(&a)[N])
Copies from a one dimensional array type into this array object.
Definition: NddArray.hpp:474
~NddArray() noexcept
Destructor; destroys the elements of the array.
Definition: NddArray.hpp:293
void resize(const Dim &dims)
Resizes the array and keeps elements who&#39;s position is within bounds of the new dimensions.
Definition: NddArray.hpp:1111
const T & operator()(const Dim &pos) const
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:650
const T & at(const Dim &pos) const
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:712
NddArray(const Dim &dims)
Makes an array of the given size.
Definition: NddArray.hpp:261
void copyTo(std::vector< T > &v) const
Copies the contents of this object into a std::vector.
Definition: NddArray.hpp:532
T * end()
An iterator (really just a pointer) to one past the last element of the array.
Definition: NddArray.hpp:820
General errors.
const T & at(const DimList &pos) const
Obtain an element from the array stored at a specific position.
Definition: NddArray.hpp:725
const T * begin() const
An iterator (really just a pointer) to the first element of the array.
Definition: NddArray.hpp:795
bool operator==(const NddArray &ndda) const
Equality operator; uses the equality operator of T.
Definition: NddArray.hpp:854
NddArray & operator=(const std::array< T, N > &a)
Copies from a std::array into this array.
Definition: NddArray.hpp:442
#define DUDS_THROW_EXCEPTION(x)
Works like BOOST_THROW_EXCEPTION, but includes a stack trace if DUDS_ERRORS_VERBOSE is defined...
Definition: Errors.hpp:48
A specified position has a different number of dimensions than the array.
Definition: NddArray.hpp:46
A specified dimension is zero.
Definition: NddArray.hpp:32
SizeType elems
Total number of elements; pre-calculated to speed up some operations.
Definition: NddArray.hpp:122
NddArray & operator=(const T(&a)[X][Y])
Copies from a two dimensional array type into this array object.
Definition: NddArray.hpp:492
void copyFrom(const std::vector< T > &v)
Copies from a std::vector into this array.
Definition: NddArray.hpp:377
const T & front() const
The first element of the array.
Definition: NddArray.hpp:744
const T * cbegin() const
An iterator (really just a pointer) to the first element of the array.
Definition: NddArray.hpp:807
const T * const_iterator
Simple const iterator.
Definition: NddArray.hpp:109
T * iterator
Simple iterator.
Definition: NddArray.hpp:105