00001
00002
00003
00004
00005
00006
00007
00008
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,
00050 typename Iterator,
00051 typename SFn>
00052
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
00077
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 }
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
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
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
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
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
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
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
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
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>
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 } }
00319
00320 #endif