[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

multi_hierarchical_iterator.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2003-2012 by Gunnar Kedenburg and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* ( Version 1.3.0, Sep 10 2004 ) */
7 /* The VIGRA Website is */
8 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
9 /* Please direct questions, bug reports, and contributions to */
10 /* ullrich.koethe@iwr.uni-heidelberg.de or */
11 /* vigra@informatik.uni-hamburg.de */
12 /* */
13 /* Permission is hereby granted, free of charge, to any person */
14 /* obtaining a copy of this software and associated documentation */
15 /* files (the "Software"), to deal in the Software without */
16 /* restriction, including without limitation the rights to use, */
17 /* copy, modify, merge, publish, distribute, sublicense, and/or */
18 /* sell copies of the Software, and to permit persons to whom the */
19 /* Software is furnished to do so, subject to the following */
20 /* conditions: */
21 /* */
22 /* The above copyright notice and this permission notice shall be */
23 /* included in all copies or substantial portions of the */
24 /* Software. */
25 /* */
26 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
27 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
28 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
29 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
30 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
31 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
32 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
33 /* OTHER DEALINGS IN THE SOFTWARE. */
34 /* */
35 /************************************************************************/
36 
37 #ifndef VIGRA_MULTI_HIERARCHICAL_ITERATOR_HXX
38 #define VIGRA_MULTI_HIERARCHICAL_ITERATOR_HXX
39 
40 #include <sys/types.h>
41 #include "multi_fwd.hxx"
42 #include "iteratortags.hxx"
43 #include "multi_handle.hxx"
44 
45 namespace vigra {
46 
47 /** \addtogroup MultiIteratorGroup
48 */
49 //@{
50 
51 /********************************************************/
52 /* */
53 /* MultiHierarchicalIterator */
54 /* */
55 /********************************************************/
56 
57 template <unsigned int N,
58  class HANDLES,
59  int DIMENSION = N-1>
60 class HierarchicalIterator
61 #ifndef DOXYGEN // doxygen doesn't understand this inheritance
62 : public HierarchicalIterator<N, HANDLES, DIMENSION-1>
63 #endif
64 {
65  public:
66 
67  typedef HierarchicalIterator<N, HANDLES, DIMENSION-1> base_type;
68  static const int level = DIMENSION;
69  typedef typename base_type::value_type value_type;
70  typedef typename base_type::reference reference;
71  typedef typename base_type::const_reference const_reference;
72  typedef typename base_type::pointer pointer;
73  typedef typename base_type::const_pointer const_pointer;
74  typedef typename base_type::difference_type difference_type;
75  typedef typename base_type::shape_type shape_type;
76 
77  explicit HierarchicalIterator(HANDLES const & handles = HANDLES())
78  : base_type(handles)
79  {}
80 
81  void operator++ ()
82  {
83  this->handles_.template increment<level>();
84  }
85 
86  void operator-- ()
87  {
88  this->handles_.template decrement<level>();
89  }
90 
91  HierarchicalIterator operator++ (int)
92  {
93  HierarchicalIterator ret = *this;
94  ++(*this);
95  return ret;
96  }
97 
98  HierarchicalIterator operator-- (int)
99  {
100  HierarchicalIterator ret = *this;
101  --(*this);
102  return ret;
103  }
104 
105  HierarchicalIterator & operator+= (difference_type n)
106  {
107  this->handles_.addDim(level, n);
108  return *this;
109  }
110 
111  HierarchicalIterator & operator+= (shape_type const & d)
112  {
114  return *this;
115  }
116 
117  HierarchicalIterator &operator-= (difference_type n)
118  {
119  this->handles_.addDim(level, -n);
120  return *this;
121  }
122 
123  // HierarchicalIterator & operator-= (multi_difference_type const & d)
124  // {
125  // this->m_ptr -= total_stride(d.begin());
126  // return *this;
127  // }
128 
129  HierarchicalIterator operator+ (difference_type n) const
130  {
131  return HierarchicalIterator(*this) += n;
132  }
133 
134  // HierarchicalIterator operator+ (multi_difference_type const & d) const
135  // {
136  // StridedMultiIterator ret = *this;
137  // ret += d;
138  // return ret;
139  // }
140 
141  difference_type operator- (HierarchicalIterator const & d) const
142  {
143  return this->point()[level] - d.point()[level];
144  }
145 
146  HierarchicalIterator operator- (difference_type n) const
147  {
148  return HierarchicalIterator(*this) -= n;
149  }
150 
151  // HierarchicalIterator operator- (multi_difference_type const & d) const
152  // {
153  // HierarchicalIterator ret = *this;
154  // ret -= d;
155  // return ret;
156  // }
157 
158  bool operator== (const HierarchicalIterator &rhs) const
159  {
160  return this->point()[level] == rhs.point()[level];
161  }
162 
163  bool operator!= (const HierarchicalIterator &rhs) const
164  {
165  return this->point()[level] != rhs.point()[level];
166  }
167 
168  bool operator< (const HierarchicalIterator &rhs) const
169  {
170  return this->point()[level] < rhs.point()[level];
171  }
172 
173  bool operator<= (const HierarchicalIterator &rhs) const
174  {
175  return this->point()[level] <= rhs.point()[level];
176  }
177 
178  bool operator> (const HierarchicalIterator &rhs) const
179  {
180  return this->point()[level] > rhs.point()[level];
181  }
182 
183  bool operator>= (const HierarchicalIterator &rhs) const
184  {
185  return this->point()[level] >= rhs.point()[level];
186  }
187 
188  base_type begin () const
189  {
190  return *this;
191  }
192 
193  base_type end () const
194  {
195  return base_type(*this) += this->shape()[level-1] - this->point()[level-1];
196  }
197 
198  HierarchicalIterator getEndIterator() const
199  {
200  return HierarchicalIterator(*this) += this->shape() - this->point();
201  }
202 
203  // iterator iteratorForDimension(unsigned int d) const
204  // {
205  // vigra_precondition(d <= level,
206  // "StridedMultiIterator<N>::iteratorForDimension(d): d < N required");
207  // return iterator(this->m_ptr, stride_traits::shift(m_stride, d), 0);
208  // }
209 
210  template <int K>
211  HierarchicalIterator<N, HANDLES, K> &
212  dim()
213  {
214  return *this;
215  }
216 
217  template <int K>
218  HierarchicalIterator<N, HANDLES, K> const &
219  dim() const
220  {
221  return *this;
222  }
223 };
224 
225 /********************************************************/
226 
227 template <unsigned int N,
228  class HANDLES>
229 class HierarchicalIterator<N, HANDLES, 0>
230 {
231  public:
232  static const int level = 0;
233 
234  typedef CoupledHandleTraits<HANDLES> HandleTraits;
235  typedef typename HandleTraits::value_type value_type;
236  typedef typename HandleTraits::reference reference;
237  typedef typename HandleTraits::const_reference const_reference;
238  typedef typename HandleTraits::pointer pointer;
239  typedef typename HandleTraits::const_pointer const_pointer;
240  typedef MultiArrayIndex difference_type;
241  typedef typename MultiArrayShape<N>::type shape_type;
242  typedef HierarchicalIterator<N, HANDLES, 0> iterator;
243  typedef std::random_access_iterator_tag iterator_category;
244 
245  protected:
246  HANDLES handles_;
247 
248  public:
249  explicit HierarchicalIterator(HANDLES const & handles = HANDLES())
250  : handles_(handles)
251  {}
252 
253  void operator++ ()
254  {
255  handles_.template increment<level>();
256  }
257 
258  void operator-- ()
259  {
260  handles_.template decrement<level>();
261  }
262 
263  HierarchicalIterator operator++ (int)
264  {
265  HierarchicalIterator ret = *this;
266  ++(*this);
267  return ret;
268  }
269 
270  HierarchicalIterator operator-- (int)
271  {
272  HierarchicalIterator ret = *this;
273  --(*this);
274  return ret;
275  }
276 
277  HierarchicalIterator & operator+= (difference_type n)
278  {
279  handles_.addDim(level, n);
280  return *this;
281  }
282 
283  HierarchicalIterator & operator+= (shape_type const & d)
284  {
285  handles_.add(d);
286  handles_.scanOrderIndex_ += detail::CoordinateToScanOrder<N>::exec(shape(), d);
287  return *this;
288  }
289 
290  HierarchicalIterator & operator-= (difference_type n)
291  {
292  handles_.addDim(level, -n);
293  return *this;
294  }
295 
296  // HierarchicalIterator & operator-= (multi_difference_type const & d)
297  // {
298  // m_ptr -= d[level];
299  // return *this;
300  // }
301 
302  HierarchicalIterator operator+ (difference_type n) const
303  {
304  return HierarchicalIterator(*this) += n;
305  }
306 
307  // HierarchicalIterator operator+ (multi_difference_type const & d) const
308  // {
309  // HierarchicalIterator ret = *this;
310  // ret += d;
311  // return ret;
312  // }
313 
314  difference_type operator- (HierarchicalIterator const & d) const
315  {
316  return point()[level] - d.point()[level];
317  }
318 
319  HierarchicalIterator operator- (difference_type n) const
320  {
321  return HierarchicalIterator(*this) -= n;
322  }
323 
324  // HierarchicalIterator operator- (multi_difference_type const & d) const
325  // {
326  // HierarchicalIterator ret = *this;
327  // ret -= d;
328  // return ret;
329  // }
330 
331  // reference operator[] (difference_type n) const
332  // {
333  // return m_ptr [n];
334  // }
335 
336  // reference operator[] (multi_difference_type const & d) const
337  // {
338  // return m_ptr [d[level]];
339  // }
340 
341  reference operator* ()
342  {
343  return HandleTraits::dereference(handles_);
344  }
345 
346  const_reference operator* () const
347  {
348  return HandleTraits::dereference(handles_);
349  }
350 
351  template <unsigned int TARGET_INDEX>
352  typename CoupledHandleCast<TARGET_INDEX, HANDLES>::reference
353  get()
354  {
355  return handles_.template get<TARGET_INDEX>();
356  }
357 
358  template <unsigned int TARGET_INDEX>
359  typename CoupledHandleCast<TARGET_INDEX, HANDLES>::const_reference
360  get() const
361  {
362  return handles_.template get<TARGET_INDEX>();
363  }
364 
365  pointer operator->()
366  {
367  return &HandleTraits::dereference(handles_);
368  }
369 
370  const_pointer operator->() const
371  {
372  return &HandleTraits::dereference(handles_);
373  }
374 
375  bool operator== (const HierarchicalIterator &rhs) const
376  {
377  return point()[level] == rhs.point()[level];
378  }
379 
380  bool operator!= (const HierarchicalIterator &rhs) const
381  {
382  return point()[level] != rhs.point()[level];
383  }
384 
385  bool operator< (const HierarchicalIterator &rhs) const
386  {
387  return point()[level] < rhs.point()[level];
388  }
389 
390  bool operator<= (const HierarchicalIterator &rhs) const
391  {
392  return point()[level] <= rhs.point()[level];
393  }
394 
395  bool operator> (const HierarchicalIterator &rhs) const
396  {
397  return point()[level] > rhs.point()[level];
398  }
399 
400  bool operator>= (const HierarchicalIterator &rhs) const
401  {
402  return point()[level] >= rhs.point()[level];
403  }
404 
405  // iterator iteratorForDimension(unsigned int d) const
406  // {
407  // vigra_precondition(d == 0,
408  // "MultiIterator<1>::iteratorForDimension(d): d == 0 required");
409  // const difference_type stride = 1;
410  // return iterator(m_ptr, &stride, 0);
411  // }
412 
413  HierarchicalIterator getEndIterator() const
414  {
415  return HierarchicalIterator(*this) += shape() - point();
416  }
417 
418  shape_type const & point() const
419  {
420  return handles_.point();
421  }
422 
423  shape_type const & shape() const
424  {
425  return handles_.shape();
426  }
427 
428  difference_type scanOrderIndex() const
429  {
430  return handles_.scanOrderIndex();
431  }
432 
433  HANDLES const & handles() const
434  {
435  return handles_;
436  }
437 
438  template <int K>
439  HierarchicalIterator<N, HANDLES, 0> &
440  dim()
441  {
442  return *this;
443  }
444 
445  template <int K>
446  HierarchicalIterator<N, HANDLES, 0> const &
447  dim() const
448  {
449  return *this;
450  }
451 
452  // protected:
453 
454  // difference_type
455  // total_stride(typename multi_difference_type::const_iterator d) const
456  // {
457  // return d[level];
458  // }
459 };
460 
461 /** Helper class to easliy get the type of a CoupledScanOrderIterator (and corresponding CoupledHandle) for up to five arrays of dimension N with element types T1,...,T5.
462  */
463 template <unsigned int N, class T1=void, class T2=void, class T3=void, class T4=void, class T5=void>
465 {
466  /** Type of the CoupledHandle.*/
467  typedef typename CoupledHandleType<N, T1, T2, T3, T4, T5>::type HandleType;
468 
469  /** Type of the CoupledScanOrderIterator.*/
470  typedef HierarchicalIterator<HandleType::dimensions, HandleType> IteratorType;
471  typedef IteratorType type;
472 };
473 
474 // /** Alias for \ref vigra::CoupledIteratorType (maybe easier to remember).
475  // */
476 // template <unsigned int N, class T1=void, class T2=void, class T3=void, class T4=void, class T5=void>
477 // struct CoupledArrays
478 // : public CoupledIteratorType<N, T1, T2, T3, T4, T5>
479 // {};
480 
481 /** Returns a HierarchicalIterator from shape to iterate over coordinates.
482  */
483 template <int N>
484 typename HierarchicalIteratorType<N>::type
486 {
487  typedef typename CoupledHandleType<N>::type P0;
488  typedef HierarchicalIterator<N, P0> IteratorType;
489 
490  return IteratorType(P0(shape));
491 }
492 
493 /** Returns a HierarchicalIterator to simultaneously iterate over image m1 and its coordinates.
494  */
495 template <unsigned int N1, class T1, class S1>
496 typename HierarchicalIteratorType<N1, T1>::type
498 {
499  typedef typename CoupledHandleType<N1, T1>::type P1;
500  typedef typename P1::base_type P0;
501  typedef HierarchicalIterator<P1::dimensions, P1> IteratorType;
502 
503  return IteratorType(P1(m1,
504  P0(m1.shape())));
505 }
506 
507 /** Returns a HierarchicalIterator to simultaneously iterate over images m1, m2 and their coordinates.
508  */
509 template <unsigned int N1, class T1, class S1,
510  unsigned int N2, class T2, class S2>
511 typename HierarchicalIteratorType<N1, T1, T2>::type
513  MultiArrayView<N2, T2, S2> const & m2)
514 {
515  typedef typename CoupledHandleType<N1, T1, T2>::type P2;
516  typedef typename P2::base_type P1;
517  typedef typename P1::base_type P0;
518  typedef HierarchicalIterator<P2::dimensions, P2> IteratorType;
519 
520  return IteratorType(P2(m2,
521  P1(m1,
522  P0(m1.shape()))));
523 }
524 
525 /** Returns a HierarchicalIterator to simultaneously iterate over images m1, m2, m3 and their coordinates.
526  */
527 template <unsigned int N1, class T1, class S1,
528  unsigned int N2, class T2, class S2,
529  unsigned int N3, class T3, class S3>
530 typename HierarchicalIteratorType<N1, T1, T2, T3>::type
532  MultiArrayView<N2, T2, S2> const & m2,
533  MultiArrayView<N3, T3, S3> const & m3)
534 {
535  typedef typename CoupledHandleType<N1, T1, T2, T3>::type P3;
536  typedef typename P3::base_type P2;
537  typedef typename P2::base_type P1;
538  typedef typename P1::base_type P0;
539  typedef HierarchicalIterator<P3::dimensions, P3> IteratorType;
540 
541  return IteratorType(P3(m3,
542  P2(m2,
543  P1(m1,
544  P0(m1.shape())))));
545 }
546 
547 /** Returns a HierarchicalIterator to simultaneously iterate over images m1, m2, m3, m4 and their coordinates.
548  */
549 template <unsigned int N1, class T1, class S1,
550  unsigned int N2, class T2, class S2,
551  unsigned int N3, class T3, class S3,
552  unsigned int N4, class T4, class S4>
553 typename HierarchicalIteratorType<N1, T1, T2, T3, T4>::type
555  MultiArrayView<N2, T2, S2> const & m2,
556  MultiArrayView<N3, T3, S3> const & m3,
557  MultiArrayView<N4, T4, S4> const & m4)
558 {
559  typedef typename CoupledHandleType<N1, T1, T2, T3, T4>::type P4;
560  typedef typename P4::base_type P3;
561  typedef typename P3::base_type P2;
562  typedef typename P2::base_type P1;
563  typedef typename P1::base_type P0;
564  typedef HierarchicalIterator<P4::dimensions, P4> IteratorType;
565 
566  return IteratorType(P4(m4,
567  P3(m3,
568  P2(m2,
569  P1(m1,
570  P0(m1.shape()))))));
571 }
572 
573 /** Returns a HierarchicalIterator to simultaneously iterate over images m1, m2, m3, m4, m5 and their coordinates.
574  */
575 template <unsigned int N1, class T1, class S1,
576  unsigned int N2, class T2, class S2,
577  unsigned int N3, class T3, class S3,
578  unsigned int N4, class T4, class S4,
579  unsigned int N5, class T5, class S5>
580 typename HierarchicalIteratorType<N1, T1, T2, T3, T4, T5>::type
582  MultiArrayView<N2, T2, S2> const & m2,
583  MultiArrayView<N3, T3, S3> const & m3,
584  MultiArrayView<N4, T4, S4> const & m4,
585  MultiArrayView<N5, T5, S5> const & m5)
586 {
587  typedef typename CoupledHandleType<N1, T1, T2, T3, T4, T5>::type P5;
588  typedef typename P5::base_type P4;
589  typedef typename P4::base_type P3;
590  typedef typename P3::base_type P2;
591  typedef typename P2::base_type P1;
592  typedef typename P1::base_type P0;
593  typedef HierarchicalIterator<P5::dimensions, P5> IteratorType;
594 
595  return IteratorType(P5(m5,
596  P4(m4,
597  P3(m3,
598  P2(m2,
599  P1(m1,
600  P0(m1.shape())))))));
601 }
602 
603 
604 template <unsigned int N, class A, class B>
605 HierarchicalIterator<N, typename ZipCoupledHandles<A, B>::type>
606 zip(HierarchicalIterator<N, A> const & a, HierarchicalIterator<N, B> const & b)
607 {
608  vigra_precondition(a.shape() == b.shape() && a.scanOrderIndex() == b.scanOrderIndex(),
609  "zip(HierarchicalIterator): iterators must have identical shape and position.");
610 
611  typedef typename ZipCoupledHandles<A, B>::type Handle;
612  typedef HierarchicalIterator<N, Handle> IteratorType;
613  return IteratorType(ZipCoupledHandles<A, B>::construct(a.handles(), b.handles()));
614 }
615 
616 //@}
617 
618 } // namespace vigra
619 
620 // namespace std {
621 
622 // template <unsigned int N, class T, class REFERENCE, class POINTER>
623 // ostream & operator<<(ostream & o, vigra::StridedScanOrderIterator<N, T, REFERENCE, POINTER> const & i)
624 // {
625  // o << *i;
626  // return o;
627 // }
628 
629 // } // namespace std
630 
631 #endif // VIGRA_MULTI_HIERARCHICAL_ITERATOR_HXX
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:711
const difference_type & shape() const
Definition: multi_array.hxx:1648
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition: diff2d.hxx:739
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
HierarchicalIteratorType< N >::type createHierarchicalIterator(TinyVector< MultiArrayIndex, N > const &shape)
Definition: multi_hierarchical_iterator.hxx:485
FFTWComplex< R > & operator-=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
subtract-assignment
Definition: fftw3.hxx:867
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition: fixedpoint.hxx:521
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
CoupledHandleType< N, T1, T2, T3, T4, T5 >::type HandleType
Definition: multi_hierarchical_iterator.hxx:467
HierarchicalIterator< HandleType::dimensions, HandleType > IteratorType
Definition: multi_hierarchical_iterator.hxx:470
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition: fixedpoint.hxx:512
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition: fixedpoint.hxx:539
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:704
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition: fixedpoint.hxx:530
Definition: multi_hierarchical_iterator.hxx:464

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)