[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
vigra/coordinate_iterator.hxx | ![]() |
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 2011-2012 by Markus Nullmeier and Ullrich Koethe */ 00004 /* */ 00005 /* This file is part of the VIGRA computer vision library. */ 00006 /* The VIGRA Website is */ 00007 /* http://hci.iwr.uni-heidelberg.de/vigra/ */ 00008 /* Please direct questions, bug reports, and contributions to */ 00009 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00010 /* vigra@informatik.uni-hamburg.de */ 00011 /* */ 00012 /* Permission is hereby granted, free of charge, to any person */ 00013 /* obtaining a copy of this software and associated documentation */ 00014 /* files (the "Software"), to deal in the Software without */ 00015 /* restriction, including without limitation the rights to use, */ 00016 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00017 /* sell copies of the Software, and to permit persons to whom the */ 00018 /* Software is furnished to do so, subject to the following */ 00019 /* conditions: */ 00020 /* */ 00021 /* The above copyright notice and this permission notice shall be */ 00022 /* included in all copies or substantial portions of the */ 00023 /* Software. */ 00024 /* */ 00025 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00026 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00027 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00028 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00029 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00030 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00031 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00032 /* OTHER DEALINGS IN THE SOFTWARE. */ 00033 /* */ 00034 /************************************************************************/ 00035 00036 #ifndef VIGRA_COORDINATE_ITERATOR_HXX 00037 #define VIGRA_COORDINATE_ITERATOR_HXX 00038 00039 #include <complex> 00040 00041 #include "tuple.hxx" 00042 #include "accessor.hxx" 00043 #include "tinyvector.hxx" 00044 #include "numerictraits.hxx" 00045 #include "multi_iterator.hxx" 00046 #include "multi_array.hxx" 00047 00048 namespace vigra { 00049 00050 template<unsigned N> 00051 struct StridePair 00052 { 00053 typedef typename MultiArrayShape<N>::type index_type; 00054 typedef TinyVector<double, N> coord_type; 00055 typedef coord_type deref_type; 00056 typedef StridePair type; 00057 typedef StridePair stride_type; 00058 typedef TinyVector<type, N> stride_array_type; 00059 typedef TinyVector<index_type, N> shape_array_type; 00060 typedef shape_array_type shape_type; 00061 00062 index_type index; 00063 coord_type coord; 00064 00065 StridePair(const index_type & i) : index(i), coord(i) {} 00066 StridePair(const coord_type & c) : index(), coord(c) {} 00067 StridePair(const index_type & i, const coord_type & c) 00068 : index (i), coord(c) {} 00069 StridePair( MultiArrayIndex i, const coord_type & c) 00070 : index(index_type(i)), coord(c) {} 00071 StridePair() {} 00072 00073 // use just the coordinates for further processing ... 00074 const coord_type & operator*() const 00075 { 00076 return this->coord; 00077 } 00078 00079 void operator+=(const StridePair & x) 00080 { 00081 index += x.index; 00082 coord += x.coord; 00083 } 00084 void operator-=(const StridePair & x) 00085 { 00086 index -= x.index; 00087 coord -= x.coord; 00088 } 00089 StridePair operator+(const StridePair & x) 00090 { 00091 StridePair ret = *this; 00092 ret += x; 00093 return ret; 00094 } 00095 StridePair operator-(const StridePair & x) 00096 { 00097 StridePair ret = *this; 00098 ret -= x; 00099 return ret; 00100 } 00101 StridePair operator*(const StridePair & x) 00102 { 00103 StridePair ret = *this; 00104 ret.index *= x.index; 00105 ret.coord *= x.coord; 00106 return ret; 00107 } 00108 StridePair operator/(const StridePair & x) 00109 { 00110 StridePair ret = *this; 00111 ret.index /= x.index; 00112 ret.coord /= x.coord; 00113 return ret; 00114 } 00115 00116 MultiArrayIndex & idx0() 00117 { 00118 return index[0]; 00119 } 00120 const index_type & idx() const 00121 { 00122 return index; 00123 } 00124 double & dim0() 00125 { 00126 return coord[0]; 00127 } 00128 double dim0() const 00129 { 00130 return coord[0]; 00131 } 00132 }; 00133 00134 template<unsigned M> 00135 struct NumericTraits<StridePair<M> > 00136 : public NumericTraits<typename StridePair<M>::index_type> 00137 {}; 00138 00139 template<unsigned N> 00140 struct StridePairCoord : public TinyVector<double, N> 00141 { 00142 typedef TinyVector<double, N> entry_type; 00143 00144 StridePairCoord(const entry_type & c) : entry_type(c) {} 00145 StridePairCoord() {} 00146 00147 double & dim0() 00148 { 00149 return (*this)[0]; 00150 } 00151 double dim0() const 00152 { 00153 return (*this)[0]; 00154 } 00155 }; 00156 template<unsigned M> 00157 struct NumericTraits<StridePairCoord<M> > 00158 : public NumericTraits<typename StridePairCoord<M>::entry_type> 00159 {}; 00160 00161 template<unsigned N> 00162 struct StridePairDiff : public StridePairCoord<N> 00163 { 00164 MultiArrayIndex c; 00165 00166 typedef StridePairCoord<N> base_type; 00167 StridePairDiff(MultiArrayIndex c_, const base_type & x) 00168 : base_type(x), c(c_) {} 00169 StridePairDiff(const base_type & x) 00170 : base_type(x), c(0) {} 00171 StridePairDiff(const TinyVector<double, N> & x) 00172 : base_type(x), c(0) {} 00173 StridePairDiff(const TinyVector<MultiArrayIndex, N> & x) 00174 : base_type(x), c(0) {} 00175 StridePairDiff() : c(0) {} 00176 00177 const base_type & base() const 00178 { 00179 return *this; 00180 } 00181 StridePairDiff operator*(const StridePairDiff & x) 00182 { 00183 StridePairDiff ret = base() * x.base(); 00184 ret.c = c * x.c; 00185 return ret; 00186 } 00187 }; 00188 00189 template<unsigned M> 00190 struct NumericTraits<StridePairDiff<M> > 00191 : public NumericTraits<StridePairCoord<M> > 00192 {}; 00193 00194 template<unsigned N, class T> 00195 struct StridePairPointer : public StridePairCoord<N> 00196 { 00197 typedef const T* index_type; 00198 typedef StridePairCoord<N> coord_type; 00199 typedef typename coord_type::entry_type coord_num_type; 00200 typedef StridePairPointer type; 00201 typedef type deref_type; 00202 typedef StridePairDiff<N> stride_type; 00203 typedef TinyVector<stride_type, N> stride_array_type; 00204 typedef typename MultiArrayShape<N>::type shape_array_type; 00205 typedef shape_array_type shape_type; 00206 00207 index_type index; 00208 00209 StridePairPointer(const index_type & i, const coord_type & c) 00210 : coord_type(c), index(i) {} 00211 00212 const type & operator*() const 00213 { 00214 return *this; 00215 } 00216 const T & value() const 00217 { 00218 return *index; 00219 } 00220 const coord_type & coord() const 00221 { 00222 return *this; 00223 } 00224 00225 index_type & idx0() 00226 { 00227 return index; 00228 } 00229 const index_type & idx() const 00230 { 00231 return index; 00232 } 00233 00234 void operator+=(stride_type x) 00235 { 00236 index += x.c; 00237 coord_type::operator+=(x); 00238 } 00239 void operator-=(stride_type x) 00240 { 00241 index -= x.c; 00242 coord_type::operator-=(x); 00243 } 00244 }; 00245 00246 template<unsigned M, class T> 00247 struct NumericTraits<StridePairPointer<M, T> > 00248 : public NumericTraits<typename StridePairPointer<M, T>::coord_type> 00249 {}; 00250 00251 namespace detail { 00252 00253 template<class T, bool is_complex = NumericTraits<T>::isComplex::value, 00254 bool is_vector = !NumericTraits<T>::isScalar::value> 00255 struct weighted_abs 00256 { 00257 static double get(const T & x) 00258 { 00259 return x; 00260 } 00261 }; 00262 00263 template<class T> 00264 struct weighted_abs<T, true, false> 00265 { 00266 static double get(const T & x) 00267 { 00268 using std::abs; 00269 return abs(x); 00270 } 00271 }; 00272 00273 template<class T, bool is_complex> 00274 struct weighted_abs<T, is_complex, true> 00275 { 00276 static double get(const T & x) 00277 { 00278 return x.magnitude(); 00279 } 00280 }; 00281 00282 template<class T> 00283 struct accumulable_coord_access; 00284 template<class T> 00285 struct accumulable_value_access; 00286 template<class T> 00287 struct accumulable_weighted_access; 00288 00289 template<unsigned N, class T> 00290 struct accumulable_coord_access<StridePairPointer<N, T> > 00291 { 00292 typedef StridePairPointer<N, T> accumulable_type; 00293 typedef typename accumulable_type::coord_num_type type; 00294 static const type & get(const accumulable_type & v) { return v.coord(); } 00295 }; 00296 00297 template<unsigned N, class T> 00298 struct accumulable_value_access<StridePairPointer<N, T> > 00299 { 00300 typedef StridePairPointer<N, T> accumulable_type; 00301 typedef T type; 00302 static const type & get(const accumulable_type & v) { return v.value(); } 00303 }; 00304 00305 template<unsigned N, class T> 00306 struct accumulable_weighted_access<StridePairPointer<N, T> > 00307 { 00308 typedef StridePairPointer<N, T> accumulable_type; 00309 typedef typename accumulable_type::coord_num_type type; 00310 static type get(const accumulable_type & v) 00311 { 00312 return weighted_abs<T>::get(v.value()) * v.coord(); 00313 } 00314 }; 00315 00316 template<class X> 00317 void dismember(X & r, const X & x, unsigned i) 00318 { 00319 r[i] = x[i]; 00320 } 00321 template<unsigned N> 00322 void dismember(StridePair<N> & r, const StridePair<N> & x, unsigned i) 00323 { 00324 r.index[i] = x.index[i]; 00325 r.coord[i] = x.coord[i]; 00326 } 00327 template<unsigned N> 00328 void dismember(StridePairDiff<N> & r, const StridePairDiff<N> & x, unsigned i) 00329 { 00330 r.c = static_cast<MultiArrayIndex>(r[i] = x[i]); 00331 } 00332 00333 template<unsigned N, class X> 00334 TinyVector<X, N> 00335 dismember(const X & x) 00336 { 00337 TinyVector<X, N> ret; 00338 for (unsigned i = 0; i != N; ++i) 00339 dismember(ret[i], x, i); 00340 return ret; 00341 } 00342 template<unsigned N> 00343 TinyVector<StridePairDiff<N>, N> 00344 dismember(const TinyVector<MultiArrayIndex, N> & x, 00345 const StridePairCoord<N> & y) 00346 { 00347 typedef StridePairDiff<N> type; 00348 TinyVector<type, N> ret; 00349 for (unsigned i = 0; i != N; ++i) 00350 { 00351 ret[i].c = x[i]; 00352 ret[i][i] = y[i]; 00353 } 00354 return ret; 00355 } 00356 00357 } // namespace detail 00358 00359 // A fake "pointer" for MultiIterator containing coordinates. 00360 // Indices (or a pointer) cannot be circumvented in coordiante iterators, 00361 // since floating point addition is not associative and 00362 // iterator comparison is done via via '<' or '!='. Class CoordinateStride 00363 // thus forwards iterator comparison to the index or pointer part 00364 // of its template parameter S. 00365 template<unsigned N, class S = StridePair<N> > 00366 class CoordinateStride : protected S 00367 { 00368 public: 00369 typedef MultiArrayIndex difference_type; 00370 typedef typename S::stride_type stride_type; 00371 typedef typename S::deref_type deref_type; 00372 typedef CoordinateStride<N> type; 00373 typedef typename S::coord_type coord_type; 00374 typedef typename S::index_type index_type; 00375 typedef typename S::shape_array_type shape_array_type; 00376 00377 protected: 00378 double stride_0; 00379 00380 CoordinateStride(void*) {} // used MultiIterator ctor, unused. 00381 00382 public: 00383 CoordinateStride(const S & x, double s0) 00384 : S(x), stride_0(s0) {} 00385 00386 using S::operator*; 00387 using S::idx0; 00388 using S::idx; 00389 using S::dim0; 00390 using S::operator+=; 00391 using S::operator-=; 00392 00393 void operator++() 00394 { 00395 ++idx0(); 00396 dim0() += stride_0; 00397 } 00398 void operator--() 00399 { 00400 --idx0(); 00401 dim0() -= stride_0; 00402 } 00403 void operator+=(difference_type n) 00404 { 00405 idx0() += n; 00406 dim0() += n * stride_0; 00407 } 00408 void operator-=(difference_type n) 00409 { 00410 idx0() -= n; 00411 dim0() -= n * stride_0; 00412 } 00413 00414 stride_type operator[](difference_type n) const 00415 { 00416 type ret = *this; 00417 ret[0] += n; 00418 return ret; 00419 } 00420 00421 stride_type operator[](stride_type x) const 00422 { 00423 return *this + x; 00424 } 00425 00426 // ... but use the idx() for comparisons: 00427 bool operator!=(const CoordinateStride & y) const 00428 { 00429 return idx() != y.idx(); 00430 } 00431 bool operator==(const CoordinateStride & y) const 00432 { 00433 if (stride_0 != y.stride_0) 00434 return false; 00435 return idx() == y.idx(); 00436 } 00437 bool operator<(const CoordinateStride & y) const 00438 { 00439 return idx() < y.idx(); 00440 } 00441 00442 bool operator<=(const CoordinateStride & y) const 00443 { 00444 if (stride_0 == y.stride_0) 00445 return true; 00446 return *this < y; 00447 } 00448 bool operator>(const CoordinateStride & y) const 00449 { 00450 return y < *this; 00451 } 00452 bool operator>=(const CoordinateStride & y) const 00453 { 00454 if (stride_0 == y.stride_0) 00455 return true; 00456 return operator>(y); 00457 } 00458 00459 friend std::ostream & 00460 operator<<(std::ostream & os, const CoordinateStride & x) 00461 { 00462 os << "{" << x.stride_0 << ": " << static_cast<const S &>(x) << "}"; 00463 return os; 00464 } 00465 00466 typedef MultiIterator<N, deref_type, const deref_type &, CoordinateStride> 00467 iterator_type; 00468 }; 00469 00470 template <unsigned N, class S> 00471 struct MultiIteratorStrideTraits<CoordinateStride<N, S> > 00472 { 00473 typedef typename S::stride_type stride_type; 00474 typedef typename S::stride_array_type stride_array_type; 00475 typedef typename S::shape_array_type shape_array_type; 00476 static stride_array_type shift(const stride_array_type & s, unsigned d) 00477 { 00478 stride_array_type ret; 00479 for (unsigned i = d; i != N; ++i) 00480 ret[i - d] = s[i]; 00481 return ret; 00482 } 00483 }; 00484 00485 template <unsigned N> 00486 struct CoordinateMultiIterator : public CoordinateStride<N>::iterator_type 00487 { 00488 typedef CoordinateStride<N> ptr_type; 00489 typedef typename ptr_type::iterator_type base_type; 00490 typedef typename ptr_type::stride_type stride_type; 00491 typedef typename ptr_type::shape_array_type shape_array_type; 00492 typedef typename ptr_type::coord_type coord_type; 00493 typedef typename ptr_type::index_type index_type; 00494 00495 CoordinateMultiIterator(const stride_type & origin, 00496 const stride_type & stride, 00497 const index_type & shape) 00498 00499 : base_type(ptr_type(origin, stride.dim0()), 00500 detail::dismember<N>(stride), 00501 detail::dismember<N>(shape)) {} 00502 00503 CoordinateMultiIterator(const base_type & x) : base_type(x) {} 00504 }; 00505 00506 namespace detail { 00507 00508 template<unsigned N> 00509 struct CoordinateMultiRangeReturns 00510 { 00511 typedef CoordinateMultiIterator<N> iterator_type; 00512 typedef typename iterator_type::coord_type coord_type; 00513 typedef StridePair<N> pair_type; 00514 typedef typename pair_type::type stride_type; 00515 typedef typename pair_type::stride_array_type stride_array_type; 00516 00517 typedef typename AccessorTraits<coord_type>::default_const_accessor 00518 access_type; 00519 typedef triple<iterator_type, stride_array_type, access_type> type; 00520 }; 00521 00522 } // namespace detail 00523 00524 template <unsigned N> 00525 typename detail::CoordinateMultiRangeReturns<N>::type 00526 coordinateMultiRange(const typename MultiArrayShape<N>::type & shape, 00527 const TinyVector<double, N> & stride 00528 = TinyVector<double, N>(1.0), 00529 const TinyVector<double, N> & origin 00530 = TinyVector<double, N>(0.0)) 00531 { 00532 typedef typename 00533 detail::CoordinateMultiRangeReturns<N>::stride_type stride_type; 00534 typedef typename 00535 detail::CoordinateMultiRangeReturns<N>::access_type access_type; 00536 00537 return typename detail::CoordinateMultiRangeReturns<N>::type 00538 (CoordinateMultiIterator<N>(stride_type(0, origin), 00539 stride_type(1, stride), 00540 shape), 00541 detail::dismember<N>(stride_type(shape)), 00542 access_type()); 00543 } 00544 00545 template <unsigned N, class T> 00546 struct CombinedMultiIterator 00547 : public CoordinateStride<N, StridePairPointer<N, T> >::iterator_type 00548 { 00549 typedef StridePairPointer<N, T> pair_type; 00550 typedef CoordinateStride<N, pair_type> ptr_type; 00551 typedef typename ptr_type::iterator_type base_type; 00552 typedef typename ptr_type::stride_type stride_type; 00553 typedef typename ptr_type::coord_type coord_type; 00554 typedef typename pair_type::shape_array_type shape_array_type; 00555 00556 CombinedMultiIterator(const T* raw_pointer, 00557 const stride_type & origin, 00558 const TinyVector<MultiArrayIndex, N> & pointer_stride, 00559 const stride_type & stride, 00560 const shape_array_type & shape) 00561 00562 : base_type(ptr_type(pair_type(raw_pointer, origin), stride.dim0()), 00563 detail::dismember<N>(pointer_stride, stride), 00564 shape) {} 00565 00566 CombinedMultiIterator(const base_type & x) : base_type(x) {} 00567 }; 00568 00569 template<unsigned N, class T> 00570 struct SrcCoordinateMultiArrayRangeReturns 00571 { 00572 typedef CombinedMultiIterator<N, T> iterator_type; 00573 typedef typename iterator_type::coord_type coord_type; 00574 typedef typename iterator_type::pair_type pair_type; 00575 typedef typename iterator_type::ptr_type ptr_type; 00576 typedef typename ptr_type::deref_type deref_type; 00577 typedef typename iterator_type::stride_type stride_type; 00578 typedef typename pair_type::stride_array_type stride_array_type; 00579 typedef typename pair_type::shape_array_type shape_array_type; 00580 00581 typedef typename AccessorTraits<deref_type>::default_const_accessor 00582 access_type; 00583 typedef triple<iterator_type, stride_array_type, access_type> type; 00584 }; 00585 00586 // work around GCC 4.4.3 template argument deduction bug: 00587 template<unsigned N> 00588 struct CoordinateSteps 00589 { 00590 typedef const TinyVector<double, N> & type; 00591 }; 00592 00593 template <unsigned int N, class T, class StrideTag> 00594 inline typename SrcCoordinateMultiArrayRangeReturns<N, T>::type 00595 srcCoordinateMultiArrayRange(const MultiArrayView<N, T, StrideTag> & array, 00596 typename CoordinateSteps<N>::type stride 00597 = TinyVector<double, N>(1.0), 00598 typename CoordinateSteps<N>::type origin 00599 = TinyVector<double, N>(0.0)) 00600 { 00601 typedef SrcCoordinateMultiArrayRangeReturns<N, T> returns; 00602 typedef typename returns::type type; 00603 typedef typename returns::stride_type stride_type; 00604 typedef typename returns::access_type access_type; 00605 typedef typename returns::iterator_type iterator_type; 00606 typedef typename returns::shape_array_type shape_array_type; 00607 00608 shape_array_type shape = array.shape(); 00609 return type(iterator_type(array.traverser_begin().get(), 00610 stride_type(origin), 00611 array.stride(), 00612 stride_type(stride), 00613 shape), 00614 detail::dismember<N>(stride_type(shape)), 00615 access_type()); 00616 } 00617 00618 template <class VALUETYPE, class COORD> 00619 struct AccessorCoordinatePair 00620 { 00621 typedef VALUETYPE value_type; 00622 typedef COORD coord_type; 00623 typedef AccessorCoordinatePair type; 00624 00625 value_type v; 00626 const coord_type & c; 00627 00628 AccessorCoordinatePair(const value_type & v_, const coord_type & c_) 00629 : v(v_), c(c_) {} 00630 00631 const value_type & value() const 00632 { 00633 return v; 00634 } 00635 const coord_type & coord() const 00636 { 00637 return c; 00638 } 00639 }; 00640 00641 /** \brief Forward accessor to the value() part of the values an iterator 00642 points to. 00643 00644 CoordinateConstValueAccessor is a accessor that forwards 00645 the underlying accessor's operator() read functions. 00646 It passes its arguments <em>by value</em>. 00647 00648 <b>\#include</b> <vigra/coordinate_iterator.hxx><br> 00649 Namespace: vigra 00650 */ 00651 template <class Accessor, class COORD> 00652 class CoordinateConstValueAccessor 00653 { 00654 public: 00655 typedef typename Accessor::value_type forward_type; 00656 typedef AccessorCoordinatePair<forward_type, COORD> value_type; 00657 Accessor a; 00658 CoordinateConstValueAccessor(const Accessor & a_) : a(a_) {} 00659 /** Read the current data item. 00660 */ 00661 template <class ITERATOR> 00662 value_type operator()(ITERATOR const & i) const 00663 { 00664 const typename ITERATOR::value_type & x = *i; 00665 return value_type(a(&x.value()), x.coord()); 00666 } 00667 /** Read the data item at an offset. 00668 */ 00669 template <class ITERATOR, class DIFFERENCE> 00670 value_type operator()(ITERATOR const & i, DIFFERENCE const & diff) const 00671 { 00672 const typename ITERATOR::value_type & x = i[diff]; 00673 return value_type(a(&x.value()), x.coord()); 00674 } 00675 }; 00676 00677 template<unsigned N, class T, class Accessor> 00678 struct SrcCoordinateMultiArrayRangeAccessorReturns 00679 { 00680 typedef CombinedMultiIterator<N, T> iterator_type; 00681 typedef typename iterator_type::coord_type coord_type; 00682 typedef typename iterator_type::pair_type pair_type; 00683 typedef typename iterator_type::ptr_type ptr_type; 00684 typedef typename ptr_type::deref_type deref_type; 00685 typedef typename iterator_type::stride_type stride_type; 00686 typedef typename pair_type::stride_array_type stride_array_type; 00687 typedef typename pair_type::shape_array_type shape_array_type; 00688 00689 typedef CoordinateConstValueAccessor<Accessor, coord_type> access_type; 00690 typedef triple<iterator_type, stride_array_type, access_type> type; 00691 }; 00692 00693 template <unsigned int N, class T, class StrideTag, class Access> 00694 inline typename SrcCoordinateMultiArrayRangeAccessorReturns<N, T, Access>::type 00695 srcCoordinateMultiArrayRangeAccessor(const MultiArrayView<N, T, StrideTag> & 00696 array, 00697 Access a, 00698 typename CoordinateSteps<N>::type stride 00699 = TinyVector<double, N>(1.0), 00700 typename CoordinateSteps<N>::type origin 00701 = TinyVector<double, N>(0.0)) 00702 { 00703 typedef SrcCoordinateMultiArrayRangeAccessorReturns<N, T, Access> returns; 00704 typedef typename returns::type type; 00705 typedef typename returns::stride_type stride_type; 00706 typedef typename returns::access_type access_type; 00707 typedef typename returns::iterator_type iterator_type; 00708 typedef typename returns::shape_array_type shape_array_type; 00709 00710 shape_array_type shape = array.shape(); 00711 return type(iterator_type(array.traverser_begin().get(), 00712 stride_type(origin), 00713 array.stride(), 00714 stride_type(stride), 00715 shape), 00716 detail::dismember<N>(stride_type(shape)), 00717 access_type(a)); 00718 } 00719 00720 } // namespace vigra 00721 00722 namespace std { 00723 00724 template <unsigned N> 00725 ostream & 00726 operator<<(ostream & os, const vigra::StridePair<N> & x) 00727 { 00728 os << "[" << x.index << ", " << x.coord << "]"; 00729 return os; 00730 } 00731 00732 template <unsigned N> 00733 ostream & 00734 operator<<(ostream & os, const vigra::StridePairDiff<N> & x) 00735 { 00736 os << "<" << x.c << "; " 00737 << static_cast<vigra::StridePairCoord<N> >(x) << ">"; 00738 return os; 00739 } 00740 00741 template <unsigned N, class T> 00742 ostream & 00743 operator<<(ostream & os, const vigra::StridePairPointer<N, T> & x) 00744 { 00745 os << "[" << x.value() << ", " << x.coord() << "]"; 00746 return os; 00747 } 00748 00749 template <class VALUETYPE, class COORD> 00750 ostream & 00751 operator<<(ostream & os, 00752 const vigra::AccessorCoordinatePair<VALUETYPE, COORD> & x) 00753 { 00754 os << "[" << x.value() << ", " << x.coord() << "]"; 00755 return os; 00756 } 00757 00758 } // namespace std 00759 00760 #endif // VIGRA_COORDINATE_ITERATOR_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|