Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Array2D.hh
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003-2009 (see file CONTACT for details)
4  Multimediale Systeme der Informationsverarbeitung
5  Institut fuer Informatik
6  Christian-Albrechts-Universitaet Kiel
7 
8 
9  BIAS is free software; you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation; either version 2.1 of the License, or
12  (at your option) any later version.
13 
14  BIAS is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with BIAS; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
22 #ifndef __Array2D_hh__
23 #define __Array2D_hh__
24 
25 #include <bias_config.h>
26 
27 #include <Base/Debug/Exception.hh>
28 
29 namespace BIAS {
30 
31  template <class T> class Array2D;
32 
33  template <class T>
34  std::ostream &operator<<(std::ostream& os, const Array2D<T> &arg);
35 
36  /** @class Array2D
37  @brief generic two dimensional rectangular array holding arbitrary data
38  types
39  @test tested with TestArray2D.cpp
40  The syntax of the access functions is kept similar to the stl:: classes
41 
42  @author woelk 09/2007 (c) www.vision-n.de */
43  template <class T>
44  class Array2D
45  {
46  public:
47  Array2D();
48 
49  Array2D(const unsigned nrows, const unsigned ncols);
50 
51  // copy constructor
52  Array2D(const Array2D<T>& m);
53 
54  ~Array2D();
55 
56  /// copy operator
57  Array2D<T>& operator=(const Array2D<T>& m);
58 
59  /// frees the memory
60  void clear();
61 
62  /// preserves the content
63  void resize(const unsigned nrows, const unsigned ncols);
64 
65  bool empty() const
66  { return (Data_==0); }
67 
68  /// fills the array with val
69  void fill(const T& val);
70 
71  unsigned ncols() const { return Ncols_; }
72 
73  unsigned nrows() const { return Nrows_; }
74 
75  unsigned size() const { return Nrows_ * Ncols_; }
76 
77  /// checked element access
78  T& operator()(const unsigned row, const unsigned col);
79  const T& operator()(const unsigned row, const unsigned col) const;
80 
81  /// unchecked element access
82  T* operator[](const unsigned row) { return &(Data_[row*Ncols_]); }
83  const T* operator[](const unsigned row) const
84  { return &(Data_[row*Ncols_]); }
85 
86  class const_iterator;
87 
88  /// for iterator access
89  /// todo: derive from std::iterator class(es)
90  class iterator
91  {
92  public:
93  inline iterator() : Val_(0) {}
94  inline iterator(const iterator& it) : Val_(it.Val_) {}
95  inline ~iterator() {}
96  inline T& operator*() { return *Val_; }
97  inline T* operator->() { return Val_; }
98  inline iterator operator++(int) { Val_++; return *this; }
99  inline bool operator==(const iterator& it) { return (Val_ == it.Val_); }
100  inline bool operator!=(const iterator& it) { return (Val_ != it.Val_); }
101  inline iterator& operator=(const iterator& it)
102  { Val_ = it.Val_; return *this; }
103 
104  friend class Array2D;
105  friend class const_iterator;
106  private:
107  T *Val_;
108  inline iterator(T *t) : Val_(t) {}
109  };
110 
111  /// for const_iterator access
112  /// todo: derive from std::iterator class(es)
114  {
115  public:
116  inline const_iterator() : Val_(0) {}
117  inline const_iterator(const iterator& it) : Val_(it.Val_) {}
118  inline const_iterator(const const_iterator& it) : Val_(it.Val_) {}
119  inline ~const_iterator() {}
120  inline const T& operator*() { return *Val_; }
121  inline const T* operator->() { return Val_; }
122  inline const_iterator operator++(int) { Val_++; return *this; }
123  inline bool operator==(const const_iterator& it)
124  { return (Val_ == it.Val_); }
125  inline bool operator!=(const const_iterator& it)
126  { return (Val_ != it.Val_); }
128  { Val_ = it.Val_; return *this; }
129 
130  friend class Array2D;
131  private:
132  const T *Val_;
133  inline const_iterator(T *t) : Val_(t) {}
134  };
135 
136  const_iterator begin() const { return const_iterator(Data_); }
138  { return const_iterator(Data_+(Nrows_*Ncols_)); }
139  iterator begin() { return iterator(Data_); }
140  iterator end() { return iterator(Data_+(Nrows_*Ncols_)); }
141 
142  private:
143  T* Data_;
144  unsigned Nrows_, Ncols_;
145  };
146 
147  /////////////////////////////////////////////////////////////////
148  // implementation
149  /////////////////////////////////////////////////////////////////
150 
151  template <class T>
153  : Data_(0), Nrows_ (0), Ncols_ (0)
154  {}
155 
156 
157  template <class T>
158  Array2D<T>::Array2D(const unsigned nrows, const unsigned ncols)
159  : Data_(new T[nrows * ncols]), Nrows_ (nrows), Ncols_ (ncols)
160  {
161  if (nrows == 0 || ncols == 0)
162  BEXCEPTION("invalid size in Arra2D "<<nrows<<"x"<<ncols);
163  }
164 
165 
166  template <class T>
168  : Data_(0), Nrows_ (0), Ncols_(0)
169  { *this = m; }
170 
171 
172  template <class T>
174  { clear(); }
175 
176 
177  template<class T>
179  {
180  // if (m.Data_ == Data_) {
181 // BEXCEPTION("self assignement");
182 // }
183  // this indirection is necessary to be able to cope with self assignement
184  const int size = m.Ncols_*m.Nrows_;
185  T *tmp = new T[size];
186  // do not use memcopy here: memcopy cannot cope with complex objects
187  // allocating memory themselve
188  for (int i=0; i<size; i++){ tmp[i] = m.Data_[i]; }
189  if (!empty()) { clear(); }
190  Data_ = tmp;
191  Nrows_ = m.Nrows_;
192  Ncols_ = m.Ncols_;
193  return *this;
194  }
195 
196 
197  template<class T>
199  { if (Data_){ delete[] Data_; Data_ = 0; Ncols_ = Nrows_ = 0; } }
200 
201 
202  template<class T>
203  void Array2D<T>::resize(const unsigned nrows, const unsigned ncols)
204  {
205  if (nrows==Nrows_ && ncols==Ncols_) return;
206  T *tmp = new T[nrows*ncols];
207  if (Data_){
208  // preserve existing data
209  const unsigned nr=Nrows_, nc=Ncols_;
210  unsigned r, c, tmp_offs, old_offs;
211  for (r=0; r<nr; r++){
212  tmp_offs = r*ncols;
213  old_offs = r*nc;
214  for (c=0; c<nc; c++){
215  tmp[tmp_offs+c] = Data_[old_offs+c];
216  }
217  }
218  delete[] Data_;
219  }
220  Data_ = tmp;
221  Nrows_ = nrows;
222  Ncols_ = ncols;
223  }
224 
225 
226  template<class T>
227  void Array2D<T>::fill(const T& val)
228  {
229  const unsigned nr=Nrows_, nc=Ncols_;
230  unsigned r, c, offs;
231  for (r=0; r<nr; r++){
232  offs = r*nc;
233  for (c=0; c<nc; c++){
234  Data_[offs+c] = val;
235  }
236  }
237  }
238 
239 
240  template<class T>
241  T& Array2D<T>::operator()(const unsigned row, const unsigned col)
242  {
243  if (row >= Nrows_ || col >= Ncols_)
244  BEXCEPTION("index out of bounds: array2D size = "<<Ncols_<<"x"<<Nrows_
245  <<" and index access at ["<<row<<"]["<<col<<"]");
246  return Data_[row*Ncols_ + col];
247  }
248 
249 
250  template<class T>
251  const T& Array2D<T>::operator()(const unsigned row, const unsigned col) const
252  {
253  if (row >= Nrows_ || col >= Ncols_)
254  BEXCEPTION("index out of bounds: array2D size = "<<Ncols_<<"x"<<Nrows_
255  <<" and index access at ["<<row<<"]["<<col<<"]");
256  return Data_[row*Ncols_ + col];
257  }
258 
259  template <class T>
260  std::ostream &operator<<(std::ostream& os, const Array2D<T> &arg)
261  {
262  os << arg.nrows() << " " << arg.ncols() << std::endl;
263  for (unsigned r=0; r<arg.nrows(); r++){
264  for (unsigned c=0; c<arg.ncols(); c++){
265  os << arg(r,c) << "\t";
266  }
267  os << std::endl;
268  }
269  return os;
270  }
271 
272 
273 
274 } // namespace
275 
276 #endif
iterator(const iterator &it)
Definition: Array2D.hh:94
for const_iterator access todo: derive from std::iterator class(es)
Definition: Array2D.hh:113
void clear()
frees the memory
Definition: Array2D.hh:198
Array2D< T > & operator=(const Array2D< T > &m)
copy operator
Definition: Array2D.hh:178
T * operator[](const unsigned row)
unchecked element access
Definition: Array2D.hh:82
generic two dimensional rectangular array holding arbitrary data types
Definition: Array2D.hh:31
T & operator()(const unsigned row, const unsigned col)
checked element access
Definition: Array2D.hh:241
unsigned ncols() const
Definition: Array2D.hh:71
iterator begin()
Definition: Array2D.hh:139
bool operator!=(const iterator &it)
Definition: Array2D.hh:100
iterator end()
Definition: Array2D.hh:140
for iterator access todo: derive from std::iterator class(es)
Definition: Array2D.hh:90
bool operator==(const const_iterator &it)
Definition: Array2D.hh:123
const_iterator operator++(int)
Definition: Array2D.hh:122
unsigned size() const
Definition: Array2D.hh:75
void resize(const unsigned nrows, const unsigned ncols)
preserves the content
Definition: Array2D.hh:203
iterator operator++(int)
Definition: Array2D.hh:98
const_iterator end() const
Definition: Array2D.hh:137
const_iterator(const const_iterator &it)
Definition: Array2D.hh:118
const_iterator & operator=(const const_iterator &it)
Definition: Array2D.hh:127
bool operator==(const iterator &it)
Definition: Array2D.hh:99
const_iterator(const iterator &it)
Definition: Array2D.hh:117
unsigned nrows() const
Definition: Array2D.hh:73
bool empty() const
Definition: Array2D.hh:65
void fill(const T &val)
fills the array with val
Definition: Array2D.hh:227
iterator & operator=(const iterator &it)
Definition: Array2D.hh:101
bool operator!=(const const_iterator &it)
Definition: Array2D.hh:125
const T * operator[](const unsigned row) const
Definition: Array2D.hh:83
const_iterator begin() const
Definition: Array2D.hh:136