Commit ea5d6300 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Clean neighborhood concept and adapt.

It uses dyn_neighborhood uses se.offsets() method.
parent bb6fc6da
......@@ -50,18 +50,19 @@ namespace mln
namespace internal
{
template <class T>
T&& iter_outer_init(T&& x)
T& iter_outer_init(T& x)
{
mln::outer_init(x);
return std::forward<T>(x);
return x;
}
}
}
#define mln_foreach(p, COL) \
MLN_DECL_VAR(_mln_range_, COL) \
MLN_DECL_VAR(_mln_it_proxy_, mln::rng::iter(_mln_range_.get())) \
MLN_DECL_VAR(__mln_has_been_broken, false) \
for (auto _mln_it_ = mln::internal::iter_outer_init(mln::rng::iter(_mln_range_.get())); \
for (auto& _mln_it_ = mln::internal::iter_outer_init(_mln_it_proxy_.get()); \
!__mln_has_been_broken.get() && !mln::outer_finished(_mln_it_); \
__mln_has_been_broken.get() ? (void)0 : mln::outer_next(_mln_it_)) \
for (mln::inner_init(_mln_it_); !__mln_has_been_broken.get() && !mln::inner_finished(_mln_it_); \
......
......@@ -55,7 +55,7 @@ namespace mln
int get_border_from_nbh(const Neighborhood& nbh, const point<T, dim>&)
{
unsigned b = 0;
mln_foreach (auto dp, nbh.dpoints)
mln_foreach (auto dp, nbh.offsets())
for (unsigned i = 0; i < dim; ++i)
b = std::max<unsigned>(b, std::abs(dp[i]));
return b;
......@@ -65,7 +65,8 @@ namespace mln
template <typename Neighborhood>
int get_border_from_nbh(const Neighborhood& nbh)
{
return dispatch::get_border_from_nbh(nbh, typename Neighborhood::point_type());
using P = typename std::remove_reference_t<decltype(nbh.offsets())>::value_type;
return dispatch::get_border_from_nbh(nbh, P());
}
}
}
......
......@@ -12,15 +12,19 @@ namespace mln
namespace
{
struct c4_t : dyn_neighborhood_base<std::array<point2d, 4>, constant_neighborhood_tag, c4_t>
struct c4_t : dyn_neighborhood_base<constant_neighborhood_tag, c4_t>
{
constexpr const std::array<point2d, 4>& offsets() const { return dpoints; }
static const int static_size = 4;
static const std::array<point2d, 4> dpoints;
};
const std::array<point2d, 4> c4_t::dpoints = {{{-1, 0}, {0, -1}, {0, 1}, {1, 0}}};
struct c8_t : dyn_neighborhood_base<std::array<point2d, 8>, constant_neighborhood_tag, c8_t>
struct c8_t : dyn_neighborhood_base<constant_neighborhood_tag, c8_t>
{
constexpr const std::array<point2d, 8>& offsets() const { return dpoints; }
static const int static_size = 8;
static const std::array<point2d, 8> dpoints;
};
......@@ -28,15 +32,19 @@ namespace mln
const std::array<point2d, 8> c8_t::dpoints = {
{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}};
struct c2_v_t : dyn_neighborhood_base<std::array<point2d, 2>, constant_neighborhood_tag, c2_v_t>
struct c2_v_t : dyn_neighborhood_base<constant_neighborhood_tag, c2_v_t>
{
constexpr const std::array<point2d, 2>& offsets() const { return dpoints; }
static const int static_size = 2;
static const std::array<point2d, 2> dpoints;
};
const std::array<point2d, 2> c2_v_t::dpoints = {{{-1, 0}, {1, 0}}};
struct c2_h_t : dyn_neighborhood_base<std::array<point2d, 2>, constant_neighborhood_tag, c2_h_t>
struct c2_h_t : dyn_neighborhood_base<constant_neighborhood_tag, c2_h_t>
{
constexpr const std::array<point2d, 2>& offsets() const { return dpoints; }
static const int static_size = 2;
static const std::array<point2d, 2> dpoints;
};
......
......@@ -10,18 +10,22 @@ namespace mln {
namespace {
struct c6_t : dyn_neighborhood_base<std::array<point3d, 6>, constant_neighborhood_tag, c6_t>
struct c6_t : dyn_neighborhood_base<constant_neighborhood_tag, c6_t>
{
static const int static_size = 6;
static const std::array<point3d, 6> dpoints;
const auto& offsets() const { return dpoints; }
};
const std::array<point3d, 6> c6_t::dpoints = {
{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0}}};
struct c26_t : dyn_neighborhood_base< std::array<point3d, 26>, constant_neighborhood_tag, c8_t >
struct c26_t : dyn_neighborhood_base<constant_neighborhood_tag, c8_t>
{
static const int static_size = 26;
static const std::array<point3d, 26> dpoints;
const auto& offsets() const { return dpoints; }
};
const std::array<point3d, 26> c26_t::dpoints = {{{-1, -1, -1},
......
......@@ -11,7 +11,7 @@
namespace mln
{
template <class SiteSet, class category, class E>
template <class category, class E>
struct dyn_neighborhood_base;
template <class SiteSet, class category>
......@@ -21,48 +21,50 @@ namespace mln
/**** Implementation ****/
/******************************************/
template <class SiteSet, class category, class E>
template <class category, class E>
struct dyn_neighborhood_base : neighborhood_base<E, category>
{
public:
typedef typename range_value<SiteSet>::type point_type;
typedef typename range_value<SiteSet>::type site_type;
auto __process_point(const point_type& p) const
template <typename P>
auto __process_point(const P& p) const
{
return make_sliding_piter(make_value_wrapper(p), mln::exact(this)->dpoints);
return make_sliding_piter(make_value_wrapper(p), mln::exact(this)->offsets());
}
template <typename P>
auto __bind_point(P& p) const
{
return make_sliding_piter(std::cref(p), mln::exact(this)->dpoints);
return make_sliding_piter(std::cref(p), mln::exact(this)->offsets());
}
template <typename PointIterator>
auto __bind_point_iterator(const PointIterator& p) const
{
return make_sliding_piter(make_iterator_proxy(p), mln::exact(this)->dpoints);
return make_sliding_piter(make_iterator_proxy(p), mln::exact(this)->offsets());
}
template <typename Px>
auto __bind_pixel(Px& px) const
{
return make_sliding_pixter(std::cref(px), mln::exact(this)->dpoints);
return make_sliding_pixter(std::cref(px), mln::exact(this)->offsets());
}
template <typename Px>
auto __bind_pixel_iterator(const Px& px) const
{
return make_sliding_pixter(make_iterator_proxy(px), mln::exact(this)->dpoints);
return make_sliding_pixter(make_iterator_proxy(px), mln::exact(this)->offsets());
}
};
template <class SiteSet, class category>
struct dyn_neighborhood : dyn_neighborhood_base<SiteSet, category, dyn_neighborhood<SiteSet, category>>
struct dyn_neighborhood : dyn_neighborhood_base<category, dyn_neighborhood<SiteSet, category>>
{
dyn_neighborhood(const SiteSet& pset) : dpoints{pset} {}
dyn_neighborhood(SiteSet&& pset) : dpoints(std::move(pset)) {}
const SiteSet& offsets() const { return dpoints; }
private:
const SiteSet dpoints;
};
}
......
......@@ -12,8 +12,9 @@ namespace mln
template <class Nbh, class tag>
struct neighborhood_base : Neighborhood<Nbh>
{
typedef tag category;
typedef std::false_type is_incremental;
using category = tag;
using is_incremental = std::false_type;
using is_decomposable = std::false_type;
private:
/// \brief Overload if x is a point lvalue
......
......@@ -34,18 +34,47 @@ namespace mln
template <class PointProxy, class SiteSet>
struct sliding_piter
: iterator_base<sliding_piter<PointProxy, SiteSet>, typename SiteSet::value_type, typename SiteSet::value_type>
: iterator_base<sliding_piter<PointProxy, SiteSet>,
typename SiteSet::value_type,
typename SiteSet::value_type>
{
using reference = typename SiteSet::value_type;
sliding_piter(const PointProxy& p, const SiteSet& s) : m_point(p), m_it(rng::iter(s)) {}
sliding_piter(const PointProxy& p, const SiteSet& s) : m_set(s), m_point(p), m_it(rng::iter(m_set)) {}
sliding_piter(const sliding_piter& other)
: m_set(other.m_set), m_point(other.m_point), m_it(rng::iter(m_set))
{
}
sliding_piter(sliding_piter&& other)
: m_set(std::move(other.m_set)), m_point(std::move(other.m_point)), m_it(rng::iter(m_set))
{
}
sliding_piter& operator= (const sliding_piter& other)
{
m_set = other.m_set;
m_point = other.m_point;
m_it = rng::iter(m_set);
}
sliding_piter& operator= (sliding_piter&& other)
{
m_set = std::move(other.m_set);
m_point = std::move(other.m_point);
m_it = rng::iter(m_set);
}
void init() { m_it.init(); }
void next() { m_it.next(); }
bool finished() const { return m_it.finished(); }
reference dereference() const { return m_point.get() + *m_it; }
reference dereference() const { return m_point.get() + *m_it; }
private:
SiteSet m_set;
const PointProxy m_point;
typename range_const_iterator<SiteSet>::type m_it;
};
......
......@@ -88,7 +88,30 @@ namespace mln
public:
sliding_pixter_base() = default;
sliding_pixter_base(const PixelProxy& p, const SiteSet& s) : m_pixel(p), m_pset_iter(rng::iter(s)) {}
sliding_pixter_base(const PixelProxy& p, const SiteSet& s) : m_set(s), m_pixel(p), m_pset_iter(rng::iter(m_set)) {}
sliding_pixter_base(const sliding_pixter_base& other)
: m_set(other.m_set), m_pixel(other.m_pixel), m_pset_iter(rng::iter(m_set))
{
}
sliding_pixter_base(sliding_pixter_base& other)
: m_set(std::move(other.m_set)), m_pixel(std::move(other.m_pixel)), m_pset_iter(rng::iter(m_set))
{
}
sliding_pixter_base& operator=(const sliding_pixter_base& other)
{
m_set = other.m_set;
m_pixel = other.m_pixel;
m_pset_iter = rng::iter(m_set);
}
sliding_pixter_base& operator=(sliding_pixter_base&& other)
{
m_set = std::move(other.m_set);
m_pixel = std::move(other.m_pixel);
m_pset_iter = rng::iter(m_set);
}
void init() { m_pset_iter.init(); }
void next() { m_pset_iter.next(); }
......@@ -97,6 +120,7 @@ namespace mln
point_pixel<Image> dereference() const { return {m_pixel.get().image(), m_pixel.get().point() + *m_pset_iter}; }
private:
SiteSet m_set;
PixelProxy m_pixel;
typename range_const_iterator<SiteSet>::type m_pset_iter;
};
......
......@@ -23,7 +23,7 @@ namespace mln
/**** Implementation ****/
/******************************************/
struct ball2d : dyn_neighborhood_base<std::vector<point2d>, dynamic_neighborhood_tag, ball2d>
struct ball2d : dyn_neighborhood_base<dynamic_neighborhood_tag, ball2d>
{
using is_incremental = std::true_type;
......@@ -80,6 +80,8 @@ namespace mln
dec_type dec() const { return m_dec; }
const auto& offsets() const { return dpoints; }
const std::vector<point2d> dpoints;
private:
......
......@@ -27,8 +27,9 @@ namespace mln
namespace
{
struct winc4_t : dyn_neighborhood_base<std::array<point2d, 5>, constant_neighborhood_tag, winc4_t>
struct winc4_t : dyn_neighborhood_base<constant_neighborhood_tag, winc4_t>
{
constexpr const std::array<point2d, 5>& offsets() { return dpoints; }
static const int static_size = 5;
static const std::array<point2d, 5> dpoints;
};
......@@ -37,8 +38,9 @@ namespace mln
static const winc4_t winc4{};
struct winc8_t : dyn_neighborhood_base<std::array<point2d, 9>, constant_neighborhood_tag, winc8_t>
struct winc8_t : dyn_neighborhood_base<constant_neighborhood_tag, winc8_t>
{
constexpr const std::array<point2d, 9>& offsets() { return dpoints; }
static const int static_size = 9;
static const std::array<point2d, 9> dpoints;
};
......@@ -48,8 +50,9 @@ namespace mln
static const winc8_t winc8{};
struct winc2_v_t : dyn_neighborhood_base<std::array<point2d, 3>, constant_neighborhood_tag, winc2_v_t>
struct winc2_v_t : dyn_neighborhood_base<constant_neighborhood_tag, winc2_v_t>
{
constexpr const std::array<point2d, 3>& offsets() { return dpoints; }
static const int static_size = 3;
static const std::array<point2d, 3> dpoints;
};
......@@ -58,8 +61,9 @@ namespace mln
static const winc2_v_t winc2_v{};
struct winc2_h_t : dyn_neighborhood_base<std::array<point2d, 3>, constant_neighborhood_tag, winc2_h_t>
struct winc2_h_t : dyn_neighborhood_base<constant_neighborhood_tag, winc2_h_t>
{
constexpr const std::array<point2d, 3>& offsets() { return dpoints; }
static const int static_size = 3;
static const std::array<point2d, 3> dpoints;
};
......@@ -73,7 +77,7 @@ namespace mln
/*** Implementation **/
/**************************/
struct rect2d : dyn_neighborhood_base<box2d, dynamic_neighborhood_tag, rect2d>
struct rect2d : dyn_neighborhood_base<dynamic_neighborhood_tag, rect2d>
{
typedef std::true_type is_incremental;
typedef std::false_type is_separable;
......@@ -100,6 +104,8 @@ namespace mln
return b;
}
const box2d& offsets() const { return dpoints; }
const box2d dpoints;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment