Warning, file /include/boost/gil/step_iterator.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_STEP_ITERATOR_HPP
0009 #define BOOST_GIL_STEP_ITERATOR_HPP
0010
0011 #include <boost/gil/dynamic_step.hpp>
0012 #include <boost/gil/pixel_iterator.hpp>
0013 #include <boost/gil/pixel_iterator_adaptor.hpp>
0014 #include <boost/gil/utilities.hpp>
0015
0016 #include <boost/iterator/iterator_facade.hpp>
0017
0018 #include <cstddef>
0019 #include <iterator>
0020 #include <type_traits>
0021
0022 namespace boost { namespace gil {
0023
0024
0025
0026
0027
0028 namespace detail {
0029
0030
0031
0032
0033
0034
0035
0036
0037 template <typename Derived,
0038 typename Iterator,
0039 typename SFn>
0040
0041 class step_iterator_adaptor : public iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type>
0042 {
0043 public:
0044 using parent_t = iterator_adaptor<Derived, Iterator, use_default, use_default, use_default, typename SFn::difference_type>;
0045 using base_difference_type = typename std::iterator_traits<Iterator>::difference_type;
0046 using difference_type = typename SFn::difference_type;
0047 using reference = typename std::iterator_traits<Iterator>::reference;
0048
0049 step_iterator_adaptor() {}
0050 step_iterator_adaptor(Iterator const& it, SFn step_fn=SFn()) : parent_t(it), _step_fn(step_fn) {}
0051
0052 auto step() const -> difference_type { return _step_fn.step(); }
0053
0054 protected:
0055 SFn _step_fn;
0056 private:
0057 friend class boost::iterator_core_access;
0058
0059 void increment() { _step_fn.advance(this->base_reference(),1); }
0060 void decrement() { _step_fn.advance(this->base_reference(),-1); }
0061 void advance(base_difference_type d) { _step_fn.advance(this->base_reference(),d); }
0062
0063 auto distance_to(step_iterator_adaptor const& it) const -> difference_type
0064 {
0065 return _step_fn.difference(this->base_reference(),it.base_reference());
0066 }
0067 };
0068
0069
0070
0071 template <typename D,typename Iterator,typename SFn> inline
0072 bool operator>(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
0073 return p1.step()>0 ? p1.base()> p2.base() : p1.base()< p2.base();
0074 }
0075
0076 template <typename D,typename Iterator,typename SFn> inline
0077 bool operator<(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
0078 return p1.step()>0 ? p1.base()< p2.base() : p1.base()> p2.base();
0079 }
0080
0081 template <typename D,typename Iterator,typename SFn> inline
0082 bool operator>=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
0083 return p1.step()>0 ? p1.base()>=p2.base() : p1.base()<=p2.base();
0084 }
0085
0086 template <typename D,typename Iterator,typename SFn> inline
0087 bool operator<=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
0088 return p1.step()>0 ? p1.base()<=p2.base() : p1.base()>=p2.base();
0089 }
0090
0091 template <typename D,typename Iterator,typename SFn> inline
0092 bool operator==(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
0093 return p1.base()==p2.base();
0094 }
0095
0096 template <typename D,typename Iterator,typename SFn> inline
0097 bool operator!=(const step_iterator_adaptor<D,Iterator,SFn>& p1, const step_iterator_adaptor<D,Iterator,SFn>& p2) {
0098 return p1.base()!=p2.base();
0099 }
0100
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 template <typename Iterator>
0126 struct memunit_step_fn {
0127 using difference_type = std::ptrdiff_t;
0128
0129 memunit_step_fn(difference_type step=memunit_step(Iterator())) : _step(step) {}
0130
0131 auto difference(Iterator const& it1, Iterator const& it2) const -> difference_type
0132 {
0133 return memunit_distance(it1,it2)/_step;
0134 }
0135
0136 void advance(Iterator& it, difference_type d) const { memunit_advance(it,d*_step); }
0137 auto step() const -> difference_type { return _step; }
0138
0139 void set_step(std::ptrdiff_t step) { _step=step; }
0140 private:
0141 BOOST_GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
0142 difference_type _step;
0143 };
0144
0145 template <typename Iterator>
0146 class memory_based_step_iterator : public detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
0147 Iterator,
0148 memunit_step_fn<Iterator>>
0149 {
0150 BOOST_GIL_CLASS_REQUIRE(Iterator, boost::gil, MemoryBasedIteratorConcept)
0151 public:
0152 using parent_t = detail::step_iterator_adaptor<memory_based_step_iterator<Iterator>,
0153 Iterator,
0154 memunit_step_fn<Iterator>>;
0155 using reference = typename parent_t::reference;
0156 using difference_type = typename parent_t::difference_type;
0157 using x_iterator = Iterator;
0158
0159 memory_based_step_iterator() : parent_t(Iterator()) {}
0160 memory_based_step_iterator(Iterator it, std::ptrdiff_t memunit_step) : parent_t(it, memunit_step_fn<Iterator>(memunit_step)) {}
0161 template <typename I2>
0162 memory_based_step_iterator(const memory_based_step_iterator<I2>& it)
0163 : parent_t(it.base(), memunit_step_fn<Iterator>(it.step())) {}
0164
0165
0166
0167 auto operator[](difference_type d) const -> reference { return *(*this+d); }
0168
0169 void set_step(std::ptrdiff_t memunit_step) { this->_step_fn.set_step(memunit_step); }
0170
0171 auto base() -> x_iterator& { return parent_t::base_reference(); }
0172 auto base() const -> x_iterator const& { return parent_t::base_reference(); }
0173 };
0174
0175 template <typename Iterator>
0176 struct const_iterator_type<memory_based_step_iterator<Iterator>> {
0177 using type = memory_based_step_iterator<typename const_iterator_type<Iterator>::type>;
0178 };
0179
0180 template <typename Iterator>
0181 struct iterator_is_mutable<memory_based_step_iterator<Iterator>> : public iterator_is_mutable<Iterator> {};
0182
0183
0184
0185
0186
0187
0188 template <typename Iterator>
0189 struct is_iterator_adaptor<memory_based_step_iterator<Iterator>> : std::true_type {};
0190
0191 template <typename Iterator>
0192 struct iterator_adaptor_get_base<memory_based_step_iterator<Iterator>>
0193 {
0194 using type = Iterator;
0195 };
0196
0197 template <typename Iterator, typename NewBaseIterator>
0198 struct iterator_adaptor_rebind<memory_based_step_iterator<Iterator>, NewBaseIterator>
0199 {
0200 using type = memory_based_step_iterator<NewBaseIterator>;
0201 };
0202
0203
0204
0205
0206
0207 template <typename Iterator>
0208 struct color_space_type<memory_based_step_iterator<Iterator>> : public color_space_type<Iterator> {};
0209
0210 template <typename Iterator>
0211 struct channel_mapping_type<memory_based_step_iterator<Iterator>> : public channel_mapping_type<Iterator> {};
0212
0213 template <typename Iterator>
0214 struct is_planar<memory_based_step_iterator<Iterator>> : public is_planar<Iterator> {};
0215
0216 template <typename Iterator>
0217 struct channel_type<memory_based_step_iterator<Iterator>> : public channel_type<Iterator> {};
0218
0219
0220
0221
0222 template <typename Iterator>
0223 struct byte_to_memunit<memory_based_step_iterator<Iterator>> : public byte_to_memunit<Iterator> {};
0224
0225 template <typename Iterator>
0226 inline auto memunit_step(memory_based_step_iterator<Iterator> const& p) -> std::ptrdiff_t { return p.step(); }
0227
0228 template <typename Iterator>
0229 inline auto memunit_distance(memory_based_step_iterator<Iterator> const& p1, memory_based_step_iterator<Iterator> const& p2)
0230 -> std::ptrdiff_t
0231 {
0232 return memunit_distance(p1.base(),p2.base());
0233 }
0234
0235 template <typename Iterator>
0236 inline void memunit_advance(memory_based_step_iterator<Iterator>& p,
0237 std::ptrdiff_t diff) {
0238 memunit_advance(p.base(), diff);
0239 }
0240
0241 template <typename Iterator>
0242 inline auto memunit_advanced(const memory_based_step_iterator<Iterator>& p, std::ptrdiff_t diff)
0243 -> memory_based_step_iterator<Iterator>
0244 {
0245 return memory_based_step_iterator<Iterator>(memunit_advanced(p.base(), diff),p.step());
0246 }
0247
0248 template <typename Iterator>
0249 inline auto memunit_advanced_ref(const memory_based_step_iterator<Iterator>& p, std::ptrdiff_t diff)
0250 -> typename std::iterator_traits<Iterator>::reference
0251 {
0252 return memunit_advanced_ref(p.base(), diff);
0253 }
0254
0255
0256
0257
0258
0259 template <typename Iterator>
0260 struct dynamic_x_step_type<memory_based_step_iterator<Iterator>> {
0261 using type = memory_based_step_iterator<Iterator>;
0262 };
0263
0264
0265 template <typename Iterator, typename Deref>
0266 struct iterator_add_deref<memory_based_step_iterator<Iterator>,Deref> {
0267 BOOST_GIL_CLASS_REQUIRE(Deref, boost::gil, PixelDereferenceAdaptorConcept)
0268
0269 using type = memory_based_step_iterator<typename iterator_add_deref<Iterator, Deref>::type>;
0270
0271 static type make(const memory_based_step_iterator<Iterator>& it, const Deref& d)
0272 {
0273 return type(iterator_add_deref<Iterator, Deref>::make(it.base(),d),it.step());
0274 }
0275 };
0276
0277
0278
0279
0280
0281 template <typename I> typename dynamic_x_step_type<I>::type make_step_iterator(const I& it, std::ptrdiff_t step);
0282
0283 namespace detail {
0284
0285
0286 template <typename I>
0287 auto make_step_iterator_impl(I const& it, std::ptrdiff_t step, std::false_type)
0288 -> typename dynamic_x_step_type<I>::type
0289 {
0290 return memory_based_step_iterator<I>(it, step);
0291 }
0292
0293
0294 template <typename I>
0295 auto make_step_iterator_impl(I const& it, std::ptrdiff_t step, std::true_type)
0296 -> typename dynamic_x_step_type<I>::type
0297 {
0298 return make_step_iterator(it.base(), step);
0299 }
0300
0301
0302 template <typename BaseIt>
0303 auto make_step_iterator_impl(
0304 memory_based_step_iterator<BaseIt> const& it,
0305 std::ptrdiff_t step,
0306 std::true_type)
0307 -> memory_based_step_iterator<BaseIt>
0308 {
0309 return memory_based_step_iterator<BaseIt>(it.base(), step);
0310 }
0311
0312 }
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 template <typename I>
0328 inline auto make_step_iterator(I const& it, std::ptrdiff_t step)
0329 -> typename dynamic_x_step_type<I>::type
0330 {
0331 return detail::make_step_iterator_impl(it, step, typename is_iterator_adaptor<I>::type());
0332 }
0333
0334 }}
0335
0336 #endif