summaryrefslogtreecommitdiff
path: root/boost/gil/concepts/pixel_locator.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/concepts/pixel_locator.hpp')
-rw-r--r--boost/gil/concepts/pixel_locator.hpp408
1 files changed, 408 insertions, 0 deletions
diff --git a/boost/gil/concepts/pixel_locator.hpp b/boost/gil/concepts/pixel_locator.hpp
new file mode 100644
index 0000000000..4ef610c024
--- /dev/null
+++ b/boost/gil/concepts/pixel_locator.hpp
@@ -0,0 +1,408 @@
+//
+// Copyright 2005-2007 Adobe Systems Incorporated
+//
+// Distributed under the Boost Software License, Version 1.0
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+#ifndef BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
+#define BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
+
+#include <boost/gil/concepts/basic.hpp>
+#include <boost/gil/concepts/concept_check.hpp>
+#include <boost/gil/concepts/fwd.hpp>
+#include <boost/gil/concepts/pixel_dereference.hpp>
+#include <boost/gil/concepts/pixel_iterator.hpp>
+#include <boost/gil/concepts/point.hpp>
+#include <boost/gil/concepts/detail/utility.hpp>
+
+#include <cstddef>
+#include <iterator>
+
+#if defined(BOOST_CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-local-typedefs"
+#endif
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+namespace boost { namespace gil {
+
+/// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
+/// \ingroup PixelLocatorConcept
+/// \brief N-dimensional locator
+
+/// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
+/// \ingroup PixelLocatorConcept
+/// \brief 2-dimensional locator
+
+/// \defgroup PixelLocator2DConcept PixelLocatorConcept
+/// \ingroup PixelLocatorConcept
+/// \brief 2-dimensional locator over pixel data
+
+/// \ingroup LocatorNDConcept
+/// \brief N-dimensional locator over immutable values
+///
+/// \code
+/// concept RandomAccessNDLocatorConcept<Regular Loc>
+/// {
+/// typename value_type; // value over which the locator navigates
+/// typename reference; // result of dereferencing
+/// typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
+/// typename const_t; // same as Loc, but operating over immutable values
+/// typename cached_location_t; // type to store relative location (for efficient repeated access)
+/// typename point_t = difference_type;
+///
+/// static const size_t num_dimensions; // dimensionality of the locator
+/// where num_dimensions = point_t::num_dimensions;
+///
+/// // The difference_type and iterator type along each dimension. The iterators may only differ in
+/// // difference_type. Their value_type must be the same as Loc::value_type
+/// template <size_t D>
+/// struct axis
+/// {
+/// typename coord_t = point_t::axis<D>::coord_t;
+/// typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
+/// where iterator::value_type == value_type;
+/// };
+///
+/// // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
+/// template <PixelDereferenceAdaptorConcept Deref>
+/// struct add_deref
+/// {
+/// typename type;
+/// where RandomAccessNDLocatorConcept<type>;
+/// static type make(const Loc& loc, const Deref& deref);
+/// };
+///
+/// Loc& operator+=(Loc&, const difference_type&);
+/// Loc& operator-=(Loc&, const difference_type&);
+/// Loc operator+(const Loc&, const difference_type&);
+/// Loc operator-(const Loc&, const difference_type&);
+///
+/// reference operator*(const Loc&);
+/// reference operator[](const Loc&, const difference_type&);
+///
+/// // Storing relative location for faster repeated access and accessing it
+/// cached_location_t Loc::cache_location(const difference_type&) const;
+/// reference operator[](const Loc&,const cached_location_t&);
+///
+/// // Accessing iterators along a given dimension at the current location or at a given offset
+/// template <size_t D> axis<D>::iterator& Loc::axis_iterator();
+/// template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
+/// template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
+/// };
+/// \endcode
+template <typename Loc>
+struct RandomAccessNDLocatorConcept
+{
+ void constraints()
+ {
+ gil_function_requires<Regular<Loc>>();
+
+ // TODO: Should these be concept-checked instead of ignored? --mloskot
+
+ using value_type = typename Loc::value_type;
+ ignore_unused_variable_warning(value_type{});
+
+ // result of dereferencing
+ using reference = typename Loc::reference;
+ //ignore_unused_variable_warning(reference{});
+
+ // result of operator-(pixel_locator, pixel_locator)
+ using difference_type = typename Loc::difference_type;
+ ignore_unused_variable_warning(difference_type{});
+
+ // type used to store relative location (to allow for more efficient repeated access)
+ using cached_location_t = typename Loc::cached_location_t;
+ ignore_unused_variable_warning(cached_location_t{});
+
+ // same as this type, but over const values
+ using const_t = typename Loc::const_t;
+ ignore_unused_variable_warning(const_t{});
+
+ // same as difference_type
+ using point_t = typename Loc::point_t;
+ ignore_unused_variable_warning(point_t{});
+
+ static std::size_t const N = Loc::num_dimensions; ignore_unused_variable_warning(N);
+
+ using first_it_type = typename Loc::template axis<0>::iterator;
+ using last_it_type = typename Loc::template axis<N-1>::iterator;
+ gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
+ gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
+
+ // point_t must be an N-dimensional point, each dimension of which must
+ // have the same type as difference_type of the corresponding iterator
+ gil_function_requires<PointNDConcept<point_t>>();
+ static_assert(point_t::num_dimensions == N, "");
+ static_assert(is_same
+ <
+ typename std::iterator_traits<first_it_type>::difference_type,
+ typename point_t::template axis<0>::coord_t
+ >::value, "");
+ static_assert(is_same
+ <
+ typename std::iterator_traits<last_it_type>::difference_type,
+ typename point_t::template axis<N-1>::coord_t
+ >::value, "");
+
+ difference_type d;
+ loc += d;
+ loc -= d;
+ loc = loc + d;
+ loc = loc - d;
+ reference r1 = loc[d]; ignore_unused_variable_warning(r1);
+ reference r2 = *loc; ignore_unused_variable_warning(r2);
+ cached_location_t cl = loc.cache_location(d); ignore_unused_variable_warning(cl);
+ reference r3 = loc[d]; ignore_unused_variable_warning(r3);
+
+ first_it_type fi = loc.template axis_iterator<0>();
+ fi = loc.template axis_iterator<0>(d);
+ last_it_type li = loc.template axis_iterator<N-1>();
+ li = loc.template axis_iterator<N-1>(d);
+
+ using deref_t = PixelDereferenceAdaptorArchetype<typename Loc::value_type>;
+ using dtype = typename Loc::template add_deref<deref_t>::type;
+ // TODO: infinite recursion - FIXME?
+ //gil_function_requires<RandomAccessNDLocatorConcept<dtype>>();
+ }
+ Loc loc;
+};
+
+/// \ingroup Locator2DConcept
+/// \brief 2-dimensional locator over immutable values
+///
+/// \code
+/// concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc>
+/// {
+/// where num_dimensions==2;
+/// where Point2DConcept<point_t>;
+///
+/// typename x_iterator = axis<0>::iterator;
+/// typename y_iterator = axis<1>::iterator;
+/// typename x_coord_t = axis<0>::coord_t;
+/// typename y_coord_t = axis<1>::coord_t;
+///
+/// // Only available to locators that have dynamic step in Y
+/// //Loc::Loc(const Loc& loc, y_coord_t);
+///
+/// // Only available to locators that have dynamic step in X and Y
+/// //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
+///
+/// x_iterator& Loc::x();
+/// x_iterator const& Loc::x() const;
+/// y_iterator& Loc::y();
+/// y_iterator const& Loc::y() const;
+///
+/// x_iterator Loc::x_at(const difference_type&) const;
+/// y_iterator Loc::y_at(const difference_type&) const;
+/// Loc Loc::xy_at(const difference_type&) const;
+///
+/// // x/y versions of all methods that can take difference type
+/// x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
+/// y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
+/// Loc Loc::xy_at(x_coord_t, y_coord_t) const;
+/// reference operator()(const Loc&, x_coord_t, y_coord_t);
+/// cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
+///
+/// bool Loc::is_1d_traversable(x_coord_t width) const;
+/// y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
+/// };
+/// \endcode
+template <typename Loc>
+struct RandomAccess2DLocatorConcept
+{
+ void constraints()
+ {
+ gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
+ static_assert(Loc::num_dimensions == 2, "");
+
+ using dynamic_x_step_t = typename dynamic_x_step_type<Loc>::type;
+ using dynamic_y_step_t = typename dynamic_y_step_type<Loc>::type;
+ using transposed_t = typename transposed_type<Loc>::type;
+
+ using cached_location_t = typename Loc::cached_location_t;
+ gil_function_requires<Point2DConcept<typename Loc::point_t>>();
+
+ using x_iterator = typename Loc::x_iterator;
+ using y_iterator = typename Loc::y_iterator;
+ using x_coord_t = typename Loc::x_coord_t;
+ using y_coord_t = typename Loc::y_coord_t;
+
+ x_coord_t xd = 0; ignore_unused_variable_warning(xd);
+ y_coord_t yd = 0; ignore_unused_variable_warning(yd);
+
+ typename Loc::difference_type d;
+ typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
+
+ dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
+ dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
+
+ using dynamic_xy_step_transposed_t = typename dynamic_y_step_type
+ <
+ typename dynamic_x_step_type<transposed_t>::type
+ >::type;
+ dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
+
+ bool is_contiguous = loc.is_1d_traversable(xd);
+ ignore_unused_variable_warning(is_contiguous);
+
+ loc.y_distance_to(loc, xd);
+
+ loc = loc.xy_at(d);
+ loc = loc.xy_at(xd, yd);
+
+ x_iterator xit = loc.x_at(d);
+ xit = loc.x_at(xd, yd);
+ xit = loc.x();
+
+ y_iterator yit = loc.y_at(d);
+ yit = loc.y_at(xd, yd);
+ yit = loc.y();
+
+ cached_location_t cl = loc.cache_location(xd, yd);
+ ignore_unused_variable_warning(cl);
+ }
+ Loc loc;
+};
+
+/// \ingroup PixelLocator2DConcept
+/// \brief GIL's 2-dimensional locator over immutable GIL pixels
+/// \code
+/// concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc>
+/// {
+/// where PixelValueConcept<value_type>;
+/// where PixelIteratorConcept<x_iterator>;
+/// where PixelIteratorConcept<y_iterator>;
+/// where x_coord_t == y_coord_t;
+///
+/// typename coord_t = x_coord_t;
+/// };
+/// \endcode
+template <typename Loc>
+struct PixelLocatorConcept
+{
+ void constraints()
+ {
+ gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
+ gil_function_requires<PixelIteratorConcept<typename Loc::x_iterator>>();
+ gil_function_requires<PixelIteratorConcept<typename Loc::y_iterator>>();
+ using coord_t = typename Loc::coord_t;
+ static_assert(is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value, "");
+ }
+ Loc loc;
+};
+
+namespace detail {
+
+/// \tparam Loc Models RandomAccessNDLocatorConcept
+template <typename Loc>
+struct RandomAccessNDLocatorIsMutableConcept
+{
+ void constraints()
+ {
+ gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
+ <
+ typename Loc::template axis<0>::iterator
+ >>();
+ gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
+ <
+ typename Loc::template axis<Loc::num_dimensions-1>::iterator
+ >>();
+
+ typename Loc::difference_type d; initialize_it(d);
+ typename Loc::value_type v; initialize_it(v);
+ typename Loc::cached_location_t cl = loc.cache_location(d);
+ *loc = v;
+ loc[d] = v;
+ loc[cl] = v;
+ }
+ Loc loc;
+};
+
+// \tparam Loc Models RandomAccess2DLocatorConcept
+template <typename Loc>
+struct RandomAccess2DLocatorIsMutableConcept
+{
+ void constraints()
+ {
+ gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
+ typename Loc::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
+ typename Loc::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
+ typename Loc::value_type v; initialize_it(v);
+ loc(xd, yd) = v;
+ }
+ Loc loc;
+};
+
+} // namespace detail
+
+/// \ingroup LocatorNDConcept
+/// \brief N-dimensional locator over mutable pixels
+///
+/// \code
+/// concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc>
+/// {
+/// where Mutable<reference>;
+/// };
+/// \endcode
+template <typename Loc>
+struct MutableRandomAccessNDLocatorConcept
+{
+ void constraints()
+ {
+ gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
+ gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
+ }
+};
+
+/// \ingroup Locator2DConcept
+/// \brief 2-dimensional locator over mutable pixels
+///
+/// \code
+/// concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc>
+/// : MutableRandomAccessNDLocatorConcept<Loc> {};
+/// \endcode
+template <typename Loc>
+struct MutableRandomAccess2DLocatorConcept
+{
+ void constraints()
+ {
+ gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
+ gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
+ }
+};
+
+/// \ingroup PixelLocator2DConcept
+/// \brief GIL's 2-dimensional locator over mutable GIL pixels
+///
+/// \code
+/// concept MutablePixelLocatorConcept<PixelLocatorConcept Loc>
+/// : MutableRandomAccess2DLocatorConcept<Loc> {};
+/// \endcode
+template <typename Loc>
+struct MutablePixelLocatorConcept
+{
+ void constraints()
+ {
+ gil_function_requires<PixelLocatorConcept<Loc>>();
+ gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
+ }
+};
+
+}} // namespace boost::gil
+
+#if defined(BOOST_CLANG)
+#pragma clang diagnostic pop
+#endif
+
+#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
+#pragma GCC diagnostic pop
+#endif
+
+#endif