Boost GIL


iterator_from_2d.hpp
1//
2// Copyright 2005-2007 Adobe Systems Incorporated
3//
4// Distributed under the Boost Software License, Version 1.0
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7//
8#ifndef BOOST_GIL_ITERATOR_FROM_2D_HPP
9#define BOOST_GIL_ITERATOR_FROM_2D_HPP
10
11#include <boost/gil/concepts.hpp>
12#include <boost/gil/locator.hpp>
13#include <boost/gil/pixel_iterator.hpp>
14#include <boost/gil/point.hpp>
15
16#include <boost/assert.hpp>
17#include <boost/stl_interfaces/iterator_interface.hpp>
18
19namespace boost { namespace gil {
20
22
28
29
33
34
40
41template <typename Loc2> // Models PixelLocatorConcept
42class iterator_from_2d : public stl_interfaces::iterator_interface<
43#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
44 iterator_from_2d<Loc2>,
45#endif
46 std::random_access_iterator_tag,
47 typename Loc2::value_type,
48 typename Loc2::reference>
49{
50 BOOST_GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
51
52 using parent_t = stl_interfaces::iterator_interface<
53#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
55#endif
56 std::random_access_iterator_tag,
57 typename Loc2::value_type,
58 typename Loc2::reference>;
59
60public:
61 using difference_type = typename parent_t::difference_type;
62 using reference = typename parent_t::reference;
63 using iterator_category = typename parent_t::iterator_concept;
64
65 using x_iterator = typename Loc2::x_iterator;
66 using point_t = typename Loc2::point_t;
67
68 std::ptrdiff_t width() const { return _width; } // number of pixels per image row
69 std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
70 std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
71
72 bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
73 x_iterator& x() { return _p.x(); }
74
75 iterator_from_2d() = default;
76 iterator_from_2d(const Loc2& p, std::ptrdiff_t width, std::ptrdiff_t x=0, std::ptrdiff_t y=0) : _coords(x,y), _width(width), _p(p) {}
77 iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
78 template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
79 iterator_from_2d& operator=(iterator_from_2d const& other) = default;
80
81 constexpr auto operator*() const noexcept -> reference { return dereference(); }
82
83 constexpr auto operator+=(difference_type d) -> iterator_from_2d& { advance(d); return *this; }
84
85 constexpr auto operator++() noexcept -> iterator_from_2d& { increment(); return *this; }
86 constexpr auto operator--() noexcept -> iterator_from_2d& { decrement(); return *this; }
87
88 constexpr auto operator++(int) noexcept -> iterator_from_2d { auto tmp = *this; increment(); return tmp; }
89 constexpr auto operator--(int) noexcept -> iterator_from_2d { auto tmp = *this; decrement(); return tmp; }
90
91 constexpr auto operator-(iterator_from_2d other) const noexcept { return -distance_to(other); }
92
93 constexpr bool operator==(iterator_from_2d other) const noexcept { return equal(other); }
94
95private:
96 template <typename Loc> friend class iterator_from_2d;
97
98 friend struct boost::stl_interfaces::access;
99
100 reference dereference() const { return *_p; }
101 void increment() {
102 ++_coords.x;
103 ++_p.x();
104 if (_coords.x>=_width) {
105 _coords.x=0;
106 ++_coords.y;
107 _p+=point_t(-_width,1);
108 }
109 }
110 void decrement() {
111 --_coords.x;
112 --_p.x();
113 if (_coords.x<0) {
114 _coords.x=_width-1;
115 --_coords.y;
116 _p+=point_t(_width,-1);
117 }
118 }
119
120 BOOST_FORCEINLINE void advance(difference_type d) {
121 if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
122 point_t delta;
123 if (_coords.x+d>=0) { // not going back to a previous row?
124 delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
125 delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
126 } else {
127 delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
128 delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
129 }
130 _p+=delta;
131 _coords.x+=delta.x;
132 _coords.y+=delta.y;
133 }
134
135 difference_type distance_to(const iterator_from_2d& it) const {
136 if (_width==0) return 0;
137 return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
138 }
139
140 bool equal(iterator_from_2d const& it) const
141 {
142 BOOST_ASSERT(_width == it.width()); // they must belong to the same image
143 return _coords == it._coords && _p == it._p;
144 }
145
146 point_t _coords;
147 std::ptrdiff_t _width;
148 Loc2 _p;
149};
150
151template <typename Loc> // Models PixelLocatorConcept
154};
155
156template <typename Loc> // Models PixelLocatorConcept
157struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
158
159
161// HasDynamicXStepTypeConcept
163
164template <typename Loc>
165struct dynamic_x_step_type<iterator_from_2d<Loc> > {
166 using type = iterator_from_2d<typename dynamic_x_step_type<Loc>::type>;
167};
168
169
171// PixelBasedConcept
173
174template <typename Loc> // Models PixelLocatorConcept
175struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
176
177template <typename Loc> // Models PixelLocatorConcept
178struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
179
180template <typename Loc> // Models PixelLocatorConcept
181struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
182
183template <typename Loc> // Models PixelLocatorConcept
184struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
185
186} } // namespace boost::gil
187
188#endif
Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept,...
Definition iterator_from_2d.hpp:49
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition algorithm.hpp:36
GIL's 2-dimensional locator over immutable GIL pixels.
Definition pixel_locator.hpp:292
Returns the type of an iterator just like the input iterator, except operating over immutable values.
Definition pixel_iterator.hpp:40