[ 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) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)