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