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

multi_hierarchical_iterator.hxx
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
45namespace vigra {
46
47/** \addtogroup MultiIteratorGroup
48*/
49//@{
50
51/********************************************************/
52/* */
53/* MultiHierarchicalIterator */
54/* */
55/********************************************************/
56
57template <unsigned int N,
58 class HANDLES,
59 int DIMENSION = N-1>
60class 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 {
113 base_type::operator+=(d);
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
227template <unsigned int N,
228 class HANDLES>
229class 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 */
463template <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 */
483template <int N>
484typename 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 */
495template <unsigned int N1, class T1, class S1>
496typename 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 */
509template <unsigned int N1, class T1, class S1,
510 unsigned int N2, class T2, class S2>
511typename HierarchicalIteratorType<N1, T1, T2>::type
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 */
527template <unsigned int N1, class T1, class S1,
528 unsigned int N2, class T2, class S2,
529 unsigned int N3, class T3, class S3>
530typename HierarchicalIteratorType<N1, T1, T2, T3>::type
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 */
549template <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>
553typename HierarchicalIteratorType<N1, T1, T2, T3, T4>::type
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 */
575template <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>
580typename HierarchicalIteratorType<N1, T1, T2, T3, T4, T5>::type
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
604template <unsigned int N, class A, class B>
605HierarchicalIterator<N, typename ZipCoupledHandles<A, B>::type>
606zip(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
TinyVector< MultiArrayIndex, N > type
Definition multi_shape.hxx:272
Base class for, and view to, MultiArray.
Definition multi_array.hxx:705
const difference_type & shape() const
Definition multi_array.hxx:1650
Class for fixed size vectors.
Definition tinyvector.hxx:1008
LookupTag< TAG, A >::result_type get(A const &a)
Definition accumulator.hxx:2942
HierarchicalIteratorType< N >::type createHierarchicalIterator(TinyVector< MultiArrayIndex, N > const &shape)
Definition multi_hierarchical_iterator.hxx:485
std::ptrdiff_t MultiArrayIndex
Definition multi_fwd.hxx:60
Definition multi_hierarchical_iterator.hxx:465
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

© 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.12.2 (Mon Apr 14 2025)