
https://svn.lrde.epita.fr/svn/oln/trunk Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Introducing mini-olena (milena). * milena: New. * milena/test: New. * milena/test/main.cc: New. * milena/convert: New. * milena/morpho: New. * milena/debug: New. * milena/debug/println.hh: New. * milena/level: New. * milena/level/fill.hh: New. * milena/core: New. * milena/core/dpoint2d.hh: New. * milena/core/window2d.cc: New. * milena/core/macros.hh: New. * milena/core/dpoints_qiter.hh: New. * milena/core/window2d_qiter.cc: New. * milena/core/box.hh: New. * milena/core/point.hh: New. * milena/core/rectangle2d.hh: New. * milena/core/box_piter.hh: New. * milena/core/dpoint.hh: New. * milena/core/concept: New. * milena/core/concept/image.hh: New. * milena/core/concept/genpoint.hh: New. * milena/core/concept/piter.hh: New. * milena/core/concept/point_set.hh: New. * milena/core/concept/psite.hh: New. * milena/core/concept/object.hh: New. * milena/core/concept/window.hh: New. * milena/core/concept/box.hh: New. * milena/core/concept/iterator.hh: New. * milena/core/concept/point.hh: New. * milena/core/concept/dpoint.hh: New. * milena/core/window2d.hh: New. * milena/core/ops.hh: New. * milena/core/exact.hh: New. * milena/core/window.hh: New. * milena/core/image2d.hh: New. * milena/core/vec.hh: New. * milena/core/internal: New. * milena/core/internal/coord_impl.hh: New. * milena/core/internal/image_adaptor.hh: New. * milena/core/internal/image_base.hh: New. * milena/core/internal/set_of.hh: New. * milena/core/box2d.hh: New. * milena/core/point2d.hh: New. * milena/core/safe_image.hh: New. * milena/mlc: New. * milena/mlc/equal.hh: New. * milena/mlc/same_point.hh: New. * milena/value: New. * milena/README: New. README | 14 ++ core/box.hh | 68 +++++++++++++ core/box2d.hh | 31 ++++++ core/box_piter.hh | 156 ++++++++++++++++++++++++++++++ core/concept/box.hh | 48 +++++++++ core/concept/dpoint.hh | 99 +++++++++++++++++++ core/concept/genpoint.hh | 136 ++++++++++++++++++++++++++ core/concept/image.hh | 92 ++++++++++++++++++ core/concept/iterator.hh | 58 +++++++++++ core/concept/object.hh | 37 +++++++ core/concept/piter.hh | 45 ++++++++ core/concept/point.hh | 65 ++++++++++++ core/concept/point_set.hh | 55 ++++++++++ core/concept/psite.hh | 38 +++++++ core/concept/window.hh | 50 +++++++++ core/dpoint.hh | 74 ++++++++++++++ core/dpoint2d.hh | 26 +++++ core/dpoints_qiter.hh | 123 ++++++++++++++++++++++++ core/exact.hh | 100 +++++++++++++++++++ core/image2d.hh | 147 +++++++++++++++++++++++++++++ core/internal/coord_impl.hh | 207 +++++++++++++++++++++++++++++++++++++++++ core/internal/image_adaptor.hh | 87 +++++++++++++++++ core/internal/image_base.hh | 68 +++++++++++++ core/internal/set_of.hh | 108 +++++++++++++++++++++ core/macros.hh | 28 +++++ core/ops.hh | 56 +++++++++++ core/point.hh | 74 ++++++++++++++ core/point2d.hh | 26 +++++ core/rectangle2d.hh | 82 ++++++++++++++++ core/safe_image.hh | 70 +++++++++++++ core/vec.hh | 35 ++++++ core/window.hh | 76 +++++++++++++++ core/window2d.cc | 65 ++++++++++++ core/window2d.hh | 39 +++++++ core/window2d_qiter.cc | 125 ++++++++++++++++++++++++ debug/println.hh | 61 ++++++++++++ level/fill.hh | 35 ++++++ mlc/equal.hh | 30 +++++ mlc/same_point.hh | 24 ++++ test/main.cc | 32 ++++++ 40 files changed, 2790 insertions(+) Index: milena/test/main.cc --- milena/test/main.cc (revision 0) +++ milena/test/main.cc (revision 0) @@ -0,0 +1,32 @@ +#include <core/image2d.hh> +#include <level/fill.hh> +#include <debug/println.hh> + +#include <core/window2d.hh> +#include <core/rectangle2d.hh> + + +int main() +{ + using namespace mln; + + box2d b = mk_box2d(/* row = */ 1, 2, + /* col = */ 3, 5); + std::cout << b << std::endl; + + image2d<int> ima(b); + level::fill(ima, 51); + debug::println(ima); + + bool w[] + { 0, 1, 0, + 0, 1, 0, + 1, 0, 0 }; + window2d win = mk_window2d(w); + std::cout << win << std::endl; + + debug::println(ima, win); + + rectangle2d rec(1, 2); + std::cout << rec << std::endl; +} Index: milena/debug/println.hh --- milena/debug/println.hh (revision 0) +++ milena/debug/println.hh (revision 0) @@ -0,0 +1,61 @@ +#ifndef MLN_DEBUG_PRINTLN_HH +# define MLN_DEBUG_PRINTLN_HH + +# include <core/concept/image.hh> +# include <core/concept/window.hh> + + +namespace mln +{ + + namespace debug + { + + template <typename I> + void println(const Image<I>& input_); + + template <typename I, typename W> + void println(const Image<I>& input_, + const Window<W>& win_); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + void println(const Image<I>& input_) + { + const I& input = exact(input_); + oln_piter(I) p(input.domain()); + for_all(p) + std::cout << input(p) << ' '; + std::cout << std::endl; + } + + + template <typename I, typename W> + void println(const Image<I>& input_, + const Window<W>& win_) + { + const I& input = exact(input_); + const W& win = exact(win_); + + oln_piter(I) p(input.domain()); + oln_qiter(W) q(win, p); + for_all(p) + { + std::cout << input(p) << ':'; + for_all(q) + if (input.owns_(q)) + std::cout << input(q) << ' '; + std::cout << std::endl; + } + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::debug + +} // end of namespace mln + + +#endif // ! MLN_DEBUG_PRINTLN_HH Index: milena/level/fill.hh --- milena/level/fill.hh (revision 0) +++ milena/level/fill.hh (revision 0) @@ -0,0 +1,35 @@ +#ifndef MLN_LEVEL_FILL_HH +# define MLN_LEVEL_FILL_HH + +# include <core/concept/image.hh> + + +namespace mln +{ + + namespace level + { + + template <typename I> + void fill(Image<I>& ima_, const oln_value(I)& value); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + void fill(Image<I>& ima_, const oln_value(I)& value) + { + I& ima = exact(ima_); + oln_piter(I) p(ima.domain()); + for_all(p) + ima(p) = value; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::level + +} // end of namespace mln + + +#endif // ! MLN_LEVEL_FILL_HH Index: milena/core/dpoint2d.hh --- milena/core/dpoint2d.hh (revision 0) +++ milena/core/dpoint2d.hh (revision 0) @@ -0,0 +1,26 @@ +#ifndef MLN_CORE_DPOINT2D_HH +# define MLN_CORE_DPOINT2D_HH + +# include <core/dpoint.hh> + + +namespace mln +{ + + typedef dpoint_<2,int> dpoint2d; + + dpoint2d mk_dpoint2d(int row, int col) + { + dpoint2d tmp; + tmp[0] = row; + tmp[1] = col; + return tmp; + } + +} // end of namespace mln + + +# include <core/point2d.hh> + + +#endif // ! MLN_CORE_DPOINT2D_HH Index: milena/core/window2d.cc --- milena/core/window2d.cc (revision 0) +++ milena/core/window2d.cc (revision 0) @@ -0,0 +1,65 @@ +# include <core/window2d.hh> +# include <core/window2d_qiter.hh> +# include <core/piter.hh> + + +namespace mln +{ + + window2d::window2d() + { + } + + window2d::window2d(unsigned nrows, unsigned ncols, + const bool values[]) + { + assert(nrows != 0 and ncols != 0); + assert(nrows % 2 = 1 and ncols % 2 = 1); + int drow = int(nrows) / 2, dcol = int(ncols) / 2; + unsigned i = 0; + for (int row = - drow; row <= drow; ++row) + for (int col = - dcol; col <= dcol; ++col) + if (values[i++]) + insert(dpoint2d(row, col)); + } + + bool + window2d::is_empty() const + { + // typedef internal::set_of_<dpoint2d> impl; + return this->impl::is_empty(); + } + + bool + window2d::is_centered() const + { + static dpoint2d O(0, 0); + return this->has(O); + } + + bool + window2d::is_symmetric() const + { + // FIXME: nyi + return false; + } + + mln::piter + window2d::fwd_qiter(const GenPoint& p) const + { + return new window2d_fwd_qiter(*this, p); + } + + mln::piter + window2d::bkd_qiter(const GenPoint& p) const + { + return new window2d_bkd_qiter(*this, p); + } + + window2d& + window2d::clone() const + { + return *new window2d(*this); + } + +} // end of namespace mln Index: milena/core/macros.hh --- milena/core/macros.hh (revision 0) +++ milena/core/macros.hh (revision 0) @@ -0,0 +1,28 @@ +#ifndef MLN_CORE_MACROS_HH +# define MLN_CORE_MACROS_HH + + +# define oln_point(T) typename T::point +# define oln_dpoint(T) typename T::dpoint +# define oln_psite(T) typename T::psite +# define oln_pset(T) typename T::pset +# define oln_box(T) typename T::box +# define oln_coord(T) typename T::coord + +# define oln_piter(T) typename T::piter +# define oln_fwd_piter(T) typename T::fwd_piter +# define oln_bkd_piter(T) typename T::bkd_piter + +# define oln_qiter(T) typename T::qiter +# define oln_fwd_qiter(T) typename T::fwd_qiter +# define oln_bkd_qiter(T) typename T::bkd_qiter + +# define oln_niter(T) typename T::niter +# define oln_fwd_niter(T) typename T::fwd_niter +# define oln_bkd_niter(T) typename T::bkd_niter + +# define oln_value(T) typename T::value +# define oln_rvalue(T) typename T::rvalue +# define oln_lvalue(T) typename T::lvalue + +#endif // ! MLN_CORE_MACROS_HH Index: milena/core/dpoints_qiter.hh --- milena/core/dpoints_qiter.hh (revision 0) +++ milena/core/dpoints_qiter.hh (revision 0) @@ -0,0 +1,123 @@ +#ifndef MLN_CORE_DPOINTS_QITER_HH +# define MLN_CORE_DPOINTS_QITER_HH + +# include <core/concept/piter.hh> +# include <core/concept/genpoint.hh> + + +namespace mln +{ + + template <typename D> + class dpoints_fwd_qiter : public Piter< dpoints_fwd_qiter<D> > + { + public: + + enum { dim = D::dim }; + + typedef D dpoint; + typedef oln_point(D) point; + typedef point psite; + typedef oln_coord(D) coord; + + template <typename Dps, typename Pref> + dpoints_fwd_qiter(const Dps& dps, + const GenPoint<Pref>& p_ref); + + operator point() const; + const point* pointer() const; + + bool is_valid() const; + void invalidate(); + void start(); + void next_(); + + coord operator[](unsigned i) const; + + private: + const std::vector<D>& dps_; + const point& p_ref_; + + unsigned i_; + point p_; + void update_p_(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename D> + template <typename Dps, typename Pref> + dpoints_fwd_qiter<D>::dpoints_fwd_qiter(const Dps& dps, + const GenPoint<Pref>& p_ref) + : dps_(exact(dps).vec()), + p_ref_(* force_exact<Pref>(p_ref).pointer()) + { + invalidate(); + } + + template <typename D> + dpoints_fwd_qiter<D>::operator point() const + { + assert(is_valid()); + return p_; + } + + template <typename D> + const oln_point(D)* + dpoints_fwd_qiter<D>::pointer() const + { + return & p_; + } + + template <typename D> + bool + dpoints_fwd_qiter<D>::is_valid() const + { + return i_ != dps_.size(); + } + + template <typename D> + void + dpoints_fwd_qiter<D>::invalidate() + { + i_ = dps_.size(); + } + + template <typename D> + void + dpoints_fwd_qiter<D>::start() + { + i_ = 0; + update_p_(); + } + + template <typename D> + void + dpoints_fwd_qiter<D>::next_() + { + ++i_; + update_p_(); + } + + template <typename D> + void + dpoints_fwd_qiter<D>::update_p_() + { + if (is_valid()) + p_ = p_ref_ + dps_[i_]; + } + + template <typename D> + oln_coord(D) + dpoints_fwd_qiter<D>::operator[](unsigned i) const + { + return p_[i]; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_DPOINTS_QITER_HH Index: milena/core/window2d_qiter.cc --- milena/core/window2d_qiter.cc (revision 0) +++ milena/core/window2d_qiter.cc (revision 0) @@ -0,0 +1,125 @@ +# include <core/window2d_qiter.hh> +# include <core/window2d.hh> + + +namespace mln +{ + + // fwd + + window2d_fwd_qiter::window2d_fwd_qiter(const Window& w, + const GenPoint& p) + : w_(dynamic_cast<const window2d&>(w)), + p_ref_(dynamic_cast<const point2d&>(p.pointee())) + { + // FIXME: test! + invalidate(); + } + + bool + window2d_fwd_qiter::is_valid() const + { + return i_ != w_.nelements(); + } + + void + window2d_fwd_qiter::invalidate() + { + i_ = w_.nelements(); + } + + void + window2d_fwd_qiter::start() + { + i_ = 0; + update_p_(); + } + + const point2d& + window2d_fwd_qiter::psite() const + { + return p_; + } + + window2d_fwd_qiter& + window2d_fwd_qiter::clone() const + { + return *new window2d_fwd_qiter(*this); + } + + void + window2d_fwd_qiter::next_() + { + ++i_; + update_p_(); + } + + void + window2d_fwd_qiter::update_p_() + { + if (is_valid()) + p_ = static_cast<const point2d&>(p_ref_.point()) + w_.element(i_); + } + + + + + + // bkd + + window2d_bkd_qiter::window2d_bkd_qiter(const Window& w, + const GenPoint& p) + : w_(dynamic_cast<const window2d&>(w)), + p_ref_(dynamic_cast<const point2d&>(p.pointee())) + { + // FIXME: test! + invalidate(); + } + + bool + window2d_bkd_qiter::is_valid() const + { + return i_ != w_.nelements(); + } + + void + window2d_bkd_qiter::invalidate() + { + i_ = w_.nelements(); + } + + void + window2d_bkd_qiter::start() + { + i_ = 0; + update_p_(); + } + + const point2d& + window2d_bkd_qiter::psite() const + { + return p_; + } + + window2d_bkd_qiter& + window2d_bkd_qiter::clone() const + { + return *new window2d_bkd_qiter(*this); + } + + void + window2d_bkd_qiter::next_() + { + ++i_; + update_p_(); + } + + void + window2d_bkd_qiter::update_p_() + { + if (is_valid()) + p_ = static_cast<const point2d&>(p_ref_.point()) + w_.element(i_); + } + + +} // end of namespace mln Index: milena/core/box.hh --- milena/core/box.hh (revision 0) +++ milena/core/box.hh (revision 0) @@ -0,0 +1,68 @@ +#ifndef MLN_CORE_BOX_HH +# define MLN_CORE_BOX_HH + +# include <core/concept/box.hh> +# include <core/point.hh> + + +namespace mln +{ + + // fwd decl + template <typename P> struct box_fwd_piter_; + template <typename P> struct box_bkd_piter_; + + + template <typename P> + struct box_ : public Box< box_<P> > + { + typedef P psite; + typedef P point; + + typedef box_fwd_piter_<P> fwd_piter; + typedef box_bkd_piter_<P> bkd_piter; + typedef fwd_piter piter; + + P pmin() const { return pmin_; } + P& pmin() { return pmin_; } + + P pmax() const { return pmax_; } + P& pmax() { return pmax_; } + + box_() + { + } + + box_(const point& pmin, const point& pmax) + : pmin_(pmin), + pmax_(pmax) + { + } + + bool has(const P& p) const + { + for (unsigned i = 0; i < P::dim; ++i) + if (p[i] < pmin_[i] or p[i] > pmax_[i]) + return false; + return true; + } + + protected: + P pmin_, pmax_; + }; + + + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const box_<P>& b) + { + return ostr << "[" << b.pmin() << ".." << b.pmax() << ']'; + } + + +} // end of namespace mln + + +# include <core/box_piter.hh> + + +#endif // ! MLN_CORE_BOX_HH Index: milena/core/point.hh --- milena/core/point.hh (revision 0) +++ milena/core/point.hh (revision 0) @@ -0,0 +1,74 @@ +#ifndef MLN_CORE_POINT_HH +# define MLN_CORE_POINT_HH + +# include <core/concept/point.hh> +# include <core/internal/coord_impl.hh> + + +namespace mln +{ + + // fwd decl + template <unsigned n, typename C> struct dpoint_; + + + template <unsigned n, typename C> + struct point_ : public Point< point_<n,C> >, + public internal::mutable_coord_impl_< n, C, point_<n,C> > + { + enum { dim = n }; + typedef C coord; + typedef dpoint_<n,C> dpoint; + + C operator[](unsigned i) const; + C& operator[](unsigned i); + + point_(); + point_(C c); + void set_all(C c); + + protected: + C coord_[n]; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, typename C> + C point_<n,C>::operator[](unsigned i) const + { + assert(i < n); + return coord_[i]; + } + + template <unsigned n, typename C> + C& point_<n,C>::operator[](unsigned i) + { + assert(i < n); + return coord_[i]; + } + + template <unsigned n, typename C> + point_<n,C>::point_() + { + } + + template <unsigned n, typename C> + point_<n,C>::point_(C c) + { + set_all(c); + } + + template <unsigned n, typename C> + void point_<n,C>::set_all(C c) + { + for (unsigned i = 0; i < n; ++i) + coord_[i] = c; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_POINT_HH Index: milena/core/rectangle2d.hh --- milena/core/rectangle2d.hh (revision 0) +++ milena/core/rectangle2d.hh (revision 0) @@ -0,0 +1,82 @@ +#ifndef MLN_CORE_RECTANGLE2D_HH +# define MLN_CORE_RECTANGLE2D_HH + +# include <core/concept/window.hh> +# include <core/internal/set_of.hh> +# include <core/dpoint2d.hh> +# include <core/dpoints_qiter.hh> + + +namespace mln +{ + + struct rectangle2d : public Window< rectangle2d >, + public internal::set_of_<dpoint2d> + { + typedef dpoints_fwd_qiter<dpoint2d> fwd_qiter; + typedef dpoints_bkd_qiter<dpoint2d> bkd_qiter; + typedef fwd_qiter qiter; + + rectangle2d(unsigned half_height, unsigned half_width); + + bool is_centered() const; + bool is_symmetric() const; + + unsigned height() const; + unsigned width() const; + + protected: + unsigned half_height_, half_width_; + }; + + std::ostream& operator<<(std::ostream& ostr, + const rectangle2d& win); + + +# ifndef MLN_INCLUDE_ONLY + + rectangle2d::rectangle2d(unsigned half_height, unsigned half_width) + : half_height_(half_height), + half_width_(half_width) + { + assert(half_height != 0 and half_width != 0); + const int drow = half_height, dcol = half_width; + for (int row = - drow; row <= drow; ++row) + for (int col = - dcol; col <= dcol; ++col) + insert(mk_dpoint2d(row, col)); + } + + bool rectangle2d::is_centered() const + { + return true; + } + + bool rectangle2d::is_symmetric() const + { + return true; + } + + unsigned rectangle2d::height() const + { + return 2 * half_height_ + 1; + } + + unsigned rectangle2d::width() const + { + return 2 * half_width_ + 1; + } + + std::ostream& operator<<(std::ostream& ostr, + const rectangle2d& win) + { + ostr << "[width=" << win.width() << ", height=" << win.height() << ']'; + return ostr; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + + +#endif // ! MLN_CORE_RECTANGLE2D_HH Index: milena/core/box_piter.hh --- milena/core/box_piter.hh (revision 0) +++ milena/core/box_piter.hh (revision 0) @@ -0,0 +1,156 @@ +#ifndef MLN_CORE_BOX_PITER_HH +# define MLN_CORE_BOX_PITER_HH + +# include <core/concept/piter.hh> +# include <core/concept/box.hh> + + +namespace mln +{ + + template <typename P> + class box_fwd_piter_ : public Piter< box_fwd_piter_<P> > + { + public: + + enum { dim = P::dim }; + + typedef P psite; + typedef P point; + typedef oln_coord(P) coord; + typedef oln_dpoint(P) dpoint; + + box_fwd_piter_(const box_<P>& b) + : b_(b) + { + nop_ = b_.pmax(); + ++nop_[0]; + invalidate(); + } + + operator P() const + { + return p_; + } + + const P* pointer() const + { + return & p_; + } + + coord operator[](unsigned i) const + { + assert(i < dim); + return p_[i]; + } + + bool is_valid() const + { + return p_ != nop_; + } + + void invalidate() + { + p_ = nop_; + } + + void start() + { + p_ = b_.pmin(); + } + + void next_() + { + for (int i = dim - 1; i >= 0; --i) + if (p_[i] = b_.pmax()[i]) + p_[i] = b_.pmin()[i]; + else + { + ++p_[i]; + break; + } + if (p_ = b_.pmin()) + p_ = nop_; + } + + private: + const box_<P>& b_; + P p_, nop_; + }; + + + + template <typename P> + class box_bkd_piter_ : public Piter< box_bkd_piter_<P> > + { + public: + + enum { dim = P::dim }; + + typedef P psite; + typedef P point; + typedef oln_coord(P) coord; + + box_bkd_piter_(const box_<P>& b) + : b_(b) + { + nop_ = b_.pmin(); + --nop_[0]; + invalidate(); + } + + operator P() const + { + return p_; + } + + const P* pointer() const + { + return & p_; + } + + coord operator[](unsigned i) const + { + assert(i < dim); + return p_[i]; + } + + bool is_valid() const + { + return p_ != nop_; + } + + void invalidate() + { + p_ = nop_; + } + + void start() + { + p_ = b_.pmax(); + } + + void next_() + { + for (int i = dim - 1; i >= 0; --i) + if (p_[i] = b_.pmin()[i]) + p_[i] = b_.pmax()[i]; + else + { + --p_[i]; + break; + } + if (p_ = b_.pmax()) + p_ = nop_; + } + + private: + const box_<P>& b_; + P p_, nop_; + }; + + +} // end of namespace mln + + +#endif // ! MLN_CORE_BOX_PITER_HH Index: milena/core/dpoint.hh --- milena/core/dpoint.hh (revision 0) +++ milena/core/dpoint.hh (revision 0) @@ -0,0 +1,74 @@ +#ifndef MLN_CORE_DPOINT_HH +# define MLN_CORE_DPOINT_HH + +# include <core/concept/dpoint.hh> +# include <core/internal/coord_impl.hh> + + +namespace mln +{ + + // fwd decl + template <unsigned n, typename C> struct point_; + + + template <unsigned n, typename C> + struct dpoint_ : public Dpoint< dpoint_<n,C> >, + public internal::mutable_coord_impl_< n, C, dpoint_<n,C> > + { + enum { dim = n }; + typedef C coord; + typedef point_<n,C> point; + + C operator[](unsigned i) const; + C& operator[](unsigned i); + + dpoint_(); + dpoint_(C c); + void set_all(C c); + + protected: + C coord_[n]; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, typename C> + C dpoint_<n,C>::operator[](unsigned i) const + { + assert(i < n); + return coord_[i]; + } + + template <unsigned n, typename C> + C& dpoint_<n,C>::operator[](unsigned i) + { + assert(i < n); + return coord_[i]; + } + + template <unsigned n, typename C> + dpoint_<n,C>::dpoint_() + { + } + + template <unsigned n, typename C> + dpoint_<n,C>::dpoint_(C c) + { + set_all(c); + } + + template <unsigned n, typename C> + void dpoint_<n,C>::set_all(C c) + { + for (unsigned i = 0; i < n; ++i) + coord_[i] = c; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_DPOINT_HH Index: milena/core/concept/image.hh --- milena/core/concept/image.hh (revision 0) +++ milena/core/concept/image.hh (revision 0) @@ -0,0 +1,92 @@ +#ifndef MLN_CORE_CONCEPT_IMAGE_HH +# define MLN_CORE_CONCEPT_IMAGE_HH + +# include <core/concept/point_set.hh> + + +namespace mln +{ + + template <typename E> + struct Image : public Object<E> + { + /* + // to be provided in concrete image classes: + + typedef value; + typedef rvalue; + typedef lvalue; + + bool has_data() const; + + bool owns_(const psite& p) const; // default is like "has(p)" + const pset& domain() const; + + rvalue operator()(const psite& p) const; + lvalue operator()(const psite& p); + + + // provided by internal::image_base_: + + typedef pset; + typedef point; + typedef psite; + + typedef piter; + typedef fwd_piter; + typedef bkd_piter; + + bool has(const psite& p) const; + const box_<point>& bbox() const; + */ + + protected: + Image(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Image<E>::Image() + { + // provided by internal::image_base_: + + typedef oln_pset(E) pset; + typedef oln_point(E) point; + typedef oln_psite(E) psite; + + typedef oln_piter(E) piter; + typedef oln_fwd_piter(E) fwd_piter; + typedef oln_bkd_piter(E) bkd_piter; + + bool (E::*m1)(const psite& p) const = & E::has; + m1 = 0; + const box_<point>& (E::*m2)() const = & E::bbox; + m2 = 0; + + // to be provided in concrete image classes: + + typedef oln_value(E) value; + typedef oln_rvalue(E) rvalue; + typedef oln_lvalue(E) lvalue; + + bool (E::*m3)() const = & E::has_data; + m3 = 0; + bool (E::*m4)(const psite& p) const = & E::owns_; + m4 = 0; + const pset& (E::*m5)() const = & E::domain; + m5 = 0; + + rvalue (E::*m6)(const psite& p) const = & E::operator(); + m6 = 0; + lvalue (E::*m7)(const psite& p) = & E::operator(); + m7 = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_IMAGE_HH Index: milena/core/concept/genpoint.hh --- milena/core/concept/genpoint.hh (revision 0) +++ milena/core/concept/genpoint.hh (revision 0) @@ -0,0 +1,136 @@ +#ifndef MLN_CORE_CONCEPT_GENPOINT_HH +# define MLN_CORE_CONCEPT_GENPOINT_HH + +# include <core/concept/object.hh> +# include <core/macros.hh> +# include <mlc/equal.hh> +# include <mlc/same_point.hh> + + +namespace mln +{ + + template <typename E> + struct GenPoint // stand-alone class! + { + /* + typedef point; + typedef dpoint; + typedef coord; + typedef topo; // FIXME + + either Point + or operator point() const; + + const point* pointer() const; + coord operator[](unsigned i) const; + */ + + protected: + GenPoint(); + }; + + + template <typename Pl, typename Pr> + bool operator=(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs); + + template <typename Pl, typename Pr> + bool operator<(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs); + + template <typename Pl, typename Pr> + oln_dpoint(Pl) + operator-(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs); + + template <typename P> + oln_point(P) + operator+(const GenPoint<P>& lhs, const oln_dpoint(P)& rhs); + + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const GenPoint<P>& p); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + GenPoint<E>::GenPoint() + { + typedef oln_point(E) point; + typedef oln_dpoint(E) dpoint; + typedef oln_coord(E) coord; + const point* (E::*m1)() const = & E::pointer; + m1 = 0; + coord (E::*m2)(unsigned i) const = & E::operator[]; + m2 = 0; + } + + template <typename Pl, typename Pr> + bool operator=(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs) + { + const Pl& lhs_ = force_exact<Pl>(lhs); + const Pr& rhs_ = force_exact<Pr>(rhs); + mlc::same_point<Pl, Pr>::check(); + for (unsigned i = 0; i < Pl::dim; ++i) + if (lhs_[i] != rhs_[i]) + return false; + return true; + } + + template <typename Pl, typename Pr> + bool operator<(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs) + { + mlc::same_point<Pl, Pr>::check(); + const Pl& lhs_ = force_exact<Pl>(lhs); + const Pr& rhs_ = force_exact<Pr>(rhs); + for (unsigned i = 0; i < Pl::dim; ++i) + { + if (lhs_[i] = rhs_[i]) + continue; + return lhs_[i] < rhs_[i]; + } + return false; + } + + + template <typename Pl, typename Pr> + oln_dpoint(Pl) + operator-(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs) + { + const Pl& lhs_ = force_exact<Pl>(lhs); + const Pr& rhs_ = force_exact<Pr>(rhs); + oln_dpoint(Pl) tmp; + for (unsigned i = 0; i < Pl::dim; ++i) + tmp[i] = lhs_[i] - rhs_[i]; + return tmp; + } + + + template <typename P> + oln_point(P) + operator+(const GenPoint<P>& lhs, const oln_dpoint(P)& rhs) + { + const P& lhs_ = force_exact<P>(lhs); + oln_point(P) tmp; + for (unsigned i = 0; i < P::dim; ++i) + tmp[i] = lhs_[i] + rhs[i]; + return tmp; + } + + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const GenPoint<P>& p) + { + const P& p_ = force_exact<P>(p); + ostr << '('; + for (unsigned i = 0; i < P::dim; ++i) + { + ostr << p_[i] + << (i = P::dim - 1 ? ')' : ','); + } + return ostr; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_GENPOINT_HH Index: milena/core/concept/piter.hh --- milena/core/concept/piter.hh (revision 0) +++ milena/core/concept/piter.hh (revision 0) @@ -0,0 +1,45 @@ +#ifndef MLN_CORE_CONCEPT_PITER_HH +# define MLN_CORE_CONCEPT_PITER_HH + +# include <core/concept/iterator.hh> +# include <core/concept/genpoint.hh> + + +namespace mln +{ + + template <typename E> + struct Piter : public Iterator<E>, + public GenPoint<E> + { + /* + typedef psite; + typedef point; + + operator psite() const; + operator point() const; + const point* pointer() const; + */ + + protected: + Piter(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Piter<E>::Piter() + { + typedef oln_psite(E) psite; + typedef oln_point(E) point; + const point* (E::*m)() const = & E::pointer; + m = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_PITER_HH Index: milena/core/concept/point_set.hh --- milena/core/concept/point_set.hh (revision 0) +++ milena/core/concept/point_set.hh (revision 0) @@ -0,0 +1,55 @@ +#ifndef MLN_CORE_CONCEPT_POINT_SET_HH +# define MLN_CORE_CONCEPT_POINT_SET_HH + +# include <core/concept/point.hh> +# include <core/concept/piter.hh> + + +namespace mln +{ + + template <typename E> + struct Point_Set : public Object<E> + { + /* + typedef point; + typedef psite; + typedef piter; + typedef fwd_piter; + typedef bkd_piter; + + bool has(const psite& p) const; + const box_<point>& bbox() const; + */ + + protected: + Point_Set(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + // fwd decl + template <typename P> struct box_; + + template <typename E> + Point_Set<E>::Point_Set() + { + typedef oln_point(E) point; + typedef oln_psite(E) psite; + typedef oln_piter(E) piter; + typedef oln_fwd_piter(E) fwd_piter; + typedef oln_bkd_piter(E) bkd_piter; + + bool (E::*m1)(const psite& p) const = & E::has; + m1 = 0; + const box_<point>& (E::*m2)() const = & E::bbox; + m2 = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_POINT_SET_HH Index: milena/core/concept/psite.hh --- milena/core/concept/psite.hh (revision 0) +++ milena/core/concept/psite.hh (revision 0) @@ -0,0 +1,38 @@ +#ifndef MLN_CORE_CONCEPT_PSITE_HH +# define MLN_CORE_CONCEPT_PSITE_HH + +# include <core/concept/genpoint.hh> + + +namespace mln +{ + + template <typename E> + struct Psite : public Object<E>, + public GenPoint<E> + { + /* + const point* pointer() const + { + return & (exact(this)->operator point()); + } + */ + + protected: + Psite(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Psite<E>::Psite() + { + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_PSITE_HH Index: milena/core/concept/object.hh --- milena/core/concept/object.hh (revision 0) +++ milena/core/concept/object.hh (revision 0) @@ -0,0 +1,37 @@ +#ifndef MLN_CORE_CONCEPT_OBJECT_HH +# define MLN_CORE_CONCEPT_OBJECT_HH + +# include <cassert> +# include <iostream> + +# include <core/macros.hh> + + +namespace mln +{ + + template <typename E> + struct Object + { + protected: + Object(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Object<E>::Object() + { + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +# include <core/exact.hh> +# include <core/ops.hh> + + +#endif // ! MLN_CORE_CONCEPT_OBJECT_HH Index: milena/core/concept/window.hh --- milena/core/concept/window.hh (revision 0) +++ milena/core/concept/window.hh (revision 0) @@ -0,0 +1,50 @@ +#ifndef MLN_CORE_CONCEPT_WINDOW_HH +# define MLN_CORE_CONCEPT_WINDOW_HH + +# include <core/concept/object.hh> + + +namespace mln +{ + + template <typename E> + struct Window : public Object<E> + { + /* + typedef qiter; + typedef fwd_qiter; + typedef bkd_qiter; + + bool is_empty() const; + bool is_centered() const; + bool is_symmetric() const; + */ + + protected: + Window(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Window<E>::Window() + { + typedef oln_qiter(E) qiter; + typedef oln_fwd_qiter(E) fwd_qiter; + typedef oln_bkd_qiter(E) bkd_qiter; + + bool (E::*m1)() const = & E::is_empty; + m1 = 0; + bool (E::*m2)() const = & E::is_centered; + m2 = 0; + bool (E::*m3)() const = & E::is_symmetric; + m3 = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_WINDOW_HH Index: milena/core/concept/box.hh --- milena/core/concept/box.hh (revision 0) +++ milena/core/concept/box.hh (revision 0) @@ -0,0 +1,48 @@ +#ifndef MLN_CORE_CONCEPT_BOX_HH +# define MLN_CORE_CONCEPT_BOX_HH + +# include <core/concept/point_set.hh> + + +namespace mln +{ + + template <typename E> + struct Box : public Point_Set<E> + { + /* + const point& pmin() const; + const point& pmax() const; + */ + + const E& bbox() const; // final + + protected: + Box(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + const E& Box<E>::bbox() const + { + return exact(*this); + } + + template <typename E> + Box<E>::Box() + { + typedef oln_point(E) point; + point (E::*m1)() const = & E::pmin; + m1 = 0; + point (E::*m2)() const = & E::pmax; + m2 = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_BOX_HH Index: milena/core/concept/iterator.hh --- milena/core/concept/iterator.hh (revision 0) +++ milena/core/concept/iterator.hh (revision 0) @@ -0,0 +1,58 @@ +#ifndef MLN_CORE_CONCEPT_ITERATOR_HH +# define MLN_CORE_CONCEPT_ITERATOR_HH + +# include <core/concept/object.hh> + + +# define for_all(x) for(x.start(); x.is_valid(); x.next()) + + +namespace mln +{ + + template <typename E> + struct Iterator : public Object<E> + { + /* + bool is_valid() const; + void invalidate(); + void start(); + void next_(); + */ + + void next(); // final + + protected: + Iterator(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + void Iterator<E>::next() // final + { + assert(exact(this)->is_valid()); + exact(this)->next_(); + } + + template <typename E> + Iterator<E>::Iterator() + { + bool (E::*m1)() const = & E::is_valid; + m1 = 0; + void (E::*m2)() = & E::invalidate; + m2 = 0; + void (E::*m3)() = & E::start; + m3 = 0; + void (E::*m4)() = & E::next_; + m4 = 0; + } + +# endif // ! MLN_INCLUDE_ONLY + + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_ITERATOR_HH Index: milena/core/concept/point.hh --- milena/core/concept/point.hh (revision 0) +++ milena/core/concept/point.hh (revision 0) @@ -0,0 +1,65 @@ +#ifndef MLN_CORE_CONCEPT_POINT_HH +# define MLN_CORE_CONCEPT_POINT_HH + +# include <core/concept/psite.hh> + + +namespace mln +{ + + template <typename P> + struct Point : public Psite<P> + { + // final + typedef P point; + const P* pointer() const; + + protected: + Point(); + }; + + + template <typename P> + P& operator+=(Point<P>& lhs, const oln_dpoint(P)& rhs); + + template <typename P> + P& operator-=(Point<P>& lhs, const oln_dpoint(P)& rhs); + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename P> + Point<P>::Point() + { + } + + template <typename P> + const P* Point<P>::pointer() const + { + return exact(this); + } + + template <typename P> + P& operator+=(Point<P>& lhs, const oln_dpoint(P)& rhs) + { + for (unsigned i = 0; i < P::dim; ++i) + exact(lhs)[i] += rhs[i]; + return lhs; + } + + template <typename P> + P& operator-=(Point<P>& lhs, const oln_dpoint(P)& rhs) + { + for (unsigned i = 0; i < P::dim; ++i) + exact(lhs)[i] -= rhs[i]; + return lhs; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + + +#endif // ! MLN_CORE_CONCEPT_POINT_HH Index: milena/core/concept/dpoint.hh --- milena/core/concept/dpoint.hh (revision 0) +++ milena/core/concept/dpoint.hh (revision 0) @@ -0,0 +1,99 @@ +#ifndef MLN_CORE_CONCEPT_DPOINT_HH +# define MLN_CORE_CONCEPT_DPOINT_HH + +# include <core/concept/object.hh> + + +namespace mln +{ + + + template <typename E> + struct Dpoint : public Object<E> + { + /* + typedef point; + typedef coord; + enum { dim }; + coord operator[](unsigned i) const; + */ + + protected: + Dpoint(); + }; + + + template <typename D> + D operator-(const Dpoint<D>& dp); + + template <typename Dl, typename Dr> + bool operator=(const Dpoint<Dl>& lhs, const Dpoint<Dr>& rhs); + + template <typename Dl, typename Dr> + bool operator<(const Dpoint<Dl>& lhs, const Dpoint<Dr>& rhs); + + template <typename D> + std::ostream& operator<<(std::ostream& ostr, const Dpoint<D>& dp); + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + Dpoint<E>::Dpoint() + { + typedef oln_point(E) point; + typedef oln_coord(E) coord; + enum { dim = E::dim }; + coord (E::*m)(unsigned i) const = & E::operator[]; + m = 0; + } + + template <typename D> + D operator-(const Dpoint<D>& dp) + { + D tmp; + for (unsigned i = 0; i < D::dim; ++i) + tmp[i] = - exact(dp)[i]; + return tmp; + } + + template <typename Dl, typename Dr> + bool operator=(const Dpoint<Dl>& lhs, const Dpoint<Dr>& rhs) + { + for (unsigned i = 0; i < Dl::dim; ++i) + if (exact(lhs)[i] != exact(rhs)[i]) + return false; + return true; + } + + template <typename Dl, typename Dr> + bool operator<(const Dpoint<Dl>& lhs, const Dpoint<Dr>& rhs) + { + for (unsigned i = 0; i < Dl::dim; ++i) + { + if (exact(lhs)[i] = exact(rhs)[i]) + continue; + return exact(lhs)[i] < exact(rhs)[i]; + } + return false; + } + + template <typename D> + std::ostream& operator<<(std::ostream& ostr, const Dpoint<D>& dp) + { + ostr << '('; + for (unsigned i = 0; i < D::dim; ++i) + { + ostr << exact(dp)[i] + << (i = D::dim - 1 ? ')' : ','); + } + return ostr; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_DPOINT_HH Index: milena/core/window2d.hh --- milena/core/window2d.hh (revision 0) +++ milena/core/window2d.hh (revision 0) @@ -0,0 +1,39 @@ +#ifndef MLN_CORE_WINDOW2D_HH +# define MLN_CORE_WINDOW2D_HH + +# include <cmath> +# include <core/window.hh> +# include <core/dpoint2d.hh> + + +namespace mln +{ + + typedef window_<dpoint2d> window2d; + + template <unsigned M> + window2d mk_window2d(const bool (&values)[M]); + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned M> + window2d mk_window2d(const bool (&values)[M]) + { + int h = unsigned(std::sqrt(float(M))) / 2; + assert((2 * h + 1) * (2 * h + 1) = M); + window2d tmp; + unsigned i = 0; + for (int row = - h; row <= h; ++row) + for (int col = - h; col <= h; ++col) + if (values[i++]) + tmp.insert(mk_dpoint2d(row, col)); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_WINDOW2D_HH Index: milena/core/ops.hh --- milena/core/ops.hh (revision 0) +++ milena/core/ops.hh (revision 0) @@ -0,0 +1,56 @@ +#ifndef MLN_CORE_OPS_HH +# define MLN_CORE_OPS_HH + +# include <core/concept/object.hh> +# include <core/exact.hh> + + +namespace mln +{ + + template <typename O1, typename O2> + bool operator!=(const Object<O1>& lhs, const Object<O2>& rhs); + + template <typename O1, typename O2> + bool operator>(const Object<O1>& lhs, const Object<O2>& rhs); + + template <typename O1, typename O2> + bool operator>=(const Object<O1>& lhs, const Object<O2>& rhs); + + template <typename O1, typename O2> + bool operator<=(const Object<O1>& lhs, const Object<O2>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename O1, typename O2> + bool operator!=(const Object<O1>& lhs, const Object<O2>& rhs) + { + return not (exact(lhs) = exact(rhs)); + } + + template <typename O1, typename O2> + bool operator>(const Object<O1>& lhs, const Object<O2>& rhs) + { + return exact(rhs) < exact(lhs); + } + + template <typename O1, typename O2> + bool operator>=(const Object<O1>& lhs, const Object<O2>& rhs) + { + return exact(rhs) <= exact(lhs); + } + + template <typename O1, typename O2> + bool operator<=(const Object<O1>& lhs, const Object<O2>& rhs) + { + // if partial ordering, this operator should be re-defined! + return not exact(rhs) < exact(lhs); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_OPS_HH Index: milena/core/exact.hh --- milena/core/exact.hh (revision 0) +++ milena/core/exact.hh (revision 0) @@ -0,0 +1,100 @@ +#ifndef MLN_CORE_EXACT_HH +# define MLN_CORE_EXACT_HH + +# include <core/concept/object.hh> + + +namespace mln +{ + + // exact + + template <typename E> + E* exact(Object<E>* ptr); + + template <typename E> + const E* exact(const Object<E>* ptr); + + template <typename E> + E& exact(Object<E>& ref); + + template <typename E> + const E& exact(const Object<E>& ref); + + + // force_exact + + template <typename E, typename O> + E* force_exact(O* ptr); + + template <typename E, typename O> + const E* force_exact(const O* ptr); + + template <typename E, typename O> + E& force_exact(O& ref); + + template <typename E, typename O> + const E& force_exact(const O& ref); + + + +# ifndef MLN_INCLUDE_ONLY + + // exact + + template <typename E> + E* exact(Object<E>* ptr) + { + return (E*)(void*)ptr; + } + + template <typename E> + const E* exact(const Object<E>* ptr) + { + return (const E*)(const void*)ptr; + } + + template <typename E> + E& exact(Object<E>& ref) + { + return *(E*)(void*)(&ref); + } + + template <typename E> + const E& exact(const Object<E>& ref) + { + return *(const E*)(const void*)(&ref); + } + + // force_exact + + template <typename E, typename O> + E* force_exact(O* ptr) + { + return (E*)(void*)ptr; + } + + template <typename E, typename O> + const E* force_exact(const O* ptr) + { + return (const E*)(const void*)ptr; + } + + template <typename E, typename O> + E& force_exact(O& ref) + { + return *(E*)(void*)(&ref); + } + + template <typename E, typename O> + const E& force_exact(const O& ref) + { + return *(const E*)(const void*)(&ref); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_EXACT_HH Index: milena/core/window.hh --- milena/core/window.hh (revision 0) +++ milena/core/window.hh (revision 0) @@ -0,0 +1,76 @@ +#ifndef MLN_CORE_WINDOW_HH +# define MLN_CORE_WINDOW_HH + +# include <core/concept/window.hh> +# include <core/internal/set_of.hh> +# include <core/dpoint.hh> + + +namespace mln +{ + + // fwd decls + template <typename D> class dpoints_fwd_qiter; + template <typename D> class dpoints_bkd_qiter; + + + template <typename D> + struct window_ : public Window< window_<D> >, + public internal::set_of_<D> + { + typedef dpoints_fwd_qiter<D> fwd_qiter; + typedef dpoints_bkd_qiter<D> bkd_qiter; + typedef fwd_qiter qiter; + + window_(); + + bool is_centered() const; + bool is_symmetric() const; + }; + + template <typename D> + std::ostream& operator<<(std::ostream& ostr, + const window_<D>& win); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename D> + window_<D>::window_() + { + } + + template <typename D> + bool window_<D>::is_centered() const + { + static const D origin(0); + return this->has(origin); + } + + template <typename D> + bool window_<D>::is_symmetric() const + { + assert(0); // FIXME: nyi! + return false; + } + + template <typename D> + std::ostream& operator<<(std::ostream& ostr, + const window_<D>& win) + { + ostr << '['; + for (unsigned i = 0; i < win.nelements(); ++i) + ostr << win.element(i) + << (i = win.nelements() - 1 ? ']' : ','); + return ostr; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +# include <core/dpoints_qiter.hh> + + +#endif // ! MLN_CORE_WINDOW_HH Index: milena/core/image2d.hh --- milena/core/image2d.hh (revision 0) +++ milena/core/image2d.hh (revision 0) @@ -0,0 +1,147 @@ +#ifndef MLN_CORE_IMAGE2D_HH +# define MLN_CORE_IMAGE2D_HH + +# include <core/internal/image_base.hh> +# include <core/box2d.hh> + + +namespace mln +{ + + template <typename T> + struct image2d : public internal::image_base_< box2d, image2d<T> > + { + typedef T value; + typedef const T& rvalue; + typedef T& lvalue; + + image2d(); + image2d(int nrows, int ncols); + image2d(const box2d& b); + + bool has_data() const; + const box2d& domain() const; + + const T& operator()(const point2d& p) const; + T& operator()(const point2d& p); + + ~image2d(); + + private: + + box2d b_; + T* buffer_; + T** array_; + + void allocate_(); + void deallocate_(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + // ctors + + template <typename T> + image2d<T>::image2d() + { + buffer_ = 0; + array_ = 0; + } + + template <typename T> + image2d<T>::image2d(int nrows, int ncols) + { + b_ = mk_box2d(nrows, ncols); + allocate_(); + } + + template <typename T> + image2d<T>::image2d(const box2d& b) + : b_(b) + { + allocate_(); + } + + // methods + + template <typename T> + bool + image2d<T>::has_data() const + { + return buffer_ != 0 and array_ != 0; + } + + template <typename T> + const box2d& + image2d<T>::domain() const + { + return b_; + } + + template <typename T> + const T& + image2d<T>::operator()(const point2d& p) const + { + assert(this->has_data() and this->owns_(p)); + return array_[p.row()][p.col()]; + } + + template <typename T> + T& + image2d<T>::operator()(const point2d& p) + { + assert(this->has_data() and this->owns_(p)); + return array_[p.row()][p.col()]; + } + + template <typename T> + image2d<T>::~image2d() + { + deallocate_(); + } + + // private + + template <typename T> + void + image2d<T>::allocate_() + { + unsigned + nrows = 1 + b_.pmax().row() - b_.pmin().row(), + ncols = 1 + b_.pmax().col() - b_.pmin().col(), + len = nrows * ncols; + buffer_ = new T[len]; + array_ = new T*[nrows]; + T* buf = buffer_ - b_.pmin().col(); + for (unsigned i = 0; i < nrows; ++i) + { + array_[i] = buf; + buf += ncols; + } + array_ -= b_.pmin().row(); + } + + template <typename T> + void + image2d<T>::deallocate_() + { + if (buffer_) + { + delete[] buffer_; + buffer_ = 0; + } + if (array_) + { + array_ += b_.pmin().row(); + delete[] array_; + array_ = 0; + } + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_IMAGE2D_HH Index: milena/core/vec.hh --- milena/core/vec.hh (revision 0) +++ milena/core/vec.hh (revision 0) @@ -0,0 +1,35 @@ +#ifndef MLN_CORE_VEC_HH +# define MLN_CORE_VEC_HH + +# include <core/concept/object.hh> + + +namespace mln +{ + + template <unsigned n, typename T> + struct vec : public Object< vec<n,T> > + { + enum { dim = n }; + typedef T coord; + + T& operator[](unsigned i) + { + assert(i < n); + return coord_[i]; + } + + T operator[](unsigned i) const + { + assert(i < n); + return coord_[i]; + } + + protected: + T coord_[n]; + }; + +} // end of namespace mln + + +#endif // ! MLN_CORE_VEC_HH Index: milena/core/internal/coord_impl.hh --- milena/core/internal/coord_impl.hh (revision 0) +++ milena/core/internal/coord_impl.hh (revision 0) @@ -0,0 +1,207 @@ +#ifndef MLN_CORE_INTERNAL_COORD_IMPL_HH +# define MLN_CORE_INTERNAL_COORD_IMPL_HH + +# include <core/concept/object.hh> + + +namespace mln +{ + + namespace internal + { + + // coord_impl + + template <unsigned n, typename C, typename E> + struct coord_impl_; + + template <typename C, typename E> + struct coord_impl_<1, C, E> + { + C ind() const; + }; + + template <typename C, typename E> + struct coord_impl_<2, C, E> + { + C row() const; + C col() const; + }; + + template <typename C, typename E> + struct coord_impl_<3, C, E> + { + C sli() const; + C row() const; + C col() const; + }; + + + // mutable_coord_impl + + template <unsigned n, typename C, typename E> + struct mutable_coord_impl_; + + template <typename C, typename E> + struct mutable_coord_impl_<1, C, E> + { + C ind() const; + C& ind(); + }; + + template <typename C, typename E> + struct mutable_coord_impl_<2, C, E> + { + C row() const; + C& row(); + C col() const; + C& col(); + }; + + template <typename C, typename E> + struct mutable_coord_impl_<3, C, E> + { + C sli() const; + C& sli(); + C row() const; + C& row(); + C col() const; + C& col(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + // coord_impl + + // 1 + + template <typename C, typename E> + C coord_impl_<1, C, E>::ind() const + { + return force_exact<E>(*this)[0]; + } + + // 2 + + template <typename C, typename E> + C coord_impl_<2, C, E>::row() const + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C coord_impl_<2, C, E>::col() const + { + return force_exact<E>(*this)[1]; + } + + // 3 + + template <typename C, typename E> + C coord_impl_<3, C, E>::sli() const + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C coord_impl_<3, C, E>::row() const + { + return force_exact<E>(*this)[1]; + } + + template <typename C, typename E> + C coord_impl_<3, C, E>::col() const + { + return force_exact<E>(*this)[2]; + } + + + // mutable_coord_impl + + // 1 + + template <typename C, typename E> + C mutable_coord_impl_<1, C, E>::ind() const + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C& mutable_coord_impl_<1, C, E>::ind() + { + return force_exact<E>(*this)[0]; + } + + // 2 + + template <typename C, typename E> + C mutable_coord_impl_<2, C, E>::row() const + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C& mutable_coord_impl_<2, C, E>::row() + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C mutable_coord_impl_<2, C, E>::col() const + { + return force_exact<E>(*this)[1]; + } + + template <typename C, typename E> + C& mutable_coord_impl_<2, C, E>::col() + { + return force_exact<E>(*this)[1]; + } + + // 3 + + template <typename C, typename E> + C mutable_coord_impl_<3, C, E>::sli() const + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C& mutable_coord_impl_<3, C, E>::sli() + { + return force_exact<E>(*this)[0]; + } + + template <typename C, typename E> + C mutable_coord_impl_<3, C, E>::row() const + { + return force_exact<E>(*this)[1]; + } + + template <typename C, typename E> + C& mutable_coord_impl_<3, C, E>::row() + { + return force_exact<E>(*this)[1]; + } + + template <typename C, typename E> + C mutable_coord_impl_<3, C, E>::col() const + { + return force_exact<E>(*this)[2]; + } + + template <typename C, typename E> + C& mutable_coord_impl_<3, C, E>::col() + { + return force_exact<E>(*this)[2]; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_COORD_IMPL_HH Index: milena/core/internal/image_adaptor.hh --- milena/core/internal/image_adaptor.hh (revision 0) +++ milena/core/internal/image_adaptor.hh (revision 0) @@ -0,0 +1,87 @@ +#ifndef MLN_CORE_INTERNAL_IMAGE_ADAPTOR_HH +# define MLN_CORE_INTERNAL_IMAGE_ADAPTOR_HH + +# include <core/internal/image_base.hh> + + +namespace mln +{ + + namespace internal + { + + template <typename I, typename E> + struct image_adaptor_ : public internal::image_base_< oln_pset(I), E > + { + typedef oln_psite(I) psite; + typedef oln_pset(I) pset; + + typedef oln_value(I) value; + typedef oln_rvalue(I) rvalue; + typedef oln_lvalue(I) lvalue; + + bool has_data() const; + + bool owns_(const psite& p) const; + const pset& domain() const; + + rvalue operator()(const psite& p) const; + lvalue operator()(const psite& p); + + protected: + I& adaptee_; + image_adaptor_(Image<I>& adaptee); + }; + + // FIXME: image_const_adaptor_ + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename E> + bool image_adaptor_<I,E>::has_data() const + { + return adaptee_.has_data(); + } + + template <typename I, typename E> + bool image_adaptor_<I,E>::owns_(const psite& p) const + { + return adaptee_.owns_(p); + } + + template <typename I, typename E> + const oln_pset(I)& + image_adaptor_<I,E>::domain() const + { + return adaptee_.domain(); + } + + template <typename I, typename E> + oln_rvalue(I) + image_adaptor_<I,E>::operator()(const psite& p) const + { + return adaptee_(p); + } + + template <typename I, typename E> + oln_lvalue(I) + image_adaptor_<I,E>::operator()(const psite& p) + { + return adaptee_(p); + } + + template <typename I, typename E> + image_adaptor_<I,E>::image_adaptor_(Image<I>& adaptee) + : adaptee_(exact(adaptee)) + { + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_IMAGE_ADAPTOR_HH Index: milena/core/internal/image_base.hh --- milena/core/internal/image_base.hh (revision 0) +++ milena/core/internal/image_base.hh (revision 0) @@ -0,0 +1,68 @@ +#ifndef MLN_CORE_INTERNAL_IMAGE_BASE_HH +# define MLN_CORE_INTERNAL_IMAGE_BASE_HH + +# include <core/concept/image.hh> + + +namespace mln +{ + + namespace internal + { + + template <typename S, typename E> + struct image_base_ : public Image<E> + { + typedef S pset; + typedef oln_psite(S) psite; + typedef oln_point(S) point; + + typedef oln_fwd_piter(S) fwd_piter; + typedef oln_bkd_piter(S) bkd_piter; + typedef fwd_piter piter; + + bool has(const psite& p) const; + bool owns_(const psite& p) const; // default + const box_<point>& bbox() const; + + protected: + image_base_(); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename S, typename E> + bool + image_base_<S,E>::has(const psite& p) const + { + return exact(this)->domain().has(p); + } + + template <typename S, typename E> + bool + image_base_<S,E>::owns_(const psite& p) const // default + { + return this->has(p); + } + + template <typename S, typename E> + const box_<oln_point(S)>& + image_base_<S,E>::bbox() const + { + return exact(this)->domain().bbox(); + } + + template <typename S, typename E> + image_base_<S,E>::image_base_() + { + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_IMAGE_BASE_HH Index: milena/core/internal/set_of.hh --- milena/core/internal/set_of.hh (revision 0) +++ milena/core/internal/set_of.hh (revision 0) @@ -0,0 +1,108 @@ +#ifndef MLN_CORE_INTERNAL_SET_OF_HH +# define MLN_CORE_INTERNAL_SET_OF_HH + +# include <vector> +# include <set> +# include <iterator> + + +namespace mln +{ + + namespace internal + { + + template <typename E> + class set_of_ + { + public: + + void insert(const E& elt); + const E& element(unsigned i) const; + unsigned nelements() const; + bool has(const E& elt) const; + bool is_empty() const; + void clear(); + + const std::vector<E>& vec() const; + + protected: + std::vector<E> v_; + + private: + std::set<E> s_; + void update_(); + + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + void + set_of_<E>::insert(const E& elt) + { + s_.insert(elt); + update_(); + } + + template <typename E> + const E& + set_of_<E>::element(unsigned i) const + { + assert(i < v_.size()); + return v_[i]; + } + + template <typename E> + unsigned + set_of_<E>::nelements() const + { + return v_.size(); + } + + template <typename E> + bool + set_of_<E>::has(const E& elt) const + { + return s_.find(elt) != s_.end(); + } + + template <typename E> + bool + set_of_<E>::is_empty() const + { + return v_.size() = 0; + } + + template <typename E> + void + set_of_<E>::clear() + { + v_.clear(); + s_.clear(); + } + + template <typename E> + const std::vector<E>& + set_of_<E>::vec() const + { + return v_; + } + + template <typename E> + void + set_of_<E>::update_() + { + v_.clear(); + std::copy(s_.begin(), s_.end(), std::back_inserter(v_)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::internal + +} // end of namespace mln + + +#endif // ! MLN_CORE_INTERNAL_SET_OF_HH Index: milena/core/box2d.hh --- milena/core/box2d.hh (revision 0) +++ milena/core/box2d.hh (revision 0) @@ -0,0 +1,31 @@ +#ifndef MLN_CORE_BOX2D_HH +# define MLN_CORE_BOX2D_HH + +# include <core/box.hh> +# include <core/point2d.hh> + + +namespace mln +{ + + typedef box_<point2d> box2d; + + box2d mk_box2d(unsigned nrows, unsigned ncols) + { + box2d tmp(mk_point2d(0, 0), + mk_point2d(nrows - 1, ncols - 1)); + return tmp; + } + + box2d mk_box2d(int min_row, int max_row, + int min_col, int max_col) + { + box2d tmp(mk_point2d(min_row, min_col), + mk_point2d(max_row, max_col)); + return tmp; + } + +} // end of namespace mln + + +#endif // ! MLN_CORE_BOX2D_HH Index: milena/core/point2d.hh --- milena/core/point2d.hh (revision 0) +++ milena/core/point2d.hh (revision 0) @@ -0,0 +1,26 @@ +#ifndef MLN_CORE_POINT2D_HH +# define MLN_CORE_POINT2D_HH + +# include <core/point.hh> + + +namespace mln +{ + + typedef point_<2,int> point2d; + + point2d mk_point2d(int row, int col) + { + point2d tmp; + tmp[0] = row; + tmp[1] = col; + return tmp; + } + +} // end of namespace mln + + +# include <core/dpoint2d.hh> + + +#endif // ! MLN_CORE_POINT2D_HH Index: milena/core/safe_image.hh --- milena/core/safe_image.hh (revision 0) +++ milena/core/safe_image.hh (revision 0) @@ -0,0 +1,70 @@ +#ifndef MLN_CORE_SAFE_IMAGE_HH +# define MLN_CORE_SAFE_IMAGE_HH + +# include <core/internal/image_adaptor.hh> + + +namespace mln +{ + + + template <typename I> + struct safe_image : public internal::image_adaptor_< I, safe_image<I> > + { + typedef internal::image_adaptor_< I, safe_image<I> > super; + + safe_image(Image<I>& ima); + + oln_rvalue(I) operator()(const oln_psite(I)& p) const; + oln_lvalue(I) operator()(const oln_psite(I)& p); + }; + + + + template <typename I> + safe_image<I> safe(Image<I>& ima); + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename I> + safe_image<I>::safe_image(Image<I>& ima) + : super(ima) + { + } + + template <typename I> + oln_rvalue(I) + safe_image<I>::operator()(const oln_psite(I)& p) const + { + static oln_value(I) tmp; + if (not this->owns_(p)) + return tmp; + return this->adaptee_(p); + } + + template <typename I> + oln_lvalue(I) + safe_image<I>::operator()(const oln_psite(I)& p) + { + static oln_value(I) tmp; + if (not this->owns_(p)) + return tmp; + return this->adaptee_(p); + } + + template <typename I> + safe_image<I> safe(Image<I>& ima) + { + safe_image<I> tmp(ima); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_SAFE_IMAGE_HH Index: milena/mlc/equal.hh --- milena/mlc/equal.hh (revision 0) +++ milena/mlc/equal.hh (revision 0) @@ -0,0 +1,30 @@ +#ifndef MLN_MLC_EQUAL_HH +# define MLN_MLC_EQUAL_HH + +# include <core/concept/genpoint.hh> + + +namespace mln +{ + + namespace mlc + { + + template <typename T1, typename T2> + struct equal + { + }; + + template <typename T> + struct equal< T, T > + { + static void check() {} + }; + + + } // end of namespace mln::mlc + +} // end of namespace mln + + +#endif // ! MLN_MLC_EQUAL_HH Index: milena/mlc/same_point.hh --- milena/mlc/same_point.hh (revision 0) +++ milena/mlc/same_point.hh (revision 0) @@ -0,0 +1,24 @@ +#ifndef MLN_MLC_SAME_POINT_HH +# define MLN_MLC_SAME_POINT_HH + +# include <mlc/equal.hh> +# include <core/macros.hh> + + +namespace mln +{ + + namespace mlc + { + + template <typename T1, typename T2> + struct same_point : mlc::equal<oln_point(T2), oln_point(T2)> + { + }; + + } // end of namespace mln::mlc + +} // end of namespace mln + + +#endif // ! MLN_MLC_SAME_POINT_HH Index: milena/README --- milena/README (revision 0) +++ milena/README (revision 0) @@ -0,0 +1,14 @@ + +Object + | + | GenPoint + | | + + -- Psite + | | + | + -- Point + | + + -- Iterator + | | + | | GenPoint + | | | + | + -- Piter