2 // Copyright 2005-2007 Adobe Systems Incorporated
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
8 #ifndef BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
9 #define BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
11 #include <boost/gil/concepts/basic.hpp>
12 #include <boost/gil/concepts/concept_check.hpp>
13 #include <boost/gil/concepts/fwd.hpp>
14 #include <boost/gil/concepts/pixel.hpp>
15 #include <boost/gil/concepts/pixel_dereference.hpp>
16 #include <boost/gil/concepts/pixel_iterator.hpp>
17 #include <boost/gil/concepts/point.hpp>
18 #include <boost/gil/concepts/detail/utility.hpp>
22 #include <type_traits>
24 #if defined(BOOST_CLANG)
25 #pragma clang diagnostic push
26 #pragma clang diagnostic ignored "-Wunknown-pragmas"
27 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
30 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
33 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
36 namespace boost { namespace gil {
38 /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
39 /// \ingroup PixelLocatorConcept
40 /// \brief N-dimensional locator
42 /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
43 /// \ingroup PixelLocatorConcept
44 /// \brief 2-dimensional locator
46 /// \defgroup PixelLocator2DConcept PixelLocatorConcept
47 /// \ingroup PixelLocatorConcept
48 /// \brief 2-dimensional locator over pixel data
50 /// \ingroup LocatorNDConcept
51 /// \brief N-dimensional locator over immutable values
54 /// concept RandomAccessNDLocatorConcept<Regular Loc>
56 /// typename value_type; // value over which the locator navigates
57 /// typename reference; // result of dereferencing
58 /// typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
59 /// typename const_t; // same as Loc, but operating over immutable values
60 /// typename cached_location_t; // type to store relative location (for efficient repeated access)
61 /// typename point_t = difference_type;
63 /// static const size_t num_dimensions; // dimensionality of the locator
64 /// where num_dimensions = point_t::num_dimensions;
66 /// // The difference_type and iterator type along each dimension. The iterators may only differ in
67 /// // difference_type. Their value_type must be the same as Loc::value_type
68 /// template <size_t D>
71 /// typename coord_t = point_t::axis<D>::coord_t;
72 /// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
73 /// where iterator::value_type == value_type;
76 /// // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
77 /// template <PixelDereferenceAdaptorConcept Deref>
81 /// where RandomAccessNDLocatorConcept<type>;
82 /// static type make(const Loc& loc, const Deref& deref);
85 /// Loc& operator+=(Loc&, const difference_type&);
86 /// Loc& operator-=(Loc&, const difference_type&);
87 /// Loc operator+(const Loc&, const difference_type&);
88 /// Loc operator-(const Loc&, const difference_type&);
90 /// reference operator*(const Loc&);
91 /// reference operator[](const Loc&, const difference_type&);
93 /// // Storing relative location for faster repeated access and accessing it
94 /// cached_location_t Loc::cache_location(const difference_type&) const;
95 /// reference operator[](const Loc&,const cached_location_t&);
97 /// // Accessing iterators along a given dimension at the current location or at a given offset
98 /// template <size_t D> axis<D>::iterator& Loc::axis_iterator();
99 /// template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
100 /// template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
103 template <typename Loc>
104 struct RandomAccessNDLocatorConcept
108 gil_function_requires<Regular<Loc>>();
110 // TODO: Should these be concept-checked instead of ignored? --mloskot
112 using value_type = typename Loc::value_type;
113 ignore_unused_variable_warning(value_type{});
115 // result of dereferencing
116 using reference = typename Loc::reference;
117 //ignore_unused_variable_warning(reference{});
119 // result of operator-(pixel_locator, pixel_locator)
120 using difference_type = typename Loc::difference_type;
121 ignore_unused_variable_warning(difference_type{});
123 // type used to store relative location (to allow for more efficient repeated access)
124 using cached_location_t = typename Loc::cached_location_t;
125 ignore_unused_variable_warning(cached_location_t{});
127 // same as this type, but over const values
128 using const_t = typename Loc::const_t;
129 ignore_unused_variable_warning(const_t{});
131 // same as difference_type
132 using point_t = typename Loc::point_t;
133 ignore_unused_variable_warning(point_t{});
135 static std::size_t const N = Loc::num_dimensions; ignore_unused_variable_warning(N);
137 using first_it_type = typename Loc::template axis<0>::iterator;
138 using last_it_type = typename Loc::template axis<N-1>::iterator;
139 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
140 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
142 // point_t must be an N-dimensional point, each dimension of which must
143 // have the same type as difference_type of the corresponding iterator
144 gil_function_requires<PointNDConcept<point_t>>();
145 static_assert(point_t::num_dimensions == N, "");
146 static_assert(std::is_same
148 typename std::iterator_traits<first_it_type>::difference_type,
149 typename point_t::template axis<0>::coord_t
151 static_assert(std::is_same
153 typename std::iterator_traits<last_it_type>::difference_type,
154 typename point_t::template axis<N-1>::coord_t
162 reference r1 = loc[d]; ignore_unused_variable_warning(r1);
163 reference r2 = *loc; ignore_unused_variable_warning(r2);
164 cached_location_t cl = loc.cache_location(d); ignore_unused_variable_warning(cl);
165 reference r3 = loc[d]; ignore_unused_variable_warning(r3);
167 first_it_type fi = loc.template axis_iterator<0>();
168 fi = loc.template axis_iterator<0>(d);
169 last_it_type li = loc.template axis_iterator<N-1>();
170 li = loc.template axis_iterator<N-1>(d);
172 using deref_t = PixelDereferenceAdaptorArchetype<typename Loc::value_type>;
173 using dtype = typename Loc::template add_deref<deref_t>::type;
174 // TODO: infinite recursion - FIXME?
175 //gil_function_requires<RandomAccessNDLocatorConcept<dtype>>();
180 /// \ingroup Locator2DConcept
181 /// \brief 2-dimensional locator over immutable values
184 /// concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc>
186 /// where num_dimensions==2;
187 /// where Point2DConcept<point_t>;
189 /// typename x_iterator = axis<0>::iterator;
190 /// typename y_iterator = axis<1>::iterator;
191 /// typename x_coord_t = axis<0>::coord_t;
192 /// typename y_coord_t = axis<1>::coord_t;
194 /// // Only available to locators that have dynamic step in Y
195 /// //Loc::Loc(const Loc& loc, y_coord_t);
197 /// // Only available to locators that have dynamic step in X and Y
198 /// //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
200 /// x_iterator& Loc::x();
201 /// x_iterator const& Loc::x() const;
202 /// y_iterator& Loc::y();
203 /// y_iterator const& Loc::y() const;
205 /// x_iterator Loc::x_at(const difference_type&) const;
206 /// y_iterator Loc::y_at(const difference_type&) const;
207 /// Loc Loc::xy_at(const difference_type&) const;
209 /// // x/y versions of all methods that can take difference type
210 /// x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
211 /// y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
212 /// Loc Loc::xy_at(x_coord_t, y_coord_t) const;
213 /// reference operator()(const Loc&, x_coord_t, y_coord_t);
214 /// cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
216 /// bool Loc::is_1d_traversable(x_coord_t width) const;
217 /// y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
220 template <typename Loc>
221 struct RandomAccess2DLocatorConcept
225 gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
226 static_assert(Loc::num_dimensions == 2, "");
228 using dynamic_x_step_t = typename dynamic_x_step_type<Loc>::type;
229 using dynamic_y_step_t = typename dynamic_y_step_type<Loc>::type;
230 using transposed_t = typename transposed_type<Loc>::type;
232 using cached_location_t = typename Loc::cached_location_t;
233 gil_function_requires<Point2DConcept<typename Loc::point_t>>();
235 using x_iterator = typename Loc::x_iterator;
236 using y_iterator = typename Loc::y_iterator;
237 using x_coord_t = typename Loc::x_coord_t;
238 using y_coord_t = typename Loc::y_coord_t;
240 x_coord_t xd = 0; ignore_unused_variable_warning(xd);
241 y_coord_t yd = 0; ignore_unused_variable_warning(yd);
243 typename Loc::difference_type d;
244 typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
246 dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
247 dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
249 using dynamic_xy_step_transposed_t = typename dynamic_y_step_type
251 typename dynamic_x_step_type<transposed_t>::type
253 dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
255 bool is_contiguous = loc.is_1d_traversable(xd);
256 ignore_unused_variable_warning(is_contiguous);
258 loc.y_distance_to(loc, xd);
261 loc = loc.xy_at(xd, yd);
263 x_iterator xit = loc.x_at(d);
264 xit = loc.x_at(xd, yd);
267 y_iterator yit = loc.y_at(d);
268 yit = loc.y_at(xd, yd);
271 cached_location_t cl = loc.cache_location(xd, yd);
272 ignore_unused_variable_warning(cl);
277 /// \ingroup PixelLocator2DConcept
278 /// \brief GIL's 2-dimensional locator over immutable GIL pixels
280 /// concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc>
282 /// where PixelValueConcept<value_type>;
283 /// where PixelIteratorConcept<x_iterator>;
284 /// where PixelIteratorConcept<y_iterator>;
285 /// where x_coord_t == y_coord_t;
287 /// typename coord_t = x_coord_t;
290 template <typename Loc>
291 struct PixelLocatorConcept
295 gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
296 gil_function_requires<PixelIteratorConcept<typename Loc::x_iterator>>();
297 gil_function_requires<PixelIteratorConcept<typename Loc::y_iterator>>();
298 using coord_t = typename Loc::coord_t;
299 static_assert(std::is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value, "");
306 /// \tparam Loc Models RandomAccessNDLocatorConcept
307 template <typename Loc>
308 struct RandomAccessNDLocatorIsMutableConcept
312 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
314 typename Loc::template axis<0>::iterator
316 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
318 typename Loc::template axis<Loc::num_dimensions-1>::iterator
321 typename Loc::difference_type d; initialize_it(d);
322 typename Loc::value_type v; initialize_it(v);
323 typename Loc::cached_location_t cl = loc.cache_location(d);
331 // \tparam Loc Models RandomAccess2DLocatorConcept
332 template <typename Loc>
333 struct RandomAccess2DLocatorIsMutableConcept
337 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
338 typename Loc::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
339 typename Loc::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
340 typename Loc::value_type v; initialize_it(v);
346 } // namespace detail
348 /// \ingroup LocatorNDConcept
349 /// \brief N-dimensional locator over mutable pixels
352 /// concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc>
354 /// where Mutable<reference>;
357 template <typename Loc>
358 struct MutableRandomAccessNDLocatorConcept
362 gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
363 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
367 /// \ingroup Locator2DConcept
368 /// \brief 2-dimensional locator over mutable pixels
371 /// concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc>
372 /// : MutableRandomAccessNDLocatorConcept<Loc> {};
374 template <typename Loc>
375 struct MutableRandomAccess2DLocatorConcept
379 gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
380 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
384 /// \ingroup PixelLocator2DConcept
385 /// \brief GIL's 2-dimensional locator over mutable GIL pixels
388 /// concept MutablePixelLocatorConcept<PixelLocatorConcept Loc>
389 /// : MutableRandomAccess2DLocatorConcept<Loc> {};
391 template <typename Loc>
392 struct MutablePixelLocatorConcept
396 gil_function_requires<PixelLocatorConcept<Loc>>();
397 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
401 }} // namespace boost::gil
403 #if defined(BOOST_CLANG)
404 #pragma clang diagnostic pop
407 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
408 #pragma GCC diagnostic pop