step_iterator.hppGo 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 1.5.6 |