* mln/world/k2/convert_on_access.hh: Rename as...
* mln/world/k2/converters.hh: ... this.
* mln/world/k2/fill_non_primary_from_primary_faces.hh,
* mln/world/kn/immerse.hh: Take a converter functor as argument.
---
milena/ChangeLog | 10 +
milena/mln/world/k2/convert_on_access.hh | 126 -----------
milena/mln/world/k2/converters.hh | 232 ++++++++++++++++++++
.../k2/fill_non_primary_from_primary_faces.hh | 73 ++++---
milena/mln/world/kn/immerse.hh | 16 +-
5 files changed, 290 insertions(+), 167 deletions(-)
delete mode 100644 milena/mln/world/k2/convert_on_access.hh
create mode 100644 milena/mln/world/k2/converters.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index bf4c572..fd1f830 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,15 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Let the user specify conversion functions in K2 immersion.
+
+ * mln/world/k2/convert_on_access.hh: Rename as...
+ * mln/world/k2/converters.hh: ... this.
+
+ * mln/world/k2/fill_non_primary_from_primary_faces.hh,
+ * mln/world/kn/immerse.hh: Take a converter functor as argument.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* mln/core/routine/ops.hh: Update comments.
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/milena/mln/world/k2/convert_on_access.hh
b/milena/mln/world/k2/convert_on_access.hh
deleted file mode 100644
index 4c9ab20..0000000
--- a/milena/mln/world/k2/convert_on_access.hh
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-/// \file
-///
-/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
-
-#ifndef MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
-# define MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
-
-# include <mln/core/alias/point2d.hh>
-# include <mln/world/k2/is_non_primary_face_vertical.hh>
-# include <mln/world/k2/is_non_primary_face_horizontal.hh>
-# include <mln/world/k2/convert_on_access.hh>
-
-# include <mln/value/int_u8.hh>
-# include <mln/value/intsub.hh>
-
-namespace mln
-{
-
- namespace world
- {
-
- namespace k2
- {
-
- using namespace mln::value;
-
- template <unsigned n>
- void convert_on_access(const intsub<n>& from, intsub<n/2>&
to);
-
- template <unsigned n>
- void convert_on_access(const int_u8& from, intsub<n>& to);
-
- template <unsigned n>
- void convert_on_access(const int_u8& from, interval<intsub<n>
>& to);
-
- template <unsigned n>
- void convert_on_access(const interval<intsub<n> >& from, int&
to);
-
- template <unsigned n>
- void convert_on_access(const interval<intsub<n> >& from,
value::int_u8& to);
-
- template <typename T, typename U>
- void convert_on_access(const T& from, U& to);
-
-
-#ifndef MLN_INCLUDE_ONLY
-
- template <unsigned n>
- void convert_on_access(const intsub<n/2>& from, intsub<n>& to)
- {
- to = from.to_int();
- }
-
- template <unsigned n>
- void convert_on_access(const int_u8& from, intsub<n>& to)
- {
- to = from.to_equiv();
- }
-
- template <unsigned n>
- void convert_on_access(const int_u8& from, interval<intsub<n>
>& to)
- {
- to = intsub<n>(from.to_interop());
- }
-
- template <unsigned n>
- void convert_on_access(const interval<intsub<n> >& from, int&
to)
- {
- mln_precondition(from.is_degenerated());
- to = from.first();
- }
-
- template <unsigned n>
- void convert_on_access(const interval<intsub<n> >& from,
value::int_u8& to)
- {
- mln_precondition(from.is_degenerated());
- to = from.first();
- }
-
- template <unsigned n>
- void convert_on_access(const interval<intsub<n> >& from,
intsub<n/2>& to)
- {
- mln_precondition(from.is_degenerated());
- to = from.first().to_interop();
- }
-
- template <typename T, typename U>
- void convert_on_access(const T& from, U& to)
- {
- to = static_cast<U>(from);
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace mln::world::k2
-
- } // end of namespace mln::world
-
-} // end of namespace mln
-
-#endif // ! MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
diff --git a/milena/mln/world/k2/converters.hh b/milena/mln/world/k2/converters.hh
new file mode 100644
index 0000000..de76087
--- /dev/null
+++ b/milena/mln/world/k2/converters.hh
@@ -0,0 +1,232 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_CONVERTERS_HH
+# define MLN_WORLD_K2_CONVERTERS_HH
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/intsub.hh>
+# include <mln/value/interval.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ using namespace mln::value;
+
+ template <unsigned n>
+ struct int_sub_n_to_intsub_n_2
+ {
+ intsub<n/2> operator()(const intsub<n>& from) const;
+ intsub<n> operator()(const intsub<n/2>& from) const;
+ };
+
+ template <unsigned n>
+ struct int_sub_n_to_intsub_2n
+ {
+ intsub<2*n> operator()(const intsub<n>& from) const;
+ intsub<n> operator()(const intsub<2*n>& from) const;
+ };
+
+ template <unsigned n>
+ struct int_u8_to_intsub_n
+ {
+ intsub<n> operator()(const value::int_u8& from) const;
+ value::int_u8 operator()(const intsub<n>& from) const;
+ };
+
+ template <unsigned n>
+ struct int_u8_to_interval_intsub_n
+ {
+ interval<intsub<n> > operator()(const value::int_u8& from) const;
+ value::int_u8 operator()(const interval<intsub<n> >& from) const;
+ };
+
+ template <unsigned n>
+ struct interval_intsub_n_to_int
+ {
+ int operator()(const interval<intsub<n> >& from) const;
+ interval<intsub<n> > operator()(const int& from) const;
+ };
+
+ template <unsigned n>
+ struct interval_intsub_n_to_int_u8
+ {
+ value::int_u8 operator()(const interval<intsub<n> >& from) const;
+ interval<intsub<n> > operator()(const value::int_u8& from) const;
+ };
+
+ template <unsigned n>
+ struct interval_intsub_n_to_intsub_n_2
+ {
+ intsub<n/2> operator()(const interval<intsub<n> >& from) const;
+ interval<intsub<n> > operator()(const intsub<n/2>& from) const;
+ };
+
+ template <typename T1, typename T2>
+ struct generic_converter
+ {
+ T2 operator()(const T1& from) const;
+ T1 operator()(const T2& from) const;
+ };
+
+
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n>
+ intsub<n/2>
+ int_sub_n_to_intsub_n_2<n>::operator()(const intsub<n>& from)
const
+ {
+ return intsub<n/2>(from);
+ }
+
+ template <unsigned n>
+ intsub<n>
+ int_sub_n_to_intsub_n_2<n>::operator()(const intsub<n/2>& from)
const
+ {
+ return intsub<n>(from);
+ }
+
+
+ template <unsigned n>
+ intsub<2*n>
+ int_sub_n_to_intsub_2n<n>::operator()(const intsub<n>& from) const
+ {
+ return static_cast<intsub<2*n> >(from.to_int());
+ }
+
+ template <unsigned n>
+ intsub<n>
+ int_sub_n_to_intsub_2n<n>::operator()(const intsub<2*n>& from)
const
+ {
+ return static_cast<intsub<n> >(from.to_int());
+ }
+
+ template <unsigned n>
+ intsub<n>
+ int_u8_to_intsub_n<n>::operator()(const int_u8& from) const
+ {
+ return from.to_equiv();
+ }
+
+ template <unsigned n>
+ value::int_u8
+ int_u8_to_intsub_n<n>::operator()(const intsub<n>& from) const
+ {
+ return from.to_interop();
+ }
+
+ template <unsigned n>
+ interval<intsub<n> >
+ int_u8_to_interval_intsub_n<n>::operator()(const int_u8& from) const
+ {
+ return intsub<n>(from.to_interop());
+ }
+
+ template <unsigned n>
+ value::int_u8
+ int_u8_to_interval_intsub_n<n>::operator()(const interval<intsub<n>
>& from) const
+ {
+ return from.first().to_interop();
+ }
+
+ template <unsigned n>
+ int
+ interval_intsub_n_to_int<n>::operator()(const interval<intsub<n>
>& from) const
+ {
+ mln_precondition(from.is_degenerated());
+ return from.first();
+ }
+
+ template <unsigned n>
+ interval<intsub<n> >
+ interval_intsub_n_to_int<n>::operator()(const int& from) const
+ {
+ return interval<intsub<n> >(from);
+ }
+
+ template <unsigned n>
+ value::int_u8
+ interval_intsub_n_to_int_u8<n>::operator()(const interval<intsub<n>
>& from) const
+ {
+ mln_precondition(from.is_degenerated());
+ return from.first().to_interop();
+ }
+
+ template <unsigned n>
+ interval<intsub<n> >
+ interval_intsub_n_to_int_u8<n>::operator()(const value::int_u8& from)
const
+ {
+ return intsub<n>(from.to_interop());
+ }
+
+ template <unsigned n>
+ intsub<n/2>
+ interval_intsub_n_to_intsub_n_2<n>::operator()(const
interval<intsub<n> >& from) const
+ {
+ mln_precondition(from.is_degenerated());
+ return from.first().to_interop();
+ }
+
+ template <unsigned n>
+ interval<intsub<n> >
+ interval_intsub_n_to_intsub_n_2<n>::operator()(const intsub<n/2>&
from) const
+ {
+ return interval<intsub<n> >(from);
+ }
+
+ template <typename T1, typename T2>
+ T2
+ generic_converter<T1,T2>::operator()(const T1& from) const
+ {
+ return static_cast<T2>(from);
+ }
+
+ template <typename T1, typename T2>
+ T1
+ generic_converter<T1,T2>::operator()(const T2& from) const
+ {
+ return static_cast<T1>(from);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_CONVERTERS_HH
diff --git a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
index bc7509f..41d15cc 100644
--- a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
+++ b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
@@ -34,7 +34,7 @@
# include <mln/world/k2/is_non_primary_face_vertical.hh>
# include <mln/world/k2/is_non_primary_face_horizontal.hh>
# include <mln/world/k2/is_non_primary_face_cross.hh>
-# include <mln/world/k2/convert_on_access.hh>
+# include <mln/world/k2/converters.hh>
namespace mln
{
@@ -76,10 +76,16 @@ namespace mln
\endverbatim
*/
+ template <typename I, typename A, typename F>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ Accumulator<A>& accu_,
+ const F& converter);
/// \overload
- template <typename I, typename A>
+ template <typename I, typename A, typename F>
void fill_non_primary_from_primary_faces(Image<I>& inout,
- const Accumulator<A>& accu);
+ const Accumulator<A>& accu,
+ const F& converter);
+
# ifndef MLN_INCLUDE_ONLY
@@ -87,58 +93,56 @@ namespace mln
// Facade
- template <typename I, typename A>
+ template <typename I, typename A, typename F>
void fill_non_primary_from_primary_faces(Image<I>& inout_,
- F& functor_)
+ F& functor_,
+ const F& converter_)
{
trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
mln_precondition(exact(inout_).is_valid());
I& inout = exact(inout_);
- (void) accu_;
typedef typename A::argument V;
- A& accu = exact(accu_);
+ const F& converter = exact(converter_);
mln_piter(I) p(inout.domain());
for_all(p)
if (is_non_primary_face_vertical(p))
{
- accu.init();
V tmp1, tmp2;
- convert_on_access(inout(p + 2 * left), tmp1);
- convert_on_access(inout(p + 2 * right), tmp2);
- convert_on_access(f(tmp1, tmp2), inout(p));
+ tmp1 = converter(inout(p + 2 * left));
+ tmp2 = converter(inout(p + 2 * right));
+ converter(f(tmp1, tmp2), inout(p));
}
else if (is_non_primary_face_horizontal(p))
{
- accu.init();
V tmp1, tmp2;
- convert_on_access(inout(p + 2 * up), tmp1);
- convert_on_access(inout(p + 2 * down), tmp2);
- convert_on_access(f(tmp1, tmp2), inout(p));
+ tmp1 = converter(inout(p + 2 * up));
+ tmp2 = converter(inout(p + 2 * down));
+ converter(f(tmp1, tmp2), inout(p));
}
else if (is_non_primary_face_cross(p))
{
- accu.init();
V tmp1, tmp2, tmp3, tmp4;
- convert_on_access(inout(p + 2 * up_left), tmp1);
- convert_on_access(inout(p + 2 * up_right), tmp2);
- convert_on_access(inout(p + 2 * down_left), tmp3);
- convert_on_access(inout(p + 2 * down_right), tmp4);
- convert_on_access(f(tmp1, tmp2, tmp3, tmp4), inout(p));
+ tmp1 = converter(inout(p + 2 * up_left));
+ tmp2 = converter(inout(p + 2 * up_right));
+ tmp3 = converter(inout(p + 2 * down_left));
+ tmp4 = converter(inout(p + 2 * down_right));
+ converter(f(tmp1, tmp2, tmp3, tmp4), inout(p));
}
trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
}
- template <typename I, typename A>
+ template <typename I, typename A, typename F>
void fill_non_primary_from_primary_faces(Image<I>& inout_,
- Accumulator<A>& accu_)
+ Accumulator<A>& accu_,
+ const F& converter_)
{
trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
@@ -148,6 +152,7 @@ namespace mln
typedef typename A::argument V;
A& accu = exact(accu_);
+ const F& converter = exact(converter_);
mln_piter(I) p(inout.domain());
for_all(p)
@@ -156,45 +161,45 @@ namespace mln
accu.init();
V tmp;
- convert_on_access(inout(p + 2 * left), tmp);
+ tmp = converter(inout(p + 2 * left));
accu.take(tmp);
- convert_on_access(inout(p + 2 * right), tmp);
+ tmp = converter(inout(p + 2 * right));
accu.take(tmp);
- convert_on_access(accu.to_result(), inout(p));
+ inout(p) = converter(accu.to_result());
}
else if (is_non_primary_face_horizontal(p))
{
accu.init();
V tmp;
- convert_on_access(inout(p + 2 * up), tmp);
+ tmp = converter(inout(p + 2 * up));
accu.take(tmp);
- convert_on_access(inout(p + 2 * down), tmp);
+ tmp = converter(inout(p + 2 * down));
accu.take(tmp);
- convert_on_access(accu.to_result(), inout(p));
+ inout(p) = converter(accu.to_result());
}
else if (is_non_primary_face_cross(p))
{
accu.init();
V tmp;
- convert_on_access(inout(p + 2 * up_left), tmp);
+ tmp = converter(inout(p + 2 * up_left));
accu.take(tmp);
- convert_on_access(inout(p + 2 * up_right), tmp);
+ tmp = converter(inout(p + 2 * up_right));
accu.take(tmp);
- convert_on_access(inout(p + 2 * down_left), tmp);
+ tmp = converter(inout(p + 2 * down_left));
accu.take(tmp);
- convert_on_access(inout(p + 2 * down_right), tmp);
+ tmp = converter(inout(p + 2 * down_right));
accu.take(tmp);
- convert_on_access(accu.to_result(), inout(p));
+ inout(p) = converter(accu.to_result());
}
trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
diff --git a/milena/mln/world/kn/immerse.hh b/milena/mln/world/kn/immerse.hh
index 380b52f..835a4a1 100644
--- a/milena/mln/world/kn/immerse.hh
+++ b/milena/mln/world/kn/immerse.hh
@@ -40,7 +40,7 @@
# include <mln/world/k1/fill_0_from_1_faces.hh>
# include <mln/world/k1/fill_1_from_2_faces.hh>
-# include <mln/world/k2/convert_on_access.hh>
+# include <mln/world/k2/converters.hh>
namespace mln
{
@@ -73,9 +73,9 @@ namespace mln
\endverbatim
*/
- template <typename I, typename V>
+ template <typename I, typename V, typename F>
mln_ch_value(I, V)
- immerse(const Image<I>& ima_, const unsigned n, const V& new_type);
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type,
const F& converter_);
/// \overload
template <typename I>
@@ -116,13 +116,15 @@ namespace mln
// Facade
- template <typename I, typename V>
+ template <typename I, typename V, typename F>
mln_ch_value(I, V)
- immerse(const Image<I>& ima_, const unsigned n, const V& new_type)
+ immerse(const Image<I>& ima_, const unsigned n,
+ const V& new_type, const F& converter_)
{
trace::entering("mln::world::kn::immerse_with");
mln_precondition(exact(ima_).is_valid());
const I& ima = exact(ima_);
+ const F& converter = exact(converter_);
(void) new_type;
mln_ch_value(I,V)
@@ -133,7 +135,7 @@ namespace mln
for_all(p)
{
V tmp;
- k2::convert_on_access(ima(p), tmp);
+ tmp = converter(ima(p));
output(internal::immerse_point(p, n)) = tmp;
}
@@ -146,7 +148,7 @@ namespace mln
immerse(const Image<I>& ima, const unsigned n)
{
typedef mln_value(I) V;
- return immerse(ima, n, V());
+ return immerse(ima, n, V(), k2::generic_converter<V,V>());
}
--
1.7.2.5