8 #ifndef BOOST_GIL_LOCATOR_HPP
9 #define BOOST_GIL_LOCATOR_HPP
11 #include <boost/gil/step_iterator.hpp>
12 #include <boost/gil/point.hpp>
14 #include <boost/assert.hpp>
18 namespace boost {
namespace gil {
23 template <
typename P> std::ptrdiff_t memunit_step(
const P*);
24 template <
typename P> P* memunit_advanced(
const P* p, std::ptrdiff_t diff);
25 template <
typename P> P& memunit_advanced_ref(P* p, std::ptrdiff_t diff);
26 template <
typename Iterator,
typename D>
struct iterator_add_deref;
27 template <
typename T>
class point;
30 template <std::
size_t D,
typename Loc>
class locator_axis;
33 template <
typename T>
struct channel_type;
34 template <
typename T>
struct color_space_type;
35 template <
typename T>
struct channel_mapping_type;
36 template <
typename T>
struct is_planar;
37 template <
typename T>
struct num_channels;
42 template <
typename LocatorOrView>
45 using type = LocatorOrView;
107 template <
typename Loc,
typename XIterator,
typename YIterator>
111 using x_iterator = XIterator;
112 using y_iterator = YIterator;
115 static const std::size_t num_dimensions=2;
116 using value_type =
typename std::iterator_traits<x_iterator>::value_type;
117 using reference =
typename std::iterator_traits<x_iterator>::reference;
118 using coord_t =
typename std::iterator_traits<x_iterator>::difference_type;
121 template <std::
size_t D>
struct axis
123 using coord_t =
typename detail::locator_axis<D,Loc>::coord_t;
124 using iterator =
typename detail::locator_axis<D,Loc>::iterator;
128 using x_coord_t =
typename point_t::template axis<0>::coord_t;
129 using y_coord_t =
typename point_t::template axis<1>::coord_t;
131 bool operator!=(
const Loc& p)
const {
return !(concrete()==p); }
133 x_iterator x_at(x_coord_t dx, y_coord_t dy)
const { Loc tmp=concrete(); tmp+=
point_t(dx,dy);
return tmp.x(); }
134 x_iterator x_at(
const difference_type& d)
const { Loc tmp=concrete(); tmp+=d;
return tmp.x(); }
135 y_iterator y_at(x_coord_t dx, y_coord_t dy)
const { Loc tmp=concrete(); tmp+=
point_t(dx,dy);
return tmp.y(); }
136 y_iterator y_at(
const difference_type& d)
const { Loc tmp=concrete(); tmp+=d;
return tmp.y(); }
137 Loc xy_at(x_coord_t dx, y_coord_t dy)
const { Loc tmp=concrete(); tmp+=
point_t(dx,dy);
return tmp; }
138 Loc xy_at(
const difference_type& d)
const { Loc tmp=concrete(); tmp+=d;
return tmp; }
140 template <std::
size_t D>
typename axis<D>::iterator& axis_iterator() {
return detail::locator_axis<D,Loc>()(concrete()); }
141 template <std::
size_t D>
typename axis<D>::iterator
const& axis_iterator()
const {
return detail::locator_axis<D,Loc>()(concrete()); }
142 template <std::
size_t D>
typename axis<D>::iterator axis_iterator(
point_t const& p)
const {
return detail::locator_axis<D,Loc>()(concrete(),p); }
144 reference operator()(x_coord_t dx, y_coord_t dy)
const {
return *x_at(dx,dy); }
145 reference operator[](
const difference_type& d)
const {
return *x_at(d.x,d.y); }
147 reference operator*()
const {
return *concrete().x(); }
149 Loc& operator+=(
const difference_type& d) { concrete().x()+=d.x; concrete().y()+=d.y;
return concrete(); }
150 Loc& operator-=(
const difference_type& d) { concrete().x()-=d.x; concrete().y()-=d.y;
return concrete(); }
161 Loc& concrete() {
return (Loc&)*
this; }
162 const Loc& concrete()
const {
return (
const Loc&)*
this; }
164 template <
typename X>
friend class pixel_2d_locator;
169 template <
typename Loc>
170 class locator_axis<0,Loc> {
171 using point_t =
typename Loc::point_t;
173 using coord_t =
typename point_t::template axis<0>::coord_t;
174 using iterator =
typename Loc::x_iterator;
176 inline iterator& operator()( Loc& loc)
const {
return loc.x(); }
177 inline iterator
const& operator()(
const Loc& loc)
const {
return loc.x(); }
178 inline iterator operator()( Loc& loc, point_t
const& d)
const {
return loc.x_at(d); }
179 inline iterator operator()(
const Loc& loc, point_t
const& d)
const {
return loc.x_at(d); }
182 template <
typename Loc>
183 class locator_axis<1,Loc> {
184 using point_t =
typename Loc::point_t;
186 using coord_t =
typename point_t::template axis<1>::coord_t;
187 using iterator =
typename Loc::y_iterator;
189 inline iterator& operator()( Loc& loc)
const {
return loc.y(); }
190 inline iterator
const& operator()(
const Loc& loc)
const {
return loc.y(); }
191 inline iterator operator()( Loc& loc, point_t
const& d)
const {
return loc.y_at(d); }
192 inline iterator operator()(
const Loc& loc, point_t
const& d)
const {
return loc.y_at(d); }
196 template <
typename Loc,
typename XIt,
typename YIt>
197 struct channel_type<pixel_2d_locator_base<Loc,XIt,YIt> > :
public channel_type<XIt> {};
199 template <
typename Loc,
typename XIt,
typename YIt>
200 struct color_space_type<pixel_2d_locator_base<Loc,XIt,YIt> > :
public color_space_type<XIt> {};
202 template <
typename Loc,
typename XIt,
typename YIt>
203 struct channel_mapping_type<pixel_2d_locator_base<Loc,XIt,YIt> > :
public channel_mapping_type<XIt> {};
205 template <
typename Loc,
typename XIt,
typename YIt>
206 struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > :
public is_planar<XIt> {};
229 template <
typename StepIterator>
237 using coord_t =
typename parent_t::coord_t;
238 using x_coord_t =
typename parent_t::x_coord_t;
239 using y_coord_t =
typename parent_t::y_coord_t;
240 using x_iterator =
typename parent_t::x_iterator;
241 using y_iterator =
typename parent_t::y_iterator;
243 using reference =
typename parent_t::reference;
245 template <
typename Deref>
struct add_deref
257 : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step),
258 (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {}
265 bool operator==(
const this_t& p)
const {
return _p==p._p; }
267 x_iterator
const& x()
const {
return _p.base(); }
268 y_iterator
const& y()
const {
return _p; }
269 x_iterator& x() {
return _p.base(); }
270 y_iterator& y() {
return _p; }
273 x_iterator x_at (x_coord_t dx, y_coord_t dy)
const {
return memunit_advanced(x(), offset(dx,dy)); }
274 x_iterator x_at (
const difference_type& d)
const {
return memunit_advanced(x(), offset(d.x,d.y)); }
275 this_t xy_at (x_coord_t dx, y_coord_t dy)
const {
return this_t(x_at( dx , dy ), row_size()); }
276 this_t xy_at (
const difference_type& d)
const {
return this_t(x_at( d.x, d.y), row_size()); }
277 reference operator()(x_coord_t dx, y_coord_t dy)
const {
return memunit_advanced_ref(x(),offset(dx,dy)); }
278 reference operator[](
const difference_type& d)
const {
return memunit_advanced_ref(x(),offset(d.x,d.y)); }
279 this_t& operator+=(
const difference_type& d) { memunit_advance(x(),offset(d.x,d.y));
return *
this; }
280 this_t& operator-=(
const difference_type& d) { memunit_advance(x(),offset(-d.x,-d.y));
return *
this; }
283 using cached_location_t = std::ptrdiff_t;
284 cached_location_t cache_location(
const difference_type& d)
const {
return offset(d.x,d.y); }
285 cached_location_t cache_location(x_coord_t dx, y_coord_t dy)
const {
return offset(dx,dy); }
286 reference operator[](
const cached_location_t& loc)
const {
return memunit_advanced_ref(x(),loc); }
289 std::ptrdiff_t row_size()
const {
return memunit_step(y()); }
290 std::ptrdiff_t pixel_size()
const {
return memunit_step(x()); }
292 bool is_1d_traversable(x_coord_t width)
const {
return row_size()-pixel_size()*width==0; }
295 std::ptrdiff_t y_distance_to(
this_t const& p2, x_coord_t xDiff)
const
297 std::ptrdiff_t rowDiff = memunit_distance(x(), p2.x()) - pixel_size() * xDiff;
298 BOOST_ASSERT((rowDiff % row_size()) == 0);
299 return rowDiff / row_size();
304 std::ptrdiff_t offset(x_coord_t x, y_coord_t y)
const {
return y*row_size() + x*pixel_size(); }
312 template <
typename SI>
313 struct color_space_type<
memory_based_2d_locator<SI> > :
public color_space_type<typename memory_based_2d_locator<SI>::parent_t> {
316 template <
typename SI>
317 struct channel_mapping_type<memory_based_2d_locator<SI> > :
public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
320 template <
typename SI>
321 struct is_planar<memory_based_2d_locator<SI> > :
public is_planar<typename memory_based_2d_locator<SI>::parent_t> {
324 template <
typename SI>
325 struct channel_type<memory_based_2d_locator<SI> > :
public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
333 template <
typename SI>
334 struct dynamic_x_step_type<memory_based_2d_locator<SI> > {
336 using base_iterator_t =
typename iterator_adaptor_get_base<SI>::type;
337 using base_iterator_step_t =
typename dynamic_x_step_type<base_iterator_t>::type;
338 using dynamic_step_base_t =
typename iterator_adaptor_rebind<SI, base_iterator_step_t>::type;
340 using type = memory_based_2d_locator<dynamic_step_base_t>;
347 template <
typename SI>
348 struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
349 using type = memory_based_2d_locator<SI>;
Memory-based pixel locator. Models: PixelLocatorConcept,HasDynamicXStepTypeConcept,...
Definition: locator.hpp:230
base class for models of PixelLocatorConcept
Definition: locator.hpp:109
2D point both axes of which have the same dimension typeModels: Point2DConcept
Definition: point.hpp:36
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36
Step iterator concept.
Definition: concepts/pixel_iterator.hpp:258
returns the base iterator for a given iterator adaptor. Provide an specialization when introducing ne...
Definition: metafunctions.hpp:36
Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor ...
Definition: pixel_iterator_adaptor.hpp:176
Definition: locator.hpp:44