Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:55

0001 //
0002 // Copyright 2005-2007 Adobe Systems Incorporated
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 #ifndef BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
0009 #define BOOST_GIL_CONCEPTS_PIXEL_LOCATOR_HPP
0010 
0011 #include <boost/gil/concepts/basic.hpp>
0012 #include <boost/gil/concepts/concept_check.hpp>
0013 #include <boost/gil/concepts/fwd.hpp>
0014 #include <boost/gil/concepts/pixel.hpp>
0015 #include <boost/gil/concepts/pixel_dereference.hpp>
0016 #include <boost/gil/concepts/pixel_iterator.hpp>
0017 #include <boost/gil/concepts/point.hpp>
0018 #include <boost/gil/concepts/detail/utility.hpp>
0019 
0020 #include <cstddef>
0021 #include <iterator>
0022 #include <type_traits>
0023 
0024 #if defined(BOOST_CLANG)
0025 #pragma clang diagnostic push
0026 #pragma clang diagnostic ignored "-Wunknown-pragmas"
0027 #pragma clang diagnostic ignored "-Wunused-local-typedefs"
0028 #endif
0029 
0030 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0031 #pragma GCC diagnostic push
0032 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
0033 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
0034 #endif
0035 
0036 namespace boost { namespace gil {
0037 
0038 /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
0039 /// \ingroup PixelLocatorConcept
0040 /// \brief N-dimensional locator
0041 
0042 /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
0043 /// \ingroup PixelLocatorConcept
0044 /// \brief 2-dimensional locator
0045 
0046 /// \defgroup PixelLocator2DConcept PixelLocatorConcept
0047 /// \ingroup PixelLocatorConcept
0048 /// \brief 2-dimensional locator over pixel data
0049 
0050 /// \ingroup LocatorNDConcept
0051 /// \brief N-dimensional locator over immutable values
0052 ///
0053 /// \code
0054 /// concept RandomAccessNDLocatorConcept<Regular Loc>
0055 /// {
0056 ///     typename value_type;        // value over which the locator navigates
0057 ///     typename reference;         // result of dereferencing
0058 ///     typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
0059 ///     typename const_t;           // same as Loc, but operating over immutable values
0060 ///     typename cached_location_t; // type to store relative location (for efficient repeated access)
0061 ///     typename point_t  = difference_type;
0062 ///
0063 ///     static const size_t num_dimensions; // dimensionality of the locator
0064 ///     where num_dimensions = point_t::num_dimensions;
0065 ///
0066 ///     // The difference_type and iterator type along each dimension. The iterators may only differ in
0067 ///     // difference_type. Their value_type must be the same as Loc::value_type
0068 ///     template <size_t D>
0069 ///     struct axis
0070 ///     {
0071 ///         typename coord_t = point_t::axis<D>::coord_t;
0072 ///         typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
0073 ///         where iterator::value_type == value_type;
0074 ///     };
0075 ///
0076 ///     // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
0077 ///     template <PixelDereferenceAdaptorConcept Deref>
0078 ///     struct add_deref
0079 ///     {
0080 ///         typename type;
0081 ///             where RandomAccessNDLocatorConcept<type>;
0082 ///         static type make(const Loc& loc, const Deref& deref);
0083 ///     };
0084 ///
0085 ///     Loc& operator+=(Loc&, const difference_type&);
0086 ///     Loc& operator-=(Loc&, const difference_type&);
0087 ///     Loc operator+(const Loc&, const difference_type&);
0088 ///     Loc operator-(const Loc&, const difference_type&);
0089 ///
0090 ///     reference operator*(const Loc&);
0091 ///     reference operator[](const Loc&, const difference_type&);
0092 ///
0093 ///     // Storing relative location for faster repeated access and accessing it
0094 ///     cached_location_t Loc::cache_location(const difference_type&) const;
0095 ///     reference operator[](const Loc&,const cached_location_t&);
0096 ///
0097 ///     // Accessing iterators along a given dimension at the current location or at a given offset
0098 ///     template <size_t D> axis<D>::iterator&       Loc::axis_iterator();
0099 ///     template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
0100 ///     template <size_t D> axis<D>::iterator        Loc::axis_iterator(const difference_type&) const;
0101 /// };
0102 /// \endcode
0103 template <typename Loc>
0104 struct RandomAccessNDLocatorConcept
0105 {
0106     void constraints()
0107     {
0108         gil_function_requires<Regular<Loc>>();
0109 
0110         // TODO: Should these be concept-checked instead of ignored? --mloskot
0111 
0112         using value_type = typename Loc::value_type;
0113         ignore_unused_variable_warning(value_type{});
0114 
0115         // result of dereferencing
0116         using reference = typename Loc::reference;
0117         //ignore_unused_variable_warning(reference{});
0118 
0119         // result of operator-(pixel_locator, pixel_locator)
0120         using difference_type = typename Loc::difference_type;
0121         ignore_unused_variable_warning(difference_type{});
0122 
0123         // type used to store relative location (to allow for more efficient repeated access)
0124         using cached_location_t = typename Loc::cached_location_t;
0125         ignore_unused_variable_warning(cached_location_t{});
0126 
0127         // same as this type, but over const values
0128         using const_t = typename Loc::const_t;
0129         ignore_unused_variable_warning(const_t{});
0130 
0131         // same as difference_type
0132         using point_t = typename Loc::point_t;
0133         ignore_unused_variable_warning(point_t{});
0134 
0135         static std::size_t const N = Loc::num_dimensions; ignore_unused_variable_warning(N);
0136 
0137         using first_it_type = typename Loc::template axis<0>::iterator;
0138         using last_it_type = typename Loc::template axis<N-1>::iterator;
0139         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type>>();
0140         gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type>>();
0141 
0142         // point_t must be an N-dimensional point, each dimension of which must
0143         // have the same type as difference_type of the corresponding iterator
0144         gil_function_requires<PointNDConcept<point_t>>();
0145         static_assert(point_t::num_dimensions == N, "");
0146         static_assert(std::is_same
0147             <
0148                 typename std::iterator_traits<first_it_type>::difference_type,
0149                 typename point_t::template axis<0>::coord_t
0150             >::value, "");
0151         static_assert(std::is_same
0152             <
0153                 typename std::iterator_traits<last_it_type>::difference_type,
0154                 typename point_t::template axis<N-1>::coord_t
0155             >::value, "");
0156 
0157         difference_type d;
0158         loc += d;
0159         loc -= d;
0160         loc = loc + d;
0161         loc = loc - d;
0162         reference r1 = loc[d];  ignore_unused_variable_warning(r1);
0163         reference r2 = *loc;  ignore_unused_variable_warning(r2);
0164         cached_location_t cl = loc.cache_location(d);  ignore_unused_variable_warning(cl);
0165         reference r3 = loc[d];  ignore_unused_variable_warning(r3);
0166 
0167         first_it_type fi = loc.template axis_iterator<0>();
0168         fi = loc.template axis_iterator<0>(d);
0169         last_it_type li = loc.template axis_iterator<N-1>();
0170         li = loc.template axis_iterator<N-1>(d);
0171 
0172         using deref_t = PixelDereferenceAdaptorArchetype<typename Loc::value_type>;
0173         using dtype = typename Loc::template add_deref<deref_t>::type;
0174         // TODO: infinite recursion - FIXME?
0175         //gil_function_requires<RandomAccessNDLocatorConcept<dtype>>();
0176     }
0177     Loc loc;
0178 };
0179 
0180 /// \ingroup Locator2DConcept
0181 /// \brief 2-dimensional locator over immutable values
0182 ///
0183 /// \code
0184 /// concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc>
0185 /// {
0186 ///     where num_dimensions==2;
0187 ///     where Point2DConcept<point_t>;
0188 ///
0189 ///     typename x_iterator = axis<0>::iterator;
0190 ///     typename y_iterator = axis<1>::iterator;
0191 ///     typename x_coord_t  = axis<0>::coord_t;
0192 ///     typename y_coord_t  = axis<1>::coord_t;
0193 ///
0194 ///     // Only available to locators that have dynamic step in Y
0195 ///     //Loc::Loc(const Loc& loc, y_coord_t);
0196 ///
0197 ///     // Only available to locators that have dynamic step in X and Y
0198 ///     //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
0199 ///
0200 ///     x_iterator&       Loc::x();
0201 ///     x_iterator const& Loc::x() const;
0202 ///     y_iterator&       Loc::y();
0203 ///     y_iterator const& Loc::y() const;
0204 ///
0205 ///     x_iterator Loc::x_at(const difference_type&) const;
0206 ///     y_iterator Loc::y_at(const difference_type&) const;
0207 ///     Loc Loc::xy_at(const difference_type&) const;
0208 ///
0209 ///     // x/y versions of all methods that can take difference type
0210 ///     x_iterator        Loc::x_at(x_coord_t, y_coord_t) const;
0211 ///     y_iterator        Loc::y_at(x_coord_t, y_coord_t) const;
0212 ///     Loc               Loc::xy_at(x_coord_t, y_coord_t) const;
0213 ///     reference         operator()(const Loc&, x_coord_t, y_coord_t);
0214 ///     cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
0215 ///
0216 ///     bool      Loc::is_1d_traversable(x_coord_t width) const;
0217 ///     y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
0218 /// };
0219 /// \endcode
0220 template <typename Loc>
0221 struct RandomAccess2DLocatorConcept
0222 {
0223     void constraints()
0224     {
0225         gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
0226         static_assert(Loc::num_dimensions == 2, "");
0227 
0228         using dynamic_x_step_t = typename dynamic_x_step_type<Loc>::type;
0229         using dynamic_y_step_t = typename dynamic_y_step_type<Loc>::type;
0230         using transposed_t = typename transposed_type<Loc>::type;
0231 
0232         using cached_location_t = typename Loc::cached_location_t;
0233         gil_function_requires<Point2DConcept<typename Loc::point_t>>();
0234 
0235         using x_iterator = typename Loc::x_iterator;
0236         using y_iterator = typename Loc::y_iterator;
0237         using x_coord_t = typename Loc::x_coord_t;
0238         using y_coord_t = typename Loc::y_coord_t;
0239 
0240         x_coord_t xd = 0; ignore_unused_variable_warning(xd);
0241         y_coord_t yd = 0; ignore_unused_variable_warning(yd);
0242 
0243         typename Loc::difference_type d;
0244         typename Loc::reference r=loc(xd,yd);  ignore_unused_variable_warning(r);
0245 
0246         dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
0247         dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
0248 
0249         using dynamic_xy_step_transposed_t = typename dynamic_y_step_type
0250             <
0251                 typename dynamic_x_step_type<transposed_t>::type
0252             >::type;
0253         dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
0254 
0255         bool is_contiguous = loc.is_1d_traversable(xd);
0256         ignore_unused_variable_warning(is_contiguous);
0257 
0258         loc.y_distance_to(loc, xd);
0259 
0260         loc = loc.xy_at(d);
0261         loc = loc.xy_at(xd, yd);
0262 
0263         x_iterator xit = loc.x_at(d);
0264         xit = loc.x_at(xd, yd);
0265         xit = loc.x();
0266 
0267         y_iterator yit = loc.y_at(d);
0268         yit = loc.y_at(xd, yd);
0269         yit = loc.y();
0270 
0271         cached_location_t cl = loc.cache_location(xd, yd);
0272         ignore_unused_variable_warning(cl);
0273     }
0274     Loc loc;
0275 };
0276 
0277 /// \ingroup PixelLocator2DConcept
0278 /// \brief GIL's 2-dimensional locator over immutable GIL pixels
0279 /// \code
0280 /// concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc>
0281 /// {
0282 ///     where PixelValueConcept<value_type>;
0283 ///     where PixelIteratorConcept<x_iterator>;
0284 ///     where PixelIteratorConcept<y_iterator>;
0285 ///     where x_coord_t == y_coord_t;
0286 ///
0287 ///     typename coord_t = x_coord_t;
0288 /// };
0289 /// \endcode
0290 template <typename Loc>
0291 struct PixelLocatorConcept
0292 {
0293     void constraints()
0294     {
0295         gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
0296         gil_function_requires<PixelIteratorConcept<typename Loc::x_iterator>>();
0297         gil_function_requires<PixelIteratorConcept<typename Loc::y_iterator>>();
0298         using coord_t = typename Loc::coord_t;
0299         static_assert(std::is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value, "");
0300     }
0301     Loc loc;
0302 };
0303 
0304 namespace detail {
0305 
0306 /// \tparam Loc Models RandomAccessNDLocatorConcept
0307 template <typename Loc>
0308 struct RandomAccessNDLocatorIsMutableConcept
0309 {
0310     void constraints()
0311     {
0312         gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
0313             <
0314                 typename Loc::template axis<0>::iterator
0315             >>();
0316         gil_function_requires<detail::RandomAccessIteratorIsMutableConcept
0317             <
0318                 typename Loc::template axis<Loc::num_dimensions-1>::iterator
0319             >>();
0320 
0321         typename Loc::difference_type d; initialize_it(d);
0322         typename Loc::value_type v; initialize_it(v);
0323         typename Loc::cached_location_t cl = loc.cache_location(d);
0324         *loc = v;
0325         loc[d] = v;
0326         loc[cl] = v;
0327     }
0328     Loc loc;
0329 };
0330 
0331 // \tparam Loc Models RandomAccess2DLocatorConcept
0332 template <typename Loc>
0333 struct RandomAccess2DLocatorIsMutableConcept
0334 {
0335     void constraints()
0336     {
0337         gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
0338         typename Loc::x_coord_t xd = 0; ignore_unused_variable_warning(xd);
0339         typename Loc::y_coord_t yd = 0; ignore_unused_variable_warning(yd);
0340         typename Loc::value_type v; initialize_it(v);
0341         loc(xd, yd) = v;
0342     }
0343     Loc loc;
0344 };
0345 
0346 } // namespace detail
0347 
0348 /// \ingroup LocatorNDConcept
0349 /// \brief N-dimensional locator over mutable pixels
0350 ///
0351 /// \code
0352 /// concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc>
0353 /// {
0354 ///     where Mutable<reference>;
0355 /// };
0356 /// \endcode
0357 template <typename Loc>
0358 struct MutableRandomAccessNDLocatorConcept
0359 {
0360     void constraints()
0361     {
0362         gil_function_requires<RandomAccessNDLocatorConcept<Loc>>();
0363         gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc>>();
0364     }
0365 };
0366 
0367 /// \ingroup Locator2DConcept
0368 /// \brief 2-dimensional locator over mutable pixels
0369 ///
0370 /// \code
0371 /// concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc>
0372 ///     : MutableRandomAccessNDLocatorConcept<Loc> {};
0373 /// \endcode
0374 template <typename Loc>
0375 struct MutableRandomAccess2DLocatorConcept
0376 {
0377     void constraints()
0378     {
0379         gil_function_requires<RandomAccess2DLocatorConcept<Loc>>();
0380         gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
0381     }
0382 };
0383 
0384 /// \ingroup PixelLocator2DConcept
0385 /// \brief GIL's 2-dimensional locator over mutable GIL pixels
0386 ///
0387 /// \code
0388 /// concept MutablePixelLocatorConcept<PixelLocatorConcept Loc>
0389 ///     : MutableRandomAccess2DLocatorConcept<Loc> {};
0390 /// \endcode
0391 template <typename Loc>
0392 struct MutablePixelLocatorConcept
0393 {
0394     void constraints()
0395     {
0396         gil_function_requires<PixelLocatorConcept<Loc>>();
0397         gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc>>();
0398     }
0399 };
0400 
0401 }} // namespace boost::gil
0402 
0403 #if defined(BOOST_CLANG)
0404 #pragma clang diagnostic pop
0405 #endif
0406 
0407 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0408 #pragma GCC diagnostic pop
0409 #endif
0410 
0411 #endif