step_iterator.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003    
00004     Use, modification and distribution are subject to the Boost Software License,
00005     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
00006     http://www.boost.org/LICENSE_1_0.txt).
00007 
00008     See http://opensource.adobe.com/gil for most recent version including documentation.
00009 */
00010 
00011 /*************************************************************************************************/
00012 
00013 #ifndef GIL_STEP_ITERATOR_H
00014 #define GIL_STEP_ITERATOR_H
00015 
00024 
00025 #include <cstddef>
00026 #include <iterator>
00027 #include <boost/iterator/iterator_facade.hpp>
00028 #include "gil_config.hpp"
00029 #include "utilities.hpp"
00030 #include "pixel_iterator.hpp"
00031 #include "pixel_iterator_adaptor.hpp"
00032 
00033 namespace boost { namespace gil {
00034 
00038 
00039 
00040 namespace detail {
00041 
00048 
00049 template <typename Derived,  // type of the derived class
00050           typename Iterator, // Models Iterator
00051           typename SFn>      // A policy object that can compute the distance between two iterators of type Iterator
00052                              // and can advance an iterator of type Iterator a given number of Iterator's units  
00053 class step_iterator_adaptor : public iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type> {
00054 public:
00055     typedef iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type> parent_t;
00056     typedef typename std::iterator_traits<Iterator>::difference_type base_difference_type;
00057     typedef typename SFn::difference_type                           difference_type;
00058     typedef typename std::iterator_traits<Iterator>::reference       reference;
00059 
00060     step_iterator_adaptor() {}
00061     step_iterator_adaptor(const Iterator& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {}
00062 
00063     difference_type step() const { return _step_fn.step(); }
00064 
00065 protected:
00066     SFn _step_fn;
00067 private:
00068     friend class boost::iterator_core_access;
00069 
00070     void increment() { _step_fn.advance(this->base_reference(),1); }
00071     void decrement() { _step_fn.advance(this->base_reference(),-1); }
00072     void advance(base_difference_type d) { _step_fn.advance(this->base_reference(),d); }
00073     difference_type distance_to(const step_iterator_adaptor& it) const { return _step_fn.difference(this->base_reference(),it.base_reference()); }
00074 };
00075 
00076 // although iterator_adaptor defines these, the default implementation computes distance and compares for zero.
00077 // it is often faster to just apply the relation operator to the base
00078 template <typename D,typename Iterator,typename SFn> inline
00079 bool operator>(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) { 
00080     return p1.step()>0 ? p1.base()> p2.base() : p1.base()< p2.base(); 
00081 }
00082 
00083 template <typename D,typename Iterator,typename SFn> inline
00084 bool operator<(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) { 
00085     return p1.step()>0 ? p1.base()< p2.base() : p1.base()> p2.base(); 
00086 }
00087 
00088 template <typename D,typename Iterator,typename SFn> inline
00089 bool operator>=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) { 
00090     return p1.step()>0 ? p1.base()>=p2.base() : p1.base()<=p2.base(); 
00091 }
00092 
00093 template <typename D,typename Iterator,typename SFn> inline
00094 bool operator<=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) { 
00095     return p1.step()>0 ? p1.base()<=p2.base() : p1.base()>=p2.base(); 
00096 }
00097 
00098 template <typename D,typename Iterator,typename SFn> inline
00099 bool operator==(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) { 
00100     return p1.base()==p2.base(); 
00101 }
00102 
00103 template <typename D,typename Iterator,typename SFn> inline
00104 bool operator!=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) { 
00105     return p1.base()!=p2.base(); 
00106 }
00107 
00108 } // namespace detail
00109 
00113 
00129 
00132 template <typename Iterator>
00133 struct memunit_step_fn {
00134     typedef std::ptrdiff_t difference_type;
00135 
00136     memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {}
00137 
00138     difference_type difference(const Iterator& it1, const Iterator& it2) const { return memunit_distance(it1,it2)/_step; }
00139     void            advance(Iterator& it, difference_type d)             const { memunit_advance(it,d*_step); } 
00140     difference_type step()                                               const { return _step; }
00141 
00142     void            set_step(std::ptrdiff_t step) { _step=step; }
00143 private:
00144     GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
00145     difference_type _step;
00146 };
00147 
00148 template <typename Iterator>
00149 class memory_based_step_iterator : public detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>, 
00150                                                                             Iterator, 
00151                                                                             memunit_step_fn<Iterator> > {
00152     GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
00153 public:
00154     typedef detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>, 
00155                                           Iterator, 
00156                                           memunit_step_fn<Iterator> > parent_t;
00157     typedef typename parent_t::reference                            reference;
00158     typedef typename parent_t::difference_type                      difference_type;
00159     typedef Iterator                                                x_iterator;
00160 
00161     memory_based_step_iterator() : parent_t(Iterator()) {}
00162     memory_based_step_iterator(Iterator it, std::ptrdiff_t memunit_step) : parent_t(it, memunit_step_fn<Iterator>(memunit_step)) {}
00163     template <typename I2> 
00164     memory_based_step_iterator(const memory_based_step_iterator<I2>& it)
00165         : parent_t(it.base(), memunit_step_fn<Iterator>(it.step())) {}
00166 
00169     reference operator[](difference_type d) const { return *(*this+d); }
00170 
00171     void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); }
00172 
00173     x_iterator& base()              { return parent_t::base_reference(); }
00174     x_iterator const& base() const  { return parent_t::base_reference(); }
00175 };
00176 
00177 template <typename Iterator>
00178 struct const_iterator_type<memory_based_step_iterator<Iterator> > {
00179     typedef memory_based_step_iterator<typename const_iterator_type<Iterator>::type>  type;
00180 };
00181 
00182 template <typename Iterator>
00183 struct iterator_is_mutable<memory_based_step_iterator<Iterator> > : public iterator_is_mutable<Iterator> {};
00184 
00185 
00187 //  IteratorAdaptorConcept
00189 
00190 template <typename Iterator>
00191 struct is_iterator_adaptor<memory_based_step_iterator<Iterator> > : public mpl::true_{};
00192 
00193 template <typename Iterator>
00194 struct iterator_adaptor_get_base<memory_based_step_iterator<Iterator> > {
00195     typedef Iterator type;
00196 };
00197 
00198 template <typename Iterator, typename NewBaseIterator>
00199 struct iterator_adaptor_rebind<memory_based_step_iterator<Iterator>,NewBaseIterator> {
00200     typedef memory_based_step_iterator<NewBaseIterator> type;
00201 };
00202 
00204 //  PixelBasedConcept
00206 
00207 template <typename Iterator>
00208 struct color_space_type<memory_based_step_iterator<Iterator> > : public color_space_type<Iterator> {};
00209 
00210 template <typename Iterator>
00211 struct channel_mapping_type<memory_based_step_iterator<Iterator> > : public channel_mapping_type<Iterator> {};
00212 
00213 template <typename Iterator>
00214 struct is_planar<memory_based_step_iterator<Iterator> > : public is_planar<Iterator> {};
00215 
00216 template <typename Iterator>
00217 struct channel_type<memory_based_step_iterator<Iterator> > : public channel_type<Iterator> {};
00218 
00220 //  MemoryBasedIteratorConcept
00222 template <typename Iterator>
00223 struct byte_to_memunit<memory_based_step_iterator<Iterator> > : public byte_to_memunit<Iterator> {};
00224 
00225 template <typename Iterator>
00226 inline std::ptrdiff_t memunit_step(const memory_based_step_iterator<Iterator>& p) { return p.step(); }
00227 
00228 template <typename Iterator>
00229 inline std::ptrdiff_t memunit_distance(const memory_based_step_iterator<Iterator>& p1, 
00230                                     const memory_based_step_iterator<Iterator>& p2) { 
00231     return memunit_distance(p1.base(),p2.base()); 
00232 }
00233 
00234 template <typename Iterator>
00235 inline void memunit_advance(memory_based_step_iterator<Iterator>& p, 
00236                          std::ptrdiff_t diff) { 
00237     memunit_advance(p.base(), diff);
00238 }
00239 
00240 template <typename Iterator>
00241 inline memory_based_step_iterator<Iterator> 
00242 memunit_advanced(const memory_based_step_iterator<Iterator>& p, 
00243               std::ptrdiff_t diff) {
00244     return memory_based_step_iterator<Iterator>(memunit_advanced(p.base(), diff),p.step());
00245 }
00246 
00247 template <typename Iterator>
00248 inline typename std::iterator_traits<Iterator>::reference 
00249 memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p, 
00250                   std::ptrdiff_t diff) { 
00251     return memunit_advanced_ref(p.base(), diff);
00252 }
00253 
00255 //  HasDynamicXStepTypeConcept
00257 
00258 template <typename Iterator>
00259 struct dynamic_x_step_type<memory_based_step_iterator<Iterator> > {
00260     typedef memory_based_step_iterator<Iterator> type;
00261 };
00262 
00263 // For step iterators, pass the function object to the base
00264 template <typename Iterator, typename Deref>
00265 struct iterator_add_deref<memory_based_step_iterator<Iterator>,Deref> {
00266     GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
00267 
00268     typedef memory_based_step_iterator<typename iterator_add_deref<Iterator, Deref>::type> type;
00269 
00270     static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d) { return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step()); }
00271 };
00272 
00276 
00277 template <typename I> typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step);
00278 
00279 namespace detail {
00280 
00281 // if the iterator is a plain base iterator (non-adaptor), wraps it in memory_based_step_iterator
00282 template <typename I> 
00283 typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::false_) {
00284     return memory_based_step_iterator<I>(it, step);
00285 }
00286 
00287 // If the iterator is compound, put the step in its base
00288 template <typename I> 
00289 typename dynamic_x_step_type<I>::type make_step_iterator_impl(const I& it, std::ptrdiff_t step, mpl::true_) {
00290     return make_step_iterator(it.base(), step);
00291 }
00292 
00293 // If the iterator is memory_based_step_iterator, change the step
00294 template <typename BaseIt> 
00295 memory_based_step_iterator<BaseIt> make_step_iterator_impl(const memory_based_step_iterator<BaseIt>& it, std::ptrdiff_t step, mpl::true_) {
00296     return memory_based_step_iterator<BaseIt>(it.base(), step);
00297 }
00298 }
00299 
00313 template <typename I>  // Models MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept
00314 typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step) {
00315     return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor<I>::type());
00316 }
00317 
00318 } }  // namespace boost::gil
00319 
00320 #endif

Generated on Sat May 2 13:50:15 2009 for Generic Image Library by  doxygen 1.5.6