Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / gil / virtual_locator.hpp
index 2128bdb..f9a2fa9 100644 (file)
 
 namespace boost { namespace gil {
 
-/// \brief A 2D locator over a virtual image. Upon dereferencing, invokes a given function object passing it its coordinates. Models: PixelLocatorConcept, HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, HasTransposedTypeConcept
 /// \ingroup PixelLocatorModel PixelBasedModel
+/// \brief A 2D locator over a virtual image
+/// Upon dereferencing, invokes a given function object passing it its coordinates.
+/// Models:
+///   PixelLocatorConcept,
+///   HasDynamicXStepTypeConcept,
+///   HasDynamicYStepTypeConcept,
+///   HasTransposedTypeConcept
 ///
-template <typename Deref, bool IsTransposed>        // A function object that given a point returns a reference. Models PixelDereferenceAdaptorConcept
-class virtual_2d_locator : public pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed>>
+/// \tparam DerefFn Function object that given a point returns a reference.
+///         Models PixelDereferenceAdaptorConcept.
+/// \tparam IsTransposed Indicates if locator should navigate in transposed mode.
+template <typename DerefFn, bool IsTransposed>
+class virtual_2d_locator
+    : public pixel_2d_locator_base
+        <
+            virtual_2d_locator<DerefFn, IsTransposed>,
+            position_iterator<DerefFn, IsTransposed>,
+            position_iterator<DerefFn, 1-IsTransposed>
+        >
 {
-    using this_t = virtual_2d_locator<Deref,IsTransposed>;
+    using this_t = virtual_2d_locator<DerefFn, IsTransposed>;
 public:
-    using parent_t = pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed>>;
-    using const_t = virtual_2d_locator<typename Deref::const_t,IsTransposed>;
-
-    using deref_fn_t = Deref;
+    using parent_t = pixel_2d_locator_base
+        <
+            virtual_2d_locator<DerefFn, IsTransposed>,
+            position_iterator<DerefFn, IsTransposed>,
+            position_iterator<DerefFn, 1-IsTransposed>
+        >;
+    using const_t = virtual_2d_locator<typename DerefFn::const_t, IsTransposed>;
+    using deref_fn_t = DerefFn;
     using point_t = typename parent_t::point_t;
-
     using coord_t = typename parent_t::coord_t;
     using x_coord_t = typename parent_t::x_coord_t;
     using y_coord_t = typename parent_t::y_coord_t;
     using x_iterator = typename parent_t::x_iterator;
     using y_iterator = typename parent_t::y_iterator;
 
-    template <typename NewDeref> struct add_deref
+    template <typename NewDerefFn>
+    struct add_deref
     {
-        using type = virtual_2d_locator<deref_compose<NewDeref,Deref>,IsTransposed>;
-        static type make(const virtual_2d_locator<Deref,IsTransposed>& loc, const NewDeref& nderef) {
-            return type(loc.pos(), loc.step(), deref_compose<NewDeref,Deref>(nderef,loc.deref_fn()));
+        using type = virtual_2d_locator<deref_compose<NewDerefFn, DerefFn>, IsTransposed>;
+
+        static type make(this_t const& loc, NewDerefFn const& new_deref_fn)
+        {
+            return type(loc.pos(), loc.step(),
+                deref_compose<NewDerefFn, DerefFn>(new_deref_fn, loc.deref_fn()));
         }
     };
 
-    virtual_2d_locator(const point_t& p=point_t(0,0), const point_t& step=point_t(1,1), const deref_fn_t& d=deref_fn_t()) : _p(p,step,d) {}
-    template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& loc, coord_t y_step)
-        : _p(loc.pos(), point_t(loc.step().x,loc.step().y*y_step),     loc.deref_fn()) {}
+    virtual_2d_locator(
+        point_t const& p = {0, 0},
+        point_t const& step = {1, 1},
+        deref_fn_t const& deref_fn = deref_fn_t())
+        : y_pos_(p, step, deref_fn)
+    {}
+
+    template <typename D, bool TR>
+    virtual_2d_locator(virtual_2d_locator<D, TR> const &loc, coord_t y_step)
+        : y_pos_(loc.pos(), point_t(loc.step().x, loc.step().y * y_step), loc.deref_fn())
+    {}
 
     template <typename D, bool TR>
     virtual_2d_locator(virtual_2d_locator<D, TR> const& loc, coord_t x_step, coord_t y_step, bool transpose = false)
-        : _p(loc.pos()
+        : y_pos_(loc.pos()
         , transpose ?
             point_t(loc.step().x * y_step, loc.step().y * x_step) :
             point_t(loc.step().x * x_step, loc.step().y * y_step)
@@ -59,27 +89,48 @@ public:
         BOOST_ASSERT(transpose == (IsTransposed != TR));
     }
 
-    template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& pl) : _p(pl._p) {}
-    virtual_2d_locator(const virtual_2d_locator& pl) : _p(pl._p) {}
+    template <typename D, bool TR>
+    virtual_2d_locator(virtual_2d_locator<D, TR> const& other) : y_pos_(other.y_pos_) {}
+
+    virtual_2d_locator(virtual_2d_locator const& other) : y_pos_(other.y_pos_) {}
+    virtual_2d_locator& operator=(virtual_2d_locator const& other) = default;
+
+    bool operator==(const this_t& p) const { return y_pos_ == p.y_pos_; }
 
-    bool              operator==(const this_t& p) const { return _p==p._p; }
+    auto x() -> x_iterator&
+    {
+        return *gil_reinterpret_cast<x_iterator*>(this);
+    }
 
-    x_iterator&       x()                               { return *gil_reinterpret_cast<x_iterator*>(this); }
-    y_iterator&       y()                               { return _p; }
-    x_iterator const& x()                         const { return *gil_reinterpret_cast_c<x_iterator const*>(this); }
-    y_iterator const& y()                         const { return _p; }
+    auto x() const -> x_iterator const&
+    {
+        return *gil_reinterpret_cast_c<x_iterator const*>(this);
+    }
 
-    // Returns the y distance between two x_iterators given the difference of their x positions
-    y_coord_t y_distance_to(const this_t& it2, x_coord_t) const { return (it2.pos()[1-IsTransposed] - pos()[1-IsTransposed])/step()[1-IsTransposed]; }
-    bool      is_1d_traversable(x_coord_t)        const { return false; }   // is there no gap at the end of each row? I.e. can we use x_iterator to visit every pixel instead of nested loops?
+    auto y() -> y_iterator& { return y_pos_; }
+    auto y() const -> y_iterator const& { return y_pos_; }
+
+    /// Returns the y distance between two x_iterators given the difference of their x positions
+    auto y_distance_to(this_t const& it2, x_coord_t) const -> y_coord_t
+    {
+        return (it2.pos()[1 - IsTransposed] - pos()[1 - IsTransposed])
+                / step()[1 - IsTransposed];
+    }
+
+    /// \todo TODO: is there no gap at the end of each row?
+    ///       i.e. can we use x_iterator to visit every pixel instead of nested loops?
+    bool is_1d_traversable(x_coord_t) const { return false; }
 
     // Methods specific for virtual 2D locator
-    const point_t&   pos()                        const { return _p.pos(); }
-    const point_t&   step()                       const { return _p.step(); }
-    const deref_fn_t& deref_fn()                  const { return _p.deref_fn(); }
+    auto pos() const -> point_t const& { return y_pos_.pos(); }
+    auto step() const -> point_t const& { return y_pos_.step(); }
+    auto deref_fn() const -> deref_fn_t const& { return y_pos_.deref_fn(); }
+
 private:
-    template <typename D, bool TR> friend class virtual_2d_locator;
-    y_iterator        _p;    // contains the current position, the step and the dereference object
+    template <typename D, bool TR>
+    friend class virtual_2d_locator;
+
+    y_iterator y_pos_; // current position, the step and the dereference object
 };
 
 /////////////////////////////
@@ -87,19 +138,27 @@ private:
 /////////////////////////////
 
 template <typename D, bool TR>
-struct channel_type<virtual_2d_locator<D,TR> > : public channel_type<typename virtual_2d_locator<D,TR>::parent_t> {
+struct channel_type<virtual_2d_locator<D, TR>>
+    : channel_type<typename virtual_2d_locator<D, TR>::parent_t>
+{
 };
 
 template <typename D, bool TR>
-struct color_space_type<virtual_2d_locator<D,TR> > : public color_space_type<typename virtual_2d_locator<D,TR>::parent_t> {
+struct color_space_type<virtual_2d_locator<D, TR>>
+    : color_space_type<typename virtual_2d_locator<D, TR>::parent_t>
+{
 };
 
 template <typename D, bool TR>
-struct channel_mapping_type<virtual_2d_locator<D,TR> > : public channel_mapping_type<typename virtual_2d_locator<D,TR>::parent_t> {
+struct channel_mapping_type<virtual_2d_locator<D, TR>>
+    : channel_mapping_type<typename virtual_2d_locator<D, TR>::parent_t>
+{
 };
 
 template <typename D, bool TR>
-struct is_planar<virtual_2d_locator<D,TR> > : public is_planar<typename virtual_2d_locator<D,TR>::parent_t> {
+struct is_planar<virtual_2d_locator<D, TR>>
+    : is_planar<typename virtual_2d_locator<D, TR>::parent_t>
+{
 };
 
 /////////////////////////////