00001 #ifndef Array_H
00002 #define Array_H
00003
00023 #include <iterator>
00024
00025 #include <wds-debug.h>
00026
00027
00040
00041
00044 template <class T> class Array {
00045 public:
00048 explicit Array(const int size) :m_size(size) {
00049 assert(size > 0); m_data = new T[size];}
00053 Array(const int size, const T &value) :m_size(size) {
00054 assert(m_size > 0); m_data = new T[size];
00055 for(size_t i = 0; i < m_size; ++i) m_data[i] = value;}
00056 Array(const Array <T> &array) :m_size(array.m_size) {
00057 assert(m_size > 0); m_data = new T[m_size];
00058 for(size_t i = 0; i < m_size; ++i) m_data[i] = array.m_data[i];}
00059 ~Array() {delete [] m_data; invalidate_pointer(m_data);}
00060
00062
00063
00064
00068 Array <T> &operator=(const Array <T> &array) {
00069 if (m_size < array.m_size) {delete [] m_data; m_data = new T[array.m_size];}
00070 m_size = array.m_size;
00071 for(size_t i = 0; i < m_size; ++i) m_data[i] = array.m_data[i];
00072 return *this;}
00074
00076 Array <T> &operator=(const T &value) {
00077 for(size_t i = 0; i < m_size; ++i) m_data[i] = value;
00078 return *this;}
00080
00082
00083 typedef T value_type;
00084
00085 typedef value_type* pointer;
00086 typedef const value_type* const_pointer;
00087 typedef value_type& reference;
00088 typedef const value_type& const_reference;
00089
00090 typedef ptrdiff_t difference_type;
00091 typedef size_t size_type;
00092
00093 typedef pointer iterator;
00094 typedef const_pointer const_iterator;
00095
00096 iterator begin() {return m_data;}
00097 iterator end() {return m_data + m_size;}
00098
00099 const_iterator begin() const {return m_data;}
00100 const_iterator end() const {return m_data + m_size;}
00101
00102 typedef std::reverse_iterator<iterator> reverse_iterator;
00103 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00104
00105 reverse_iterator rbegin() {return reverse_iterator(end());}
00106 reverse_iterator rend() {return reverse_iterator(begin());}
00107
00108 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
00109 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
00111
00113
00114 reference operator[](const size_type index) {assert_range(index, 0, m_size); return m_data[index];}
00115 const_reference operator[](const size_type index) const {assert_range(index, 0, m_size); return m_data[index];}
00116
00117 reference operator()(const size_type index) {assert_range(index, 0, m_size); return m_data[index];}
00118 const_reference operator()(const size_type index) const {assert_range(index, 0, m_size); return m_data[index];}
00120
00122
00123 size_type size() const {return m_size;}
00125
00126 private:
00127 size_type m_size;
00128 T *m_data;
00129 };
00130
00131
00133
00136 template <class T> class Array2d {
00137 public:
00141 Array2d(const int rows, const int columns) :m_rows(rows), m_columns(columns) {
00142 assert(rows > 0); assert(columns > 0); m_data = new T[rows * columns];}
00147 Array2d(const int rows, const int columns, const T &value) :m_rows(rows), m_columns(columns) {
00148 assert(rows > 0); assert(columns > 0); m_data = new T[rows * columns];
00149 for(size_t i = 0; i < (rows * columns); ++i) m_data[i] = value;}
00150 Array2d(const Array2d <T> &array) :m_rows(array.m_rows), m_columns(array.m_columns) {
00151 assert(m_rows > 0); assert(m_columns > 0); m_data = new T[m_rows * m_columns];
00152 for(size_t i = 0; i < (m_rows * m_columns); ++i) m_data[i] = array.m_data[i];}
00153 ~Array2d() {delete [] m_data; invalidate_pointer(m_data);}
00154
00156
00157
00158
00162 Array2d <T> &operator=(const Array2d <T> &array) {
00163 if ((m_rows * m_columns) < (array.m_rows * array.m_columns)) {delete [] m_data; m_data = new T[array.m_rows * array.m_columns];}
00164 m_rows = array.m_rows; m_columns = array.m_columns;
00165 for(size_t i = 0; i < (m_rows * m_columns); ++i) m_data[i] = array.m_data[i];
00166 return *this;}
00168
00170 Array2d <T> &operator=(const T &value) {
00171 for(size_t i = 0; i < (m_rows * m_columns); ++i) m_data[i] = value;
00172 return *this;}
00174
00176
00177 typedef T value_type;
00178
00179 typedef value_type* pointer;
00180 typedef const value_type* const_pointer;
00181 typedef value_type& reference;
00182 typedef const value_type& const_reference;
00183
00184 typedef ptrdiff_t difference_type;
00185 typedef size_t size_type;
00186
00187 typedef pointer iterator;
00188 typedef const_pointer const_iterator;
00189
00190 iterator begin() {return m_data;}
00191 iterator end() {return m_data + (m_rows * m_columns);}
00192
00193 const_iterator begin() const {return m_data;}
00194 const_iterator end() const {return m_data + (m_rows * m_columns);}
00195
00196 typedef std::reverse_iterator<iterator> reverse_iterator;
00197 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00198
00199 reverse_iterator rbegin() {return reverse_iterator(end());}
00200 reverse_iterator rend() {return reverse_iterator(begin());}
00201
00202 const_reverse_iterator rbegin() const {return const_reverse_iterator(end());}
00203 const_reverse_iterator rend() const {return const_reverse_iterator(begin());}
00205
00207
00208 reference operator()(const size_type row, const size_type column) {
00209 assert_range(row, 0, m_rows); assert_range(column, 0, m_columns); return m_data[row * m_columns + column];}
00210 const_reference operator()(const size_type row, const size_type column) const {
00211 assert_range(row, 0, m_rows); assert_range(column, 0, m_columns); return m_data[row * m_columns + column];}
00213
00215
00216 size_type size() const {return (m_rows * m_columns);}
00217 size_type rows() const {return m_rows;}
00218 size_type columns() const {return m_columns;}
00220
00221 private:
00222 size_type m_rows;
00223 size_type m_columns;
00224 T *m_data;
00225 };
00226
00227
00229
00234 template <class T> class Ring : public Array <T> {
00235 public:
00236 explicit Ring(const int size) :Array <T> (size) {}
00237 Ring(const int size, const T &value) :Array <T> (size, value) {}
00238 Ring(const Ring <T> &ring) :Array <T> (ring) {}
00239 ~Ring() {}
00240
00241 using Array <T>::operator=;
00242
00244
00245 typedef T value_type;
00246
00247 typedef value_type* pointer;
00248 typedef const value_type* const_pointer;
00249 typedef value_type& reference;
00250 typedef const value_type& const_reference;
00251
00252 typedef ptrdiff_t difference_type;
00253 typedef size_t size_type;
00254
00255 typedef pointer iterator;
00256 typedef const_pointer const_iterator;
00257
00258 typedef std::reverse_iterator<iterator> reverse_iterator;
00259 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00261
00263
00264 reference operator[](const size_type index) {return Array<T>::operator[](wrap_index(index));}
00265 const_reference operator[](const size_type index) const {return Array<T>::operator[](wrap_index(index));}
00266
00267 reference operator()(const size_type index) {return Array<T>::operation()(wrap_index(index));}
00268 const_reference operator()(const size_type index) const {return Array<T>::operation()(wrap_index(index));}
00270
00271 using Array<T>::size;
00272
00273 private:
00274 int wrap_index(const int index) const {return ((index < 0)?(((index - 1) % size())):(index % size()));}
00275 };
00276
00277
00279
00284 template <class T> class Torus : public Array2d <T> {
00285 public:
00286 Torus(const int rows, const int columns) :Array2d <T> (rows, columns) {}
00287 Torus(const int rows, const int columns, const T &value) :Array2d <T> (rows, columns, value) {}
00288 Torus(const Torus <T> &torus) :Array2d <T> (torus) {}
00289 ~Torus() {}
00290
00291 using Array2d <T>::operator=;
00292
00294
00295 typedef T value_type;
00296
00297 typedef value_type* pointer;
00298 typedef const value_type* const_pointer;
00299 typedef value_type& reference;
00300 typedef const value_type& const_reference;
00301
00302 typedef ptrdiff_t difference_type;
00303 typedef size_t size_type;
00304
00305 typedef pointer iterator;
00306 typedef const_pointer const_iterator;
00307
00308 typedef std::reverse_iterator<iterator> reverse_iterator;
00309 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00311
00313
00314 reference operator()(const size_type row, const size_type column) {
00315 return Array2d<T>::operation()(wrap_index(row, rows()), wrap_index(columns, columns()));}
00316 const_reference operator()(const size_type row, const size_type column) const {
00317 return Array2d<T>::operation()(wrap_index(row, rows()), wrap_index(columns, columns()));}
00319
00320 using Array<T>::size;
00321 using Array<T>::rows;
00322 using Array<T>::columns;
00323
00324 private:
00325 int wrap_index(const int index, const int size) const {return ((index < 0)?(((index - 1) % size)):(index % size));}
00326 };
00327
00328 #endif