https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add initialization for extension morphers.
* mln/core/image/extension_fun.hh,
* mln/core/image/extension_ima.hh,
* mln/core/image/extension_val.hh,
(init): Rename this method as...
(init_): ...this.
(init_): New procedure overloads.
* doc/tutorial/examples/image_if.cc: Augment.
* mln/trait/ch_value.hh: New overload.
* mln/core/image/extension_fun.hh (FIXME): Fix.
Augment doc.
(extension): New method.
* mln/core/image/extension_ima.hh (skeleton): Fix.
Now the extension is a particular tag so we cannot mix up
image and extension.
* mln/core/image/extension_val.hh: .
(extension_value, change_extension_value): Rename as...
(extension, change_extension): ...these.
* mln/core/internal/image_morpher.hh (FIXME): Fix.
Add static check.
* mln/core/concept/image.hh: Layout.
(check_init): New material.
(Image): Check the presence of the init_ method.
* mln/tag/init.hh: Layout.
(extension_t, extension): New tag type and object.
* mln/tag/skeleton.hh (ext_): New tag.
* mln/fun/p2b/has.hh: New check.
doc/tutorial/examples/image_if.cc | 13 ++++++++-
mln/core/concept/image.hh | 34 +++++++++++++++++++++++
mln/core/image/extension_fun.hh | 53 +++++++++++++++++++++++++++++++++----
mln/core/image/extension_ima.hh | 46 ++++++++++++++++++++++++++++----
mln/core/image/extension_val.hh | 43 ++++++++++++++++++++++++------
mln/core/internal/image_morpher.hh | 4 +-
mln/fun/p2b/has.hh | 5 ++-
mln/tag/init.hh | 4 ++
mln/tag/skeleton.hh | 9 +++---
mln/trait/ch_value.hh | 7 ++++
10 files changed, 190 insertions(+), 28 deletions(-)
Index: doc/tutorial/examples/image_if.cc
--- doc/tutorial/examples/image_if.cc (revision 2196)
+++ doc/tutorial/examples/image_if.cc (working copy)
@@ -51,6 +51,13 @@
}
}
+template <typename I>
+void algo(const I& input)
+{
+ using namespace mln;
+ mln_ch_value(I, float) output;
+ initialize(output, input);
+}
@@ -58,6 +65,8 @@
{
using namespace mln;
+ trace::quiet = false;
+
typedef image2d<unsigned> I;
I ima(3, 3, 1);
// FIXME: border::fill(ima, 0);
@@ -75,8 +84,10 @@
ch_target(mln_fwd_piter_(S)(), ima_.domain());
// mln_VAR(ima_e, extend(ima_, pw::value(ima)));
- // mln_VAR(ima_e, extend(ima_, 0));
+ // mln_VAR(ima_e, extend(ima_, 8));
mln_VAR(ima_e, extend(ima_, ima));
debug::println(ima_e);
browse(ima_e, c4());
+
+ algo(ima_e);
}
Index: mln/trait/ch_value.hh
--- mln/trait/ch_value.hh (revision 2196)
+++ mln/trait/ch_value.hh (working copy)
@@ -105,6 +105,13 @@
typedef M< mln_ch_value(I1, V), mln_ch_value(I2, V) > ret;
};
+ template < template <class, class> class M, typename I, typename E,
+ typename V >
+ struct ch_value_< M< tag::image_<I>, tag::ext_<E> >, V
>
+ {
+ typedef M< mln_ch_value(I, V), E > ret;
+ };
+
// For mln::value::stack_image<n,I>.
template < template <unsigned, class> class M, unsigned n, typename I,
typename V >
Index: mln/core/image/extension_fun.hh
--- mln/core/image/extension_fun.hh (revision 2196)
+++ mln/core/image/extension_fun.hh (working copy)
@@ -89,6 +89,7 @@
template <typename I, typename F>
class extension_fun :
+
public internal::image_identity< I, mln_pset(I), extension_fun<I, F> >,
private mlc_converts_to(mln_result(F), mln_value(I))::check_t
{
@@ -96,7 +97,6 @@
/// Skeleton.
typedef extension_fun< tag::image_<I>, tag::function_<F> >
skeleton;
- // FIXME: OK when ch_value?
/// Return type of read-only access.
@@ -111,10 +111,11 @@
/// Deferred initialization from an image \p ima and a function \p
/// fun.
- void init(I& ima, const F& fun);
+ void init_(I& ima, const F& fun);
- /// Test if \p p is valid. It returns always true.
+ /// Test if \p p is valid. It returns always true, assuming that
+ /// the function is valid for any \p p.
// Tech note: the 'template' allows for multiple input.
template <typename P>
bool has(const P& p) const;
@@ -125,9 +126,22 @@
/// Read-write access to the image value located at site \p p.
mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
+
+
+ /// Give the extension function.
+ const F& extension() const;
};
+ // init_
+
+ template <typename I, typename F, typename J>
+ void init_(tag::image_t, extension_fun<I,F>& target, const J& model);
+
+ template <typename F, typename I>
+ void init_(tag::extension_t, F& target, const extension_fun<I,F>&
model);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -147,6 +161,7 @@
} // end of namespace mln::internal
+
// extension_fun<I, F>
template <typename I, typename F>
@@ -159,13 +174,13 @@
inline
extension_fun<I, F>::extension_fun(I& ima, const F& fun)
{
- init(ima, fun);
+ init_(ima, fun);
}
template <typename I, typename F>
inline
void
- extension_fun<I, F>::init(I& ima, const F& fun)
+ extension_fun<I, F>::init_(I& ima, const F& fun)
{
this->data_ = new internal::data< extension_fun<I, F> >(ima, fun);
}
@@ -213,6 +228,34 @@
}
}
+ template <typename I, typename F>
+ inline
+ const F&
+ extension_fun<I, F>::extension() const
+ {
+ mln_precondition(this->has_data());
+ return this->data_->fun_;
+ }
+
+
+ // init_
+
+ template <typename I, typename F, typename J>
+ void init_(tag::image_t, extension_fun<I,F>& target, const J& model)
+ {
+ I ima;
+ init_(tag::image, ima, model);
+ F fun;
+ init_(tag::extension, fun, model);
+ target.init_(ima, fun);
+ }
+
+ template <typename F, typename I>
+ void init_(tag::extension_t, F& target, const extension_fun<I,F>& model)
+ {
+ target = model.extension();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/image/extension_ima.hh
--- mln/core/image/extension_ima.hh (revision 2196)
+++ mln/core/image/extension_ima.hh (working copy)
@@ -96,8 +96,7 @@
public:
/// Skeleton.
- typedef extension_ima< tag::image_<I>, tag::image_<J> > skeleton;
- // FIXME: OK when ch_value?
+ typedef extension_ima< tag::image_<I>, tag::ext_<J> > skeleton;
/// Return type of read-only access.
@@ -112,7 +111,7 @@
/// Deferred initialization from an image \p ima and a function \p
/// ext.
- void init(I& ima, J& ext);
+ void init_(I& ima, J& ext);
/// Test if \p p is valid.
@@ -137,6 +136,18 @@
};
+ // init_
+
+ template <typename I, typename J, typename M>
+ void init_(tag::image_t, extension_ima<I,J>& target, const M& model);
+
+ template <typename J, typename I>
+ void init_(tag::extension_t, J& target, const extension_ima<I,J>&
model);
+
+ template <typename J, typename I>
+ void init_(tag::extension_t, J& target, const extension_ima<I,const J>&
model);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -168,13 +179,13 @@
inline
extension_ima<I, J>::extension_ima(I& ima, J& ext)
{
- init(ima, ext);
+ init_(ima, ext);
}
template <typename I, typename J>
inline
void
- extension_ima<I, J>::init(I& ima, J& ext)
+ extension_ima<I, J>::init_(I& ima, J& ext)
{
this->data_ = new internal::data< extension_ima<I, J> >(ima, ext);
}
@@ -246,6 +257,31 @@
return this->data_->ext_;
}
+
+ // init_
+
+ template <typename I, typename J, typename M>
+ void init_(tag::image_t, extension_ima<I,J>& target, const M& model)
+ {
+ I ima;
+ init_(tag::image, ima, model);
+ J ext;
+ init_(tag::extension, ext, model);
+ target.init_(ima, ext);
+ }
+
+ template <typename J, typename I>
+ void init_(tag::extension_t, J& target, const extension_ima<I,J>& model)
+ {
+ target = model.extension();
+ }
+
+ template <typename J, typename I>
+ void init_(tag::extension_t, J& target, const extension_ima<I,const J>&
model)
+ {
+ target = model.extension();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/image/extension_val.hh
--- mln/core/image/extension_val.hh (revision 2196)
+++ mln/core/image/extension_val.hh (working copy)
@@ -94,7 +94,6 @@
/// Skeleton.
typedef extension_val< tag::image_<I> > skeleton;
- // FIXME: OK when ch_value?
/// Return type of read-only access.
@@ -109,7 +108,7 @@
/// Deferred initialization from an image \p ima and a value \p
/// val.
- void init(I& ima, const mln_value(I)& val);
+ void init_(I& ima, const mln_value(I)& val);
/// Test if \p p is valid. It returns always true.
@@ -126,13 +125,21 @@
/// Read-only access to the value of the extension domain.
- const mln_value(I)& extension_value() const;
+ const mln_value(I)& extension() const;
/// Change the value of the extension domain.
- void change_extension_value(const mln_value(I)& val);
+ void change_extension(const mln_value(I)& val);
};
+ // init_
+
+ template <typename I, typename J>
+ void init_(tag::image_t, extension_val<I>& target, const J& model);
+
+ template <typename V, typename I>
+ void init_(tag::extension_t, V& target, const extension_val<I>& model);
+
# ifndef MLN_INCLUDE_ONLY
@@ -164,13 +171,13 @@
inline
extension_val<I>::extension_val(I& ima, const mln_value(I)& val)
{
- init(ima, val);
+ init_(ima, val);
}
template <typename I>
inline
void
- extension_val<I>::init(I& ima, const mln_value(I)& val)
+ extension_val<I>::init_(I& ima, const mln_value(I)& val)
{
this->data_ = new internal::data< extension_val<I> >(ima, val);
}
@@ -218,7 +225,7 @@
template <typename I>
inline
const mln_value(I)&
- extension_val<I>::extension_value() const
+ extension_val<I>::extension() const
{
mln_precondition(this->has_data());
return this->data_->val_;
@@ -227,12 +234,32 @@
template <typename I>
inline
void
- extension_val<I>::change_extension_value(const mln_value(I)& val)
+ extension_val<I>::change_extension(const mln_value(I)& val)
{
mln_precondition(this->has_data());
this->data_->val_ = val;
}
+
+ // init_
+
+ template <typename I, typename J>
+ void init_(tag::image_t, extension_val<I>& target, const J& model)
+ {
+ I ima;
+ init_(tag::image, ima, model);
+ mln_value(I) val;
+ init_(tag::extension, val, model);
+ target.init_(ima, val);
+ }
+
+ template <typename V, typename I>
+ void init_(tag::extension_t, V& target, const extension_val<I>& model)
+ {
+ mlc_converts_to(mln_value(I), V)::check();
+ target = model.extension();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/internal/image_morpher.hh
--- mln/core/internal/image_morpher.hh (revision 2196)
+++ mln/core/internal/image_morpher.hh (working copy)
@@ -167,8 +167,8 @@
inline
void init_(Subject s, T& target, const Image<J>& model_)
{
- // FIXME: Precondition.
- // FIXME: Properly check that J is an internal::image_morpher.
+ mlc_is(mln_trait_image_category(J),
+ trait::image::category::morpher)::check();
const J& model = exact(model_);
init_(s, target, * model.delegatee_());
}
Index: mln/core/concept/image.hh
--- mln/core/concept/image.hh (revision 2196)
+++ mln/core/concept/image.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
@@ -114,6 +114,7 @@
namespace internal
{
+
template <typename values_browsing_trait, typename E>
struct image_values_interface_check
{
@@ -132,8 +133,35 @@
m = 0;
}
};
+
+
+ // check_init
+
+ template < typename E,
+ typename A >
+ int check_init(void (E::*)(A))
+ {
+ return 0;
+ }
+
+ template < typename E,
+ typename A1, typename A2 >
+ int check_init(void (E::*)(A1, A2))
+ {
+ return 0;
}
+ template < typename E,
+ typename A1, typename A2, typename A3 >
+ int check_init(void (E::*)(A1, A2, A3))
+ {
+ return 0;
+ }
+
+ } // end of namespace mln::internal
+
+
+
template <typename E>
inline
Image<E>::Image()
@@ -187,6 +215,10 @@
typedef typename E::skeleton skeleton;
+ // Check E::init_ presence. Since its signature varies from an
+ // image type to another, that is the only thing we can ensure.
+ internal::check_init(& E::init_);
+
/// Optional interface:
internal::image_values_interface_check<mln_trait_image_value_browsing(E),
E>::run();
Index: mln/tag/init.hh
--- mln/tag/init.hh (revision 2196)
+++ mln/tag/init.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
@@ -44,6 +44,7 @@
struct domain_t {};
struct bbox_t {};
struct border_t {};
+ struct extension_t {};
struct function_t {};
// FIXME: Make these proper globals (issue #43).
@@ -51,6 +52,7 @@
static const domain_t domain = domain_t();
static const bbox_t bbox = bbox_t();
static const border_t border = border_t();
+ static const extension_t extension = extension_t();
static const function_t function = function_t();
} // end of namespace mln::tag
Index: mln/tag/skeleton.hh
--- mln/tag/skeleton.hh (revision 2196)
+++ mln/tag/skeleton.hh (working copy)
@@ -42,13 +42,14 @@
{
// With param.
- template <typename I> struct image_ { typedef I param; };
- template <typename V> struct value_ { typedef V param; };
- template <typename P> struct psite_ { typedef P param; };
- template <typename S> struct pset_ { typedef S param; };
template <typename D> struct data_ { typedef D param; };
+ template <typename E> struct ext_ { typedef E param; };
template <typename F> struct function_ { typedef F param; };
+ template <typename I> struct image_ { typedef I param; };
template <typename N> struct neighb_ { typedef N param; };
+ template <typename P> struct psite_ { typedef P param; };
+ template <typename S> struct pset_ { typedef S param; };
+ template <typename V> struct value_ { typedef V param; };
// With value.
template <unsigned u> struct unsigned_ { enum { value = u }; };
Index: mln/fun/p2b/has.hh
--- mln/fun/p2b/has.hh (revision 2196)
+++ mln/fun/p2b/has.hh (working copy)
@@ -50,7 +50,10 @@
// FIXME: Doc!
template <typename I>
- struct has : public Function_p2b< has<I> >
+ struct has
+
+ : public Function_p2b< has<I> >,
+ private mlc_is_a(I, Image)::check_t
{
/// Result associated type.
typedef bool result;