https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)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");
}