
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make the from_to conversion mechanism more general. * mln/core/alias/window2d.hh (from_to_): New overload. The code comes from make/window2d.hh * mln/convert/to.hh (to): New static check on O. * mln/convert/from_to.hh: Relax signature. Add tech note. convert/from_to.hh | 20 ++++++++++++----- convert/to.hh | 1 core/alias/window2d.hh | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 6 deletions(-) Index: mln/core/alias/window2d.hh --- mln/core/alias/window2d.hh (revision 2260) +++ mln/core/alias/window2d.hh (working copy) @@ -34,6 +34,7 @@ # include <mln/core/window.hh> # include <mln/core/alias/dpoint2d.hh> +# include <mln/metal/math/sqrt.hh> namespace mln @@ -54,6 +55,22 @@ const window2d& win_c4p(); + namespace convert + { + namespace impl + { + + template <unsigned S> + void from_to_(bool (&values)[S], window2d& win); + + template <unsigned R, unsigned C> + void from_to_(bool (&values)[R][C], window2d& win); + + } // end of namespace mln::convert::impl + + } // end of namespace mln::convert + + # ifndef MLN_INCLUDE_ONLY @@ -74,6 +91,44 @@ return it; } + + namespace convert + { + namespace impl + { + + template <unsigned S> + void + from_to_(bool (&values)[S], window2d& win) + { + mln_precondition(win.is_empty()); // FIXME: or just .clear() it? + enum { h = mlc_sqrt_int(S) / 2 }; + mlc_bool((2 * h + 1) * (2 * h + 1) == S)::check(); + unsigned i = 0; + for (int row = - h; row <= h; ++row) + for (int col = - h; col <= h; ++col) + if (values[i++]) + win.insert(row, col); + } + + template <unsigned R, unsigned C> + void + from_to_(bool (&values)[R][C], window2d& win) + { + mln_precondition(win.is_empty()); // FIXME: or just .clear() it? + mlc_bool(R % 2 == 1)::check(); + mlc_bool(C % 2 == 1)::check(); + const int drow = int(R) / 2, dcol = int(C) / 2; + for (int row = - drow; row <= drow; ++row) + for (int col = - dcol; col <= dcol; ++col) + if (values[row + drow][col + dcol]) + win.insert(row, col); + } + + } // end of namespace mln::convert::impl + + } // end of namespace mln::convert + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/convert/to.hh --- mln/convert/to.hh (revision 2260) +++ mln/convert/to.hh (working copy) @@ -64,6 +64,7 @@ to(const O& from) { mlc_equal(T, mln_exact(T))::check(); + mlc_equal(O, mln_exact(O))::check(); trace::entering("convert::to"); T tmp; Index: mln/convert/from_to.hh --- mln/convert/from_to.hh (revision 2260) +++ mln/convert/from_to.hh (working copy) @@ -56,11 +56,10 @@ /// Conversion of an object \p from towards an object \p to. - template <typename F, typename T> inline void - from_to(const Object<F>& from, Object<T>& to); + from_to(F& from, Object<T>& to); // See below an explanation of this signature. template <typename T> @@ -75,15 +74,23 @@ from_to(const int& from, Object<T>& to); + // Technical note: + + // In order to remain as general as possible (for instance to be + // able to pass a C array to 'from'), the signature cannot be + // "const F& from." It cannot embed the strong typing "Object<*>" + // neither. + + # ifndef MLN_INCLUDE_ONLY namespace impl { - // Default (Object -> Object) means "unknown conversion". + // Default (F -> Object) means "unknown conversion". template <typename F, typename T> void - from_to_(const Object<F>& from, Object<T>& to); + from_to_(const F& from, Object<T>& to); // Image -> Site_Set. @@ -129,10 +136,11 @@ template <typename F, typename T> inline void - from_to(const Object<F>& from, Object<T>& to) + from_to(F& from, Object<T>& to) { trace::entering("convert::from_to"); - impl::from_to_(exact(from), exact(to)); + mlc_equal(F, mln_exact(F))::check(); + impl::from_to_(from, exact(to)); trace::exiting("convert::from_to"); }