KrisLibrary  1.0.0
array3d.h
1 #ifndef ARRAY3D_H
2 #define ARRAY3D_H
3 
4 #include <KrisLibrary/File.h>
5 #include <KrisLibrary/utils.h>
6 #include <KrisLibrary/utils/IntTriple.h>
7 #include <KrisLibrary/utils/indexing.h>
8 #include <KrisLibrary/errors.h>
9 #include <iosfwd>
10 
30 template <class T>
31 class Array3D
32 {
33  public:
34  Array3D();
35  Array3D(int m,int n,int p);
36  Array3D(int m,int n,int p,const T& initVal);
37  Array3D(const Array3D<T>& rhs);
38  Array3D(Array3D<T>&& rhs);
39  ~Array3D();
40 
41  inline T& operator()(int i,int j,int k) { Assert(i>=0&&i<m); return items[(i*n+j)*p+k]; }
42  inline const T& operator()(int i,int j,int k) const { return items[(i*n+j)*p+k]; }
43  inline T& operator()(const IntTriple& t) { return operator()(t.a,t.b,t.c); }
44  inline const T& operator()(const IntTriple& t) const { return operator()(t.a,t.b,t.c); }
45  Array3D<T>& operator =(const Array3D<T>& rhs);
46  Array3D<T>& operator =(Array3D<T>&& rhs);
47 
48  bool Read(File& f);
49  bool Write(File& f) const;
50 
51  inline int dim1() const { return m; }
52  inline int dim2() const { return n; }
53  inline int dim3() const { return p; }
54  inline IntTriple size() const { return IntTriple(m,n,p); }
55  inline bool empty() const { return m==0&&n==0&&p==0; }
56  void initialize(int m,int n,int p);
57  void initialize(int m,int n,int p,const T& initVal);
58  void resize(int m,int n,int p);
59  void resize(int m,int n,int p,const T& initVal);
60  void reserve(int cap);
61  void clear();
62 
63  bool find(const T& item,int& i,int& j,int& k) const;
64  bool find(const T& item,IntTriple& t) const { return find(item,t.a,t.b,t.c); }
65  inline bool contains(const T& item) const { int i,j,k; return find(item,i,j,k); }
66  void set(const T& item);
67  void set(const Array3D<T>&);
68  void swap(Array3D<T>&);
69  inline T* getData() const { return items; }
70 
71  class iterator
72  {
73  public:
74  iterator(const Array3D<T>* array);
75  iterator(const Array3D<T>* array,int invalid);
76  iterator(const Array3D<T>* array,const Stripe3Indices& range);
77  iterator(const Array3D<T>* array,const Stripe3Indices& range,int invalid);
78  iterator(const iterator& rhs);
79  inline iterator& operator ++() { ++it; return *this; }
80  inline iterator& operator --() { --it; return *this; }
81  inline iterator& operator +=(int skip) { it+=skip; return *this; }
82  inline iterator& operator -=(int skip) { it-=skip; return *this; }
83  inline void incFirst(int skip=1) { it.incFirst(skip); }
84  inline void incSecond(int skip=1) { it.incSecond(skip); }
85  inline void incThird(int skip=1) { it.incThird(skip); }
86  inline T& operator*() { return array->getData()[*it]; }
87  const iterator& operator = (const iterator& rhs);
88  inline bool operator == (const iterator& rhs) const { return it == rhs.it && array==rhs.array; }
89  inline bool operator != (const iterator& rhs) const { return !operator==(rhs); }
90  inline bool operator < (const iterator& rhs) const { return it<rhs.it; }
91  IntTriple getElement() const {
92  //translate to original coordinates
93  IntTriple i=it.getElement();
94  //range.base = ibase*n*p + jbase*p + kbase;
95  //range.istride = istride*n*p;
96  //range.jstride = jstride*p;
97  //range.kstride = kstride;
98  int kstride = range.kstride;
99  int jstride = range.jstride/array->p;
100  int istride = range.istride/(array->p*array->n);
101  div_t d=div(range.base,array->p);
102  int kbase=d.rem;
103  d=div(d.quot,array->n);
104  int jbase=d.rem;
105  int ibase=d.quot;
106  return IntTriple(i.a*istride+ibase,i.b*jstride+jbase,i.c*kstride+kbase);
107  }
108 
109  //private:
110  const Array3D<T>* array;
111  Stripe3Indices range;
113  };
114  iterator begin() const { return iterator(this); }
115  iterator end() const { return iterator(this,-1); }
116  iterator begin(const Range3Indices& range) const { return iterator(this,Stripe3Indices(m,n,p,range)); }
117  iterator end(const Range3Indices& range) const{ return iterator(this,Stripe3Indices(m,n,p,range),-1); }
118 
119  //READ ONLY
120  int m,n,p;
121  protected:
122  T* items;
123  int capacity;
124 };
125 
126 template <class T>
127 std::istream& operator >> (std::istream& in,Array3D<T>& a)
128 {
129  int m,n,p;
130  in>>m>>n>>p;
131  if(!in) return in;
132  Assert(m >= 0 && n >= 0 && p >= 0);
133  a.resize(m,n,p);
134  for(int i=0;i<m;i++)
135  for(int j=0;j<n;j++)
136  for(int k=0;k<p;k++)
137  in>>a(i,j,k);
138  return in;
139 }
140 
141 template <class T>
142 std::ostream& operator << (std::ostream& out,const Array3D<T>& a)
143 {
144  out<<a.m<<" "<<a.n<<" "<<" "<<a.p<<std::endl;
145  for(int i=0;i<a.m;i++) {
146  for(int j=0;j<a.n;j++) {
147  for(int k=0;k<a.p;k++)
148  out<<a(i,j,k)<<" ";
149  out<<std::endl;
150  }
151  }
152  return out;
153 }
154 
155 template <class T>
157  :m(0),n(0),p(0),items(0),capacity(0)
158 {}
159 
160 template <class T>
161 Array3D<T>::Array3D(int _m,int _n,int _p)
162 :m(0),n(0),p(0),items(0),capacity(0)
163 {
164  initialize(_m,_n,_p);
165 }
166 
167 template <class T>
168 Array3D<T>::Array3D(int _m,int _n,int _p,const T& initVal)
169 :m(0),n(0),p(0),items(0),capacity(0)
170 {
171  initialize(_m,_n,_p,initVal);
172 }
173 
174 template <class T>
176 :m(0),n(0),p(0),items(0),capacity(0)
177 {
178  set(rhs);
179 }
180 
181 template <class T>
183 {
184  m = rhs.m;
185  n = rhs.n;
186  p = rhs.p;
187  items = rhs.items;
188  capacity = rhs.capacity;
189  //prevent deletion
190  rhs.items = 0;
191 }
192 
193 template <class T>
195 {
196  clear();
197 }
198 
199 template <class T>
201 {
202  set(rhs);
203  return *this;
204 }
205 
206 template <class T>
208 {
209  m = rhs.m;
210  n = rhs.n;
211  p = rhs.p;
212  items = rhs.items;
213  capacity = rhs.capacity;
214  //prevent deletion
215  rhs.items = 0;
216  return *this;
217 }
218 
219 template <class T>
220 bool Array3D<T>::Read(File& f)
221 {
222  if(!ReadFile(f,m)) return false;
223  if(!ReadFile(f,n)) return false;
224  if(!ReadFile(f,p)) return false;
225  initialize(m,n,p);
226  if(!ReadArrayFile(f,items,m*n*p)) return false;
227  return true;
228 }
229 
230 template <class T>
231 bool Array3D<T>::Write(File& f) const
232 {
233  if(!WriteFile(f,m)) return false;
234  if(!WriteFile(f,n)) return false;
235  if(!WriteFile(f,p)) return false;
236  if(!WriteArrayFile(f,items,m*n*p)) return false;
237  return true;
238 }
239 
240 template <class T>
241 void Array3D<T>::initialize(int _m,int _n,int _p)
242 {
243  clear();
244  m=_m;
245  n=_n;
246  p=_p;
247  capacity = m*n*p;
248  items=new T[capacity];
249 }
250 
251 template <class T>
252 void Array3D<T>::initialize(int _m,int _n,int _p,const T& initVal)
253 {
254  clear();
255  m=_m;
256  n=_n;
257  p=_p;
258  capacity = m*n*p;
259  items=new T[capacity];
260  set(initVal);
261 }
262 
263 template <class T>
264 void Array3D<T>::resize(int _m,int _n,int _p)
265 {
266  if(_m*_n*_p > capacity)
267  initialize(_m,_n,_p);
268  m=_m;
269  n=_n;
270  p=_p;
271 }
272 
273 template <class T>
274 void Array3D<T>::resize(int _m,int _n,int _p,const T& initVal)
275 {
276  if(_m*_n*_p > capacity)
277  initialize(_m,_n,_p);
278  m=_m;
279  n=_n;
280  p=_p;
281  set(initVal);
282 }
283 
284 template <class T>
285 void Array3D<T>::clear()
286 {
287  SafeArrayDelete(items);
288  m=n=p=0;
289  capacity=0;
290 }
291 
292 template <class T>
293 bool Array3D<T>::find(const T& item,int& i,int& j,int& k) const
294 {
295  for(int s=0;s<m;s++)
296  for(int t=0;t<n;t++)
297  for(int u=0;u<p;u++)
298  if(operator()(s,t,u)==item) {
299  i=s; j=t; k=u;
300  return true;
301  }
302  return false;
303 }
304 
305 template <class T>
306 void Array3D<T>::set(const T& item)
307 {
308  for(int i=0;i<m*n*p;i++) items[i]=item;
309 }
310 
311 template <class T>
312 void Array3D<T>::set(const Array3D<T>& rhs)
313 {
314  resize(rhs.m,rhs.n,rhs.p);
315  for(int i=0;i<m*n*p;i++) items[i]=rhs.items[i];
316 }
317 
318 template <class T>
320 {
321  int tempm=m,tempn=n,tempp=p;
322  int tempcap=capacity;
323  T* tempitems=items;
324  m=b.m; n=b.n; p=b.p;
325  items=b.items;
326  capacity=b.capacity;
327  b.m=tempm; b.n=tempn; b.p=tempp;
328  b.items=tempitems;
329  b.capacity=tempcap;
330 }
331 
332 template <class T>
334  :array(_array),range(_array->m,_array->n,_array->p),it(&range)
335 {}
336 
337 template <class T>
338 Array3D<T>::iterator::iterator(const Array3D<T>* _array,int invalid)
339  :array(_array),range(_array->m,_array->n,_array->p),it(range.end())
340 {}
341 
342 template <class T>
343 Array3D<T>::iterator::iterator(const Array3D<T>* _array,const Stripe3Indices& _range)
344  :array(_array),range(_range),it(&range)
345 {}
346 
347 template <class T>
348 Array3D<T>::iterator::iterator(const Array3D<T>* _array,const Stripe3Indices& _range,int invalid)
349  :array(_array),range(_range),it(range.end())
350 {}
351 
352 template <class T>
354  :array(rhs.array),range(rhs.range),it(rhs.it)
355 {
356  it.stripe = &range; //maintain a valid pointer over the iterator's lifetime
357 }
358 
359 template <class T>
361 {
362  array = rhs.array;
363  range = rhs.range;
364  it = rhs.it;
365  it.stripe = &range; //maintain a valid pointer over the iterator's lifetime
366  return *this;
367 }
368 
369 
370 namespace std {
371 
372  template <class T>
373  void swap(Array3D<T>& a,Array3D<T>&b)
374  {
375  a.swap(b);
376  }
377 
378 } //namespace std
379 
380 #endif
A lightweight integer 3-tuple class.
Definition: IntTriple.h:9
bool WriteFile(File &f, const std::vector< type > &v)
WriteFile() for STL vectors. See File.h.
Definition: ioutils.h:73
A 3D lattice of regular ranges.
Definition: utils/indexing.h:175
Definition: rayprimitives.h:132
Utilities commonly used throughout a program.
A unified interface for reading/writing binary data to file.
Definition: utils/indexing.h:312
bool ReadFile(File &f, std::vector< type > &v)
ReadFile() for STL vectors. See File.h.
Definition: ioutils.h:61
Definition: array3d.h:71
A cross-platform class for reading/writing binary data.
Definition: File.h:47
A 3D lattice indexing into a linear sequence, in a striping pattern.
Definition: utils/indexing.h:295
A three-dimensional m x n x parray.
Definition: array3d.h:31
#define SafeArrayDelete(x)
Delete a non-NULL pointer to an array and set it to NULL.
Definition: utils.h:95