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

vigra/coordinate_iterator.hxx VIGRA

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)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Nov 6 2012)