https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix multiple-windows.
* mln/win/multiple.hh (n): Turn this parameter into dynamic.
Fix.
* doc/tutorial/examples/win_multiple.cc: Update.
doc/tutorial/examples/win_multiple.cc | 8 -
mln/win/multiple.hh | 210 +++++++++++++++++++++++++---------
2 files changed, 164 insertions(+), 54 deletions(-)
Index: doc/tutorial/examples/win_multiple.cc
--- doc/tutorial/examples/win_multiple.cc (revision 2256)
+++ doc/tutorial/examples/win_multiple.cc (working copy)
@@ -2,6 +2,7 @@
# include <mln/core/alias/window2d.hh>
# include <mln/win/multiple.hh>
+// # include <mln/border/fill.hh>
# include <mln/debug/iota.hh>
# include <mln/debug/println.hh>
@@ -39,11 +40,12 @@
using namespace mln;
typedef image2d<unsigned> I;
- I ima(3, 3, 0); // no border
+ I ima(3, 3, 0); // 1);
+ // border::fill(ima, 0);
debug::iota(ima);
debug::println(ima);
- win::multiple<2, window2d, row_oddity> w;
+ win::multiple<window2d, row_oddity> w;
bool vert[] = { 0, 1, 0,
0, 0, 0,
@@ -53,7 +55,7 @@
1, 0, 1,
0, 0, 0 };
w.set_window(1, make::window2d(horiz));
+ mln_assertion(w.size() == 2);
browse(ima, w);
-
}
Index: mln/win/multiple.hh
--- mln/win/multiple.hh (revision 2256)
+++ mln/win/multiple.hh (working copy)
@@ -35,6 +35,7 @@
# include <mln/core/internal/window_base.hh>
# include <mln/core/internal/site_relative_iterator_base.hh>
+# include <mln/util/array.hh>
@@ -45,11 +46,11 @@
{
// Forward declaration.
- template <unsigned n, typename W, typename F> class multiple_qiter;
+ template <typename W, typename F> class multiple_qiter;
- template <unsigned n, typename W, typename F>
- class multiple : public internal::window_base< mln_dpsite(W),
multiple<n,W,F> >
+ template <typename W, typename F>
+ class multiple : public internal::window_base< mln_dpsite(W), multiple<W,F>
>
{
public:
@@ -57,106 +58,213 @@
typedef mln_psite(W) psite;
typedef mln_site(W) site;
- typedef multiple_qiter<n,W,F> fwd_qiter;
- typedef multiple_qiter<n,W,F> bkd_qiter;
- typedef multiple_qiter<n,W,F> qiter;
+ typedef multiple_qiter<W,F> fwd_qiter;
+ typedef multiple_qiter<W,F> bkd_qiter;
+ typedef multiple_qiter<W,F> qiter;
- multiple()
+ multiple();
+
+ multiple(const F& f);
+
+ bool is_empty() const;
+
+ void set_window(unsigned i, const W& win);
+
+ const W& window(unsigned i) const;
+
+ unsigned size() const;
+
+ unsigned size_around(const mln_psite(W)& p) const;
+
+ const mln_dpsite(W)& ith_dp_around(unsigned i, const mln_psite(W)& p)
const;
+
+ private:
+
+ util::array<W> win_;
+ F f_;
+ unsigned size_;
+ };
+
+
+
+ template <typename W, typename F>
+ class multiple_qiter
+ : public internal::site_relative_iterator_base< multiple<W,F>,
+ multiple_qiter<W,F> >
+ {
+ public:
+
+ multiple_qiter();
+
+ template <typename P>
+ multiple_qiter(const multiple<W,F>& w, const P& c);
+
+ /// Test the iterator validity.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void do_start_();
+
+ /// Go to the next point.
+ void do_next_();
+
+ /// Compute the current psite.
+ mln_psite(W) compute_p_() const;
+
+ private:
+ int i_;
+ unsigned n_() const;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // win::multiple<W,F>
+
+ template <typename W, typename F>
+ inline
+ multiple<W,F>::multiple()
: f_()
{
}
- multiple(const F& f)
+ template <typename W, typename F>
+ inline
+ multiple<W,F>::multiple(const F& f)
: f_(f)
{
}
- bool is_empty() const
+ template <typename W, typename F>
+ inline
+ bool
+ multiple<W,F>::is_empty() const
{
- bool res = false;
- for (unsigned i = 0; i < n; ++i)
- if (win_[i].is_empty())
- return true;
- return res;
+ return size_ == 0;
}
- void set_window(unsigned i, const W& win)
+ template <typename W, typename F>
+ inline
+ void
+ multiple<W,F>::set_window(unsigned i, const W& win)
{
- mln_precondition(i < n);
- win_[i] = win;
+ mln_precondition(i == win_.nelements());
+ win_.append(win);
}
- const W& window(unsigned i) const
+ template <typename W, typename F>
+ inline
+ const W&
+ multiple<W,F>::window(unsigned i) const
{
- mln_precondition(i < n);
+ mln_precondition(i < win_.nelements());
return win_[i];
}
- const F& fun() const
+ template <typename W, typename F>
+ inline
+ unsigned
+ multiple<W,F>::size() const
{
- return f_;
+ mln_precondition(win_.nelements() >= 1);
+ unsigned s = win_[0].size();
+ for (unsigned i = 1; i < win_.nelements(); ++i)
+ mln_precondition(win_[i].size() == s);
+ return s;
}
- private:
- W win_[n];
- F f_;
- };
+ template <typename W, typename F>
+ inline
+ unsigned
+ multiple<W,F>::size_around(const mln_psite(W)& p) const
+ {
+ mln_precondition(f_(p) < win_.nelements());
+ return win_[f_(p)].size();
+ }
+ template <typename W, typename F>
+ inline
+ const mln_dpsite(W)&
+ multiple<W,F>::ith_dp_around(unsigned i, const mln_psite(W)& p) const
+ {
+ mln_precondition(f_(p) < win_.nelements());
+ mln_precondition(i < win_[f_(p)].size());
+ return win_[f_(p)].dp(i);
+ }
- template <unsigned n, typename W, typename F>
- class multiple_qiter
- : public internal::site_relative_iterator_base< multiple<n,W,F>,
- multiple_qiter<n,W,F> >
- {
- public:
+ // win::multiple_qiter<W,F>
- multiple_qiter()
+ template <typename W, typename F>
+ inline
+ multiple_qiter<W,F>::multiple_qiter()
{
}
+ template <typename W, typename F>
template <typename P>
- multiple_qiter(const multiple<n,W,F>& w, const P& c)
+ inline
+ multiple_qiter<W,F>::multiple_qiter(const multiple<W,F>& w, const
P& c)
{
- this->change_target(w);
this->center_at(c);
+ // We have to first change the center so that 'invalidate' can
+ // work when changing the target.
+ this->change_target(w);
}
- /// Test the iterator validity.
- bool is_valid_() const
+ template <typename W, typename F>
+ inline
+ bool
+ multiple_qiter<W,F>::is_valid_() const
{
- return i_ != -1;
+ return i_ < n_();
}
- /// Invalidate the iterator.
- void invalidate_()
+ template <typename W, typename F>
+ inline
+ void
+ multiple_qiter<W,F>::invalidate_()
{
- i_ = -1;
+ i_ = n_();
}
- /// Start an iteration.
- void do_start_()
+ template <typename W, typename F>
+ inline
+ void
+ multiple_qiter<W,F>::do_start_()
{
i_ = 0;
}
- /// Go to the next point.
- void do_next_()
+ template <typename W, typename F>
+ inline
+ void
+ multiple_qiter<W,F>::do_next_()
{
++i_;
}
- /// Compute the current psite.
- mln_psite(W) compute_p_() const
+ template <typename W, typename F>
+ inline
+ mln_psite(W)
+ multiple_qiter<W,F>::compute_p_() const
{
- unsigned w = this->s_->fun()(*this->c_);
- return *this->c_ + this->s_->window(w).std_vector()[i_];
+ return *this->c_ + this->s_->ith_dp_around(i_, *this->c_);
}
- private:
- int i_;
- };
+ template <typename W, typename F>
+ inline
+ unsigned
+ multiple_qiter<W,F>::n_() const
+ {
+ return this->s_->size_around(*this->c_);
+ }
+# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::win