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