
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make basic neighborhoods rely on neighb<W> and fix from_to. * tests/core/other/neighb.cc: Revamp. * doc/tutorial/examples/p_key.cc: Augment. * mln/core/window.hh (clear): New. (insert): New overload. * mln/core/alias/neighb1d.hh, * mln/core/alias/neighb2d.hh, * mln/core/alias/neighb3d.hh: Update. They now rely on neighb<W>. * mln/core/alias/window1d.hh, * mln/core/alias/window2d.hh, * mln/core/alias/window3d.hh: Update. (impl::from_to_): Replace by... (from_to): ...these new overloads. * mln/core/neighb.hh (todo): New. (include): Fix missings. (to_window): Rename as... (win): ...this. (size, delta, hook_win_): New. (impl::from_to_): Replace by... (from_to): ...this and update. * mln/core/concept/neighborhood.hh: Update. * mln/metal/abort.hh (mlc_abort): New. * mln/make/neighb2d.hh: Remove. * mln/convert/to.hh (impl::from_to_): Update call to... (from_to): ...this. * mln/convert/from_to.hh (impl::from_to_): Rename as... (from_to): ...this. Now convert::from_to is a set of overloaded routines; that makes much easier the definitions of new versions. doc/tutorial/examples/p_key.cc | 6 +- mln/convert/from_to.hh | 83 ++++++++++++++++------------------ mln/convert/to.hh | 2 mln/core/alias/neighb1d.hh | 15 +++--- mln/core/alias/neighb2d.hh | 95 +++++++++++++++++++++++++++------------ mln/core/alias/neighb3d.hh | 77 ++++++++++++++----------------- mln/core/alias/window1d.hh | 17 +----- mln/core/alias/window2d.hh | 38 ++++++--------- mln/core/alias/window3d.hh | 17 +----- mln/core/concept/neighborhood.hh | 7 ++ mln/core/neighb.hh | 71 ++++++++++++++++++++++------- mln/core/window.hh | 29 +++++++++++ mln/metal/abort.hh | 2 tests/core/other/neighb.cc | 30 ++++++------ 14 files changed, 287 insertions(+), 202 deletions(-) Index: tests/core/other/neighb.cc --- tests/core/other/neighb.cc (revision 2374) +++ tests/core/other/neighb.cc (working copy) @@ -26,33 +26,37 @@ // Public License. /// \file tests/core/other/neighb.cc -/// \brief Tests on mln::neighb<D> specializations. +/// \brief Tests on regular neighborhoods. #include <mln/core/alias/neighb1d.hh> #include <mln/core/alias/neighb2d.hh> #include <mln/core/alias/neighb3d.hh> +#include <mln/literal/origin.hh> using namespace mln; + template <typename N> -void test(const Neighborhood<N>& nbh, const mln_site(N)& p_ref, - unsigned size) +unsigned +size(const N& nbh) { - mln_niter(N) n(nbh, p_ref); - unsigned i = 0; + mln_site(N) O = literal::origin; + mln_niter(N) n(nbh, O); + unsigned s = 0; for_all(n) - ++i; - mln_assertion(i == size); + ++s; + return s; } + int main() { - test(c2(), point1d(0), 2); + mln_assertion(size(c2()) == 2); - test(c4(), point2d(0, 0), 4); - test(c8(), point2d(0, 0), 8); + mln_assertion(size(c4()) == 4); + mln_assertion(size(c8()) == 8); - test( c6(), point3d(0, 0, 0), 6); - test(c18(), point3d(0, 0, 0), 18); - test(c26(), point3d(0, 0, 0), 26); + mln_assertion(size( c6()) == 6); + mln_assertion(size(c18()) == 18); + mln_assertion(size(c26()) == 26); } Index: doc/tutorial/examples/p_key.cc --- doc/tutorial/examples/p_key.cc (revision 2374) +++ doc/tutorial/examples/p_key.cc (working copy) @@ -41,6 +41,8 @@ for (unsigned i = 0; i < 7; ++i) p += dp[i], s.insert(p.row(), p); + picture(s); + std::cout << s.keys() << std::endl; std::cout << s << std::endl; } @@ -78,8 +80,8 @@ s.remove_key(0); std::cout << s << std::endl; - std::cout << "change key 2 -> 4" << std::endl; - s.change_key(2, 4); + std::cout << "change key 2 -> 5" << std::endl; + s.change_key(2, 5); std::cout << s << std::endl; std::cout << "remove key 3" << std::endl; Index: mln/core/window.hh --- mln/core/window.hh (revision 2374) +++ mln/core/window.hh (working copy) @@ -114,6 +114,9 @@ */ bool is_empty() const; + /// Clear the window. + void clear(); + /*! \brief Give the maximum coordinate gap between the window center and a window point. */ @@ -128,6 +131,10 @@ /// Insert a delta-point \p dp. window<D>& insert(const D& dp); + /// Insert another window \p win. + template <typename W> + window<D>& insert(const Window<W>& win); + /// \{ Insertion of a delta-point with different numbers of /// arguments (coordinates) w.r.t. the dimension. window<D>& insert(const mln_coord(D)& dind); // For 1D or index access. @@ -211,7 +218,6 @@ *this = tmp; } - template <typename D> inline bool @@ -222,6 +228,14 @@ template <typename D> inline + void + window<D>::clear() + { + dps_.clear(); + } + + template <typename D> + inline unsigned window<D>::delta() const { @@ -280,6 +294,19 @@ } template <typename D> + template <typename W> + inline + window<D>& + window<D>::insert(const Window<W>& win_) + { + const W& win = exact(win_); + const unsigned n = win.size(); + for (unsigned i = 0; i < n; ++i) + dps_.insert(win.dp(i)); + return *this; + } + + template <typename D> inline window<D>& window<D>::insert(const mln_coord(D)& dind) Index: mln/core/alias/neighb1d.hh --- mln/core/alias/neighb1d.hh (revision 2374) +++ mln/core/alias/neighb1d.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -36,7 +36,8 @@ # include <cmath> # include <mln/core/neighb.hh> -# include <mln/core/alias/dpoint1d.hh> +# include <mln/core/alias/window1d.hh> +# include <mln/geom/sym.hh> namespace mln @@ -45,7 +46,7 @@ /*! \brief Type alias for a neighborhood defined on the 1D square * grid with integer coordinates. */ - typedef neighb_<dpoint1d> neighb1d; + typedef neighb<window1d> neighb1d; /*! \brief 2-connectivity neighborhood on the 1D grid. @@ -62,12 +63,12 @@ inline const neighb1d& c2() { - static bool flower = true; static neighb1d it; - if (flower) + if (it.size() == 0) { - it.insert(dpoint1d(+1)); - flower = false; + it.hook_win_() + .insert(dpoint1d(-1)) + .insert(dpoint1d(+1)); } return it; } Index: mln/core/alias/neighb2d.hh --- mln/core/alias/neighb2d.hh (revision 2374) +++ mln/core/alias/neighb2d.hh (working copy) @@ -32,11 +32,14 @@ * * \brief Definition of the mln::neighb2d alias and of some classical * 2D neighborhoods. + * + * \todo Add symmetry and non-centering tests in conversion. */ # include <cmath> -# include <mln/core/neighborhood.hh> -# include <mln/core/alias/dpoint2d.hh> +# include <mln/core/alias/window2d.hh> +# include <mln/core/neighb.hh> +# include <mln/convert/from_to.hh> namespace mln @@ -45,14 +48,11 @@ /*! \brief Type alias for a neighborhood defined on the 2D square * grid with integer coordinates. */ - typedef neighborhood<dpoint2d> neighb2d; + typedef neighb<window2d> neighb2d; } -# include <mln/make/neighb2d.hh> - - namespace mln { @@ -101,20 +101,31 @@ + namespace convert + { + + template <unsigned S> + void from_to(const bool (&values)[S], neighb2d& nbh); + + template <unsigned R, unsigned C> + void from_to(bool const (&values)[R][C], neighb2d& nbh); + + } // end of namespace mln::convert + + + # ifndef MLN_INCLUDE_ONLY inline const neighb2d& c4() { - // FIXME: `flower' is probably not a canonical name to state - // whether the neighborhood is initialized or not. :) - static bool flower = true; static neighb2d it; - if (flower) + if (it.size() == 0) { - it.insert(0, 1) - .insert(1, 0); - flower = false; + static const bool vals[] = { 0, 1, 0, + 1, 0, 1, + 0, 1, 0 }; + convert::from_to(vals, it); } return it; } @@ -122,15 +133,13 @@ inline const neighb2d& c8() { - static bool flower = true; static neighb2d it; - if (flower) + if (it.size() == 0) { - it.insert(0, 1) - .insert(1,-1) - .insert(1, 0) - .insert(1, 1); - flower = false; + static const bool vals[] = { 1, 1, 1, + 1, 0, 1, + 1, 1, 1 }; + convert::from_to(vals, it); } return it; } @@ -138,12 +147,13 @@ inline const neighb2d& c2_row() { - static bool flower = true; static neighb2d it; - if (flower) + if (it.size() == 0) { - it.insert(0, 1); - flower = false; + static const bool vals[] = { 0, 0, 0, + 1, 0, 1, + 0, 0, 0 }; + convert::from_to(vals, it); } return it; } @@ -151,16 +161,45 @@ inline const neighb2d& c2_col() { - static bool flower = true; static neighb2d it; - if (flower) + if (it.size() == 0) { - it.insert(1, 0); - flower = false; + static const bool vals[] = { 0, 1, 0, + 0, 0, 0, + 0, 1, 0 }; + convert::from_to(vals, it); } return it; } + + namespace convert + { + + template <unsigned S> + void + from_to(const bool (&values)[S], neighb2d& nbh) + { + enum { h = mlc_sqrt_int(S) / 2 }; + mlc_bool((2 * h + 1) * (2 * h + 1) == S)::check(); + window2d& win = nbh.hook_win_(); + convert::from_to(values, win); + mln_postcondition(win.is_neighbable_()); + } + + template <unsigned R, unsigned C> + void + from_to(bool const (&values)[R][C], neighb2d& nbh) + { + mlc_bool(R % 2 == 1)::check(); + mlc_bool(C % 2 == 1)::check(); + window2d& win = nbh.hook_win_(); + convert::from_to(values, win); + mln_postcondition(win.is_neighbable_()); + } + + } // end of namespace mln::convert + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/alias/neighb3d.hh --- mln/core/alias/neighb3d.hh (revision 2374) +++ mln/core/alias/neighb3d.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -36,7 +36,8 @@ # include <cmath> # include <mln/core/neighb.hh> -# include <mln/core/alias/dpoint3d.hh> +# include <mln/core/alias/window3d.hh> +# include <mln/geom/sym.hh> namespace mln @@ -45,7 +46,7 @@ /*! \brief Type alias for a neighborhood defined on the 3D square * grid with integer coordinates. */ - typedef neighb_<dpoint3d> neighb3d; + typedef neighb<window3d> neighb3d; /*! \brief 6-connectivity neighborhood on the 3D grid. @@ -102,19 +103,23 @@ */ const neighb3d& c26(); + + # ifndef MLN_INCLUDE_ONLY inline const neighb3d& c6() { - static bool flower = true; static neighb3d it; - if (flower) + if (it.size() == 0) { - it.insert(dpoint3d(+1, 0, 0)); - it.insert(dpoint3d(0, +1, 0)); - it.insert(dpoint3d(0, 0, +1)); - flower = false; + window3d& win = it.hook_win_(); + win + .insert(1, 0, 0) + .insert(0, 1, 0) + .insert(0, 0, 1); + win + .insert(geom::sym(win)); } return it; } @@ -122,22 +127,20 @@ inline const neighb3d& c18() { - static bool flower = true; static neighb3d it; - if (flower) + if (it.size() == 0) { - it.insert(dpoint3d(+1, 0, 0)); - it.insert(dpoint3d(0, +1, 0)); - it.insert(dpoint3d(0, 0, +1)); - - it.insert(dpoint3d(+1, 0, +1)); - it.insert(dpoint3d(+1, 0, -1)); - it.insert(dpoint3d(0, +1, +1)); - it.insert(dpoint3d(0, +1, -1)); - it.insert(dpoint3d(+1, +1, 0)); - it.insert(dpoint3d(+1, -1, 0)); - - flower = false; + window3d& win = it.hook_win_(); + win + .insert(1, 0, 1) + .insert(1, 0, -1) + .insert(0, 1, 1) + .insert(0, 1, -1) + .insert(1, 1, 0) + .insert(1, -1, 0); + win + .insert(geom::sym(win)) + .insert(c6().win()); } return it; } @@ -145,26 +148,18 @@ inline const neighb3d& c26() { - static bool flower = true; static neighb3d it; - if (flower) + if (it.size() == 0) { - it.insert(dpoint3d(+1, 0, 0)); - it.insert(dpoint3d(0, +1, 0)); - it.insert(dpoint3d(0, 0, +1)); - - it.insert(dpoint3d(+1, 0, +1)); - it.insert(dpoint3d(+1, 0, -1)); - it.insert(dpoint3d(0, +1, +1)); - it.insert(dpoint3d(0, +1, -1)); - it.insert(dpoint3d(+1, +1, 0)); - it.insert(dpoint3d(+1, -1, 0)); - - it.insert(dpoint3d(+1, +1, +1)); - it.insert(dpoint3d(+1, +1, -1)); - it.insert(dpoint3d(+1, -1, +1)); - it.insert(dpoint3d(+1, -1, -1)); - flower = false; + window3d& win = it.hook_win_(); + win + .insert(1, 1, 1) + .insert(1, 1, -1) + .insert(1, -1, 1) + .insert(1, -1, -1); + win + .insert(geom::sym(win)) + .insert(c18().win()); } return it; } Index: mln/core/alias/window1d.hh --- mln/core/alias/window1d.hh (revision 2374) +++ mln/core/alias/window1d.hh (working copy) @@ -47,13 +47,9 @@ namespace convert { - namespace impl - { template <unsigned M> - void from_to_(bool const (&values)[M], window1d& win); - - } // end of namespace mln::convert::impl + void from_to(const bool (&values)[M], window1d& win); } // end of namespace mln::convert @@ -63,25 +59,20 @@ namespace convert { - namespace impl - { template <unsigned M> void - from_to_(bool const (&values)[M], window1d& win) + from_to(bool const (&values)[M], window1d& win) { mlc_bool(M % 2 == 1)::check(); - mln_precondition(win.is_empty()); // FIXME: or just .clear() it? - + win.clear(); const int h = int(M) / 2; unsigned i = 0; for (int ind = - h; ind <= h; ++ind) if (values[i++]) - win.insert(dpoint1d(ind)); + win.insert(ind); } - } // end of namespace mln::convert::impl - } // end of namespace mln::convert # endif // ! MLN_INCLUDE_ONLY Index: mln/core/alias/window2d.hh --- mln/core/alias/window2d.hh (revision 2374) +++ mln/core/alias/window2d.hh (working copy) @@ -31,6 +31,8 @@ /// \file mln/core/alias/window2d.hh /// \brief Definition of the mln::window2d alias and of a construction /// routine. +/// +/// \todo c8p etc. # include <mln/core/window.hh> # include <mln/core/alias/dpoint2d.hh> @@ -58,16 +60,12 @@ namespace convert { - namespace impl - { template <unsigned S> - void from_to_(bool const (&values)[S], window2d& win); + void from_to(const bool (&values)[S], window2d& win); template <unsigned R, unsigned C> - void from_to_(bool const (&values)[R][C], window2d& win); - - } // end of namespace mln::convert::impl + void from_to(const bool (&values)[R][C], window2d& win); } // end of namespace mln::convert @@ -78,16 +76,15 @@ inline const window2d& win_c4p() { - static bool initialized_p = false; static window2d it; - if (!initialized_p) + if (it.size() == 0) { - it.insert(dpoint2d( 0, -1)); - it.insert(dpoint2d(-1, 0)); - it.insert(dpoint2d( 0, 0)); - it.insert(dpoint2d(+1, 0)); - it.insert(dpoint2d( 0, +1)); - initialized_p = true; + it + .insert( 0, -1) + .insert(-1, 0) + .insert( 0, 0) + .insert(+1, 0) + .insert( 0, +1); } return it; } @@ -95,16 +92,14 @@ namespace convert { - namespace impl - { template <unsigned S> void - from_to_(bool const (&values)[S], window2d& win) + from_to(const 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(); + win.clear(); unsigned i = 0; for (int row = - h; row <= h; ++row) for (int col = - h; col <= h; ++col) @@ -114,12 +109,11 @@ template <unsigned R, unsigned C> void - from_to_(bool const (&values)[R][C], window2d& win) + from_to(const bool (&values)[R][C], window2d& win) { mlc_bool(R % 2 == 1)::check(); mlc_bool(C % 2 == 1)::check(); - mln_precondition(win.is_empty()); // FIXME: or just .clear() it? - + win.clear(); const int drow = int(R) / 2, dcol = int(C) / 2; for (int row = - drow; row <= drow; ++row) for (int col = - dcol; col <= dcol; ++col) @@ -127,8 +121,6 @@ win.insert(row, col); } - } // end of namespace mln::convert::impl - } // end of namespace mln::convert # endif // ! MLN_INCLUDE_ONLY Index: mln/core/alias/window3d.hh --- mln/core/alias/window3d.hh (revision 2374) +++ mln/core/alias/window3d.hh (working copy) @@ -48,13 +48,9 @@ namespace convert { - namespace impl - { template <unsigned M> - void from_to_(bool const (&values)[M], window3d& win); - - } // end of namespace mln::convert::impl + void from_to(bool const (&values)[M], window3d& win); } // end of namespace mln::convert @@ -64,27 +60,22 @@ namespace convert { - namespace impl - { template <unsigned M> void - from_to_(bool const (&values)[M], window3d& win) + from_to(bool const (&values)[M], window3d& win) { - mln_precondition(win.is_empty()); // FIXME: or just .clear() it? const int h = unsigned(std::pow(float(M), float(1. / 3.))) / 2; mln_precondition((2 * h + 1) * (2 * h + 1) * (2 * h + 1) == M); - + win.clear(); unsigned i = 0; for (int sli = - h; sli <= h; ++sli) for (int row = - h; row <= h; ++row) for (int col = - h; col <= h; ++col) if (values[i++]) - win.insert(dpoint3d(sli, row, col)); + win.insert(sli, row, col); } - } // end of namespace mln::convert::impl - } // end of namespace mln::convert # endif // ! MLN_INCLUDE_ONLY Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 2374) +++ mln/core/neighb.hh (working copy) @@ -31,9 +31,17 @@ /*! \file mln/core/neighb.hh * * \brief Definition of a window-to-neighborhood adapter. + * + * \todo Introduce properties so that we can deal properly with + * optional methods. + * + * \todo See if the impl of from_to is fine. What about removing the + * origin? etc. */ +# include <mln/core/concept/window.hh> # include <mln/core/internal/neighborhood_base.hh> +# include <mln/core/internal/site_relative_iterator_base.hh> # include <mln/convert/from_to.hh> @@ -53,8 +61,8 @@ { public: + /// Window associated type. typedef W window; - const W& to_window() const { return win_; } /// Forward site iterator associated type. typedef neighb_fwd_niter<W> fwd_niter; @@ -78,6 +86,21 @@ /// Change the corresponding window. void change_window(const W& new_win); + + // Optional methods... + + /// Give the neighborhood size, i.e., the number of elements it + /// contains. + unsigned size() const; + + /// Give the maximum coordinate gap between the neighborhood + /// center and a neighboring point. + unsigned delta() const; + + + /// \internal Hook to the window. + W& hook_win_(); + private: W win_; }; @@ -86,18 +109,14 @@ namespace convert { - namespace impl - { template <typename W> void - from_to_(const mln::neighb<W>& from, W& to); + from_to(const mln::neighb<W>& from, W& to); template <typename W> void - from_to_(const W& from, mln::neighb<W>& to); - - } // end of namespace convert::impl + from_to(const W& from, mln::neighb<W>& to); } // end of namespace convert @@ -211,30 +230,50 @@ win_ = new_win; } + template <typename W> + inline + unsigned + neighb<W>::size() const + { + return win_.size(); + } + + template <typename W> + inline + unsigned + neighb<W>::delta() const + { + return win_.delta(); + } + + template <typename W> + inline + W& + neighb<W>::hook_win_() + { + return win_; + } + - // convert::impl::from_to_ + // convert::from_to namespace convert { - namespace impl - { template <typename W> void - from_to_(const mln::neighb<W>& from, W& to) + from_to(const mln::neighb<W>& from, W& to) { to = from.win(); } template <typename W> void - from_to_(const W& from, mln::neighb<W>& to) + from_to(const W& from, mln::neighb<W>& to) { to.change_window(from); } - } // end of namespace convert::impl - } // end of namespace convert @@ -254,7 +293,7 @@ this->change_target(nbh); this->center_at(c); i_.center_at(c); // Always before change_target for this kind of iter. - i_.change_target(nbh.to_window()); + i_.change_target(nbh.win()); } template <typename W> @@ -314,7 +353,7 @@ this->change_target(nbh); this->center_at(c); i_.center_at(c); // Always before change_target for this kind of iter. - i_.change_target(nbh.to_window()); + i_.change_target(nbh.win()); } template <typename W> Index: mln/core/concept/neighborhood.hh --- mln/core/concept/neighborhood.hh (revision 2374) +++ mln/core/concept/neighborhood.hh (working copy) @@ -65,7 +65,10 @@ typedef bkd_niter; typedef window; - window to_window() const; + either + const window& win() const; + or + window win() const; */ protected: @@ -85,7 +88,7 @@ typedef mln_bkd_niter(E) bkd_niter; typedef mln_window(E) window; - bool m = (& E::to_window) == (& E::to_window); + bool m = (& E::win) == (& E::win); m = 0; // const window& (E::*m)() const = & E::to_window; // m = 0; Index: mln/metal/abort.hh --- mln/metal/abort.hh (revision 2374) +++ mln/metal/abort.hh (working copy) @@ -35,6 +35,8 @@ # include <mln/metal/bool.hh> +# define mlc_abort(A_TYPE) mln::metal::abort_< A_TYPE > + namespace mln { Index: mln/convert/to.hh --- mln/convert/to.hh (revision 2374) +++ mln/convert/to.hh (working copy) @@ -68,7 +68,7 @@ trace::entering("convert::to"); T tmp; - impl::from_to_(from, tmp); + from_to(from, tmp); trace::exiting("convert::to"); return tmp; Index: mln/convert/from_to.hh --- mln/convert/from_to.hh (revision 2374) +++ mln/convert/from_to.hh (working copy) @@ -32,9 +32,11 @@ * * \brief General conversion procedure between two objects. * - * \todo Prefer a static check that fails in the "unknown" case. - * * \todo Use 'round' instead of static_cast in vec->Gpoint. + * + * \todo Test the effectiveness of guards. + * \todo Add fwd decls. + * \todo Dispatch code in appropriate files. */ # include <mln/core/concept/object.hh> @@ -46,6 +48,7 @@ # include <mln/algebra/vec.hh> # include <mln/metal/is.hh> +# include <mln/metal/abort.hh> @@ -56,49 +59,63 @@ { - /// Conversion of an object \p from towards an object \p to. + /// Guards. + template <typename F, typename T> + void + from_to(const F& from, Object<T>& to); + template <typename F, typename T> - inline void - from_to(F& from, Object<T>& to); // See below an explanation of this signature. + from_to(const Object<F>& from, Object<T>& to); + + template <typename F, typename T> + void + from_to(const Object<F>& from, T& to); + /// end of Guards. template <typename T> - inline void from_to(const float& from, Object<T>& to); template <typename T> - inline void 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 -# ifndef MLN_INCLUDE_ONLY + /// Guards. + template <typename F, typename T> + void + from_to(const F&, Object<T>&) + { + mlc_abort(F)::check(); + } - namespace impl + template <typename F, typename T> + void + from_to(const Object<F>&, Object<T>&) { + mlc_abort(F)::check(); + } - // Default (F -> Object) means "unknown conversion". template <typename F, typename T> void - from_to_(const F& from, Object<T>& to); + from_to(const Object<F>&, T&) + { + mlc_abort(F)::check(); + } + /// end of Guards. // Image -> Site_Set. template <typename I, typename S> inline void - from_to_(const Image<I>& from, Site_Set<S>& to) + from_to(const Image<I>& from, Site_Set<S>& to) { mlc_is(mln_trait_site_set_contents(S), mln::trait::site_set::contents::dynamic)::check(); @@ -110,7 +127,7 @@ template <unsigned n, typename T, typename P> inline void - from_to_(const algebra::vec<n,T>& from, Gpoint<P>& to_) + from_to(const algebra::vec<n,T>& from, Gpoint<P>& to_) { mlc_bool(P::dim == n)::check(); P& to = exact(to_); @@ -122,7 +139,7 @@ template <typename T, unsigned m> inline void - from_to_(const algebra::vec<3,T>& from, value::rgb<m>& to_) + from_to(const algebra::vec<3,T>& from, value::rgb<m>& to_) { value::rgb<m>& to = exact(to_); algebra::vec<3, unsigned> tmp; @@ -132,34 +149,16 @@ to = value::rgb<m>(tmp); } - + // Value -> Value template <typename F, typename T> inline void - from_to_(const Value<F>& from, Value<T>& to) + from_to(const Value<F>& from, Value<T>& to) { mln::convert::impl::from_value_to_value(from, to); } - } // end of namespace mln::convert::impl - - - - // Facades. - - - template <typename F, typename T> - inline - void - from_to(F& from, Object<T>& to) - { - trace::entering("convert::from_to"); - mlc_equal(F, mln_exact(F))::check(); - impl::from_to_(from, exact(to)); - trace::exiting("convert::from_to"); - } - - + // float -> Object template <typename T> inline void @@ -169,7 +168,7 @@ exact(to) = from; } - + // int -> Object template <typename T> inline void