https://svn.lrde.epita.fr/svn/oln/trunk
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)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