cleanup-2008 2197: Add initialization for extension morphers.

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