1222: Make the trait solver rely on category inheritance.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make the trait solver rely on category inheritance. Fix image_if related-classes. * mln/core/image_if.hh, * mln/core/internal/image_if_base.hh, * mln/core/image_if_value.hh: Fix. * mln/labeling/estimate.hh: Update. * tests/image_if_value.cc: New. Make float01[_] work on float! * mln/value/float01_.hh, * mln/value/float01.hh: Fix. Enhance the trait solver mechanism; now it can rely on category inheritance :-) * mln/core/concept/image.hh, * mln/core/concept/function.hh, * mln/core/concept/meta_accumulator.hh, * mln/core/concept/value_set.hh, * mln/core/concept/weighted_window.hh, * mln/core/concept/browsing.hh, * mln/core/concept/dpoint.hh, * mln/core/concept/object.hh, * mln/core/concept/neighborhood.hh, * mln/core/concept/window.hh, * mln/core/concept/value.hh, * mln/core/concept/point_site.hh, * mln/core/concept/accumulator.hh: Specialize the category flag. (super): New in those specializations. Update. * tests/trait_op_uminus.cc: New. * tests/core_category.cc: New. * tests/trait_op_plus.cc: Augment. * mln/trait/op_plus.hh (set_binary_): Set category. * mln/trait/promote.hh: Likewise. * mln/trait/op_uminus.hh: Likewise. * mln/trait/solve.hh: Augment. * mln/trait/all.hh: Typo. * mln/core/category.hh (Unknown<void>): New. (Built_In): Move into... * mln/value/builtin.hh: ...this new file. * mln/core/ops.hh: Include builtin.hh. Misc. * mln/core/internal/exact.hh: Remove useless param. * mln/value/graylevel.hh: Fix. mln/core/category.hh | 25 +++--- mln/core/concept/accumulator.hh | 10 ++ mln/core/concept/browsing.hh | 11 ++ mln/core/concept/dpoint.hh | 10 ++ mln/core/concept/function.hh | 10 ++ mln/core/concept/image.hh | 10 ++ mln/core/concept/meta_accumulator.hh | 10 ++ mln/core/concept/neighborhood.hh | 11 ++ mln/core/concept/object.hh | 12 ++ mln/core/concept/point_site.hh | 13 ++- mln/core/concept/value.hh | 12 ++ mln/core/concept/value_set.hh | 13 ++- mln/core/concept/weighted_window.hh | 11 ++ mln/core/concept/window.hh | 10 ++ mln/core/image_if.hh | 77 ++++++++++++++++++ mln/core/image_if_value.hh | 139 +++++++++++++++++++++++++++------- mln/core/internal/exact.hh | 11 +- mln/core/internal/image_if_base.hh | 135 ++++++++++++--------------------- mln/core/ops.hh | 1 mln/labeling/estimate.hh | 4 mln/trait/op_plus.hh | 5 - mln/trait/op_uminus.hh | 9 +- mln/trait/promote.hh | 8 + mln/trait/solve.hh | 143 ++++++++++++++++++++++++++++++++++- mln/value/builtin.hh | 63 +++++++++++++++ mln/value/float01.hh | 12 +- mln/value/float01_.hh | 32 +++---- mln/value/graylevel.hh | 10 -- tests/core_category.cc | 40 +++++++++ tests/image_if_value.cc | 48 +++++++++++ tests/trait_op_plus.cc | 2 tests/trait_op_uminus.cc | 129 +++++++++++++++++++++++++++++++ 32 files changed, 858 insertions(+), 178 deletions(-) Index: tests/image_if_value.cc --- tests/image_if_value.cc (revision 0) +++ tests/image_if_value.cc (revision 0) @@ -0,0 +1,48 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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 tests/image_if_value.cc + * + * \brief Tests on mln::image_if_value. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/image_if_value.hh> +#include <mln/debug/iota.hh> +#include <mln/debug/println.hh> + + +int main() +{ + using namespace mln; + + typedef image2d_b<int> I; + I ima(3, 3); + debug::iota(ima); + debug::println(ima); + debug::println(ima | 5); +} Index: tests/trait_op_uminus.cc --- tests/trait_op_uminus.cc (revision 0) +++ tests/trait_op_uminus.cc (revision 0) @@ -0,0 +1,129 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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 tests/trait_op_uminus.cc + * + * \brief Tests on mln::trait::op_uminus. + */ + +#include <mln/trait/op_uminus.hh> +#include <mln/core/concept/object.hh> + + +template <typename E> struct Top_Concept; +template <typename E> struct Sub_Concept; + + +// Top_Concept. + +template <> struct Top_Concept<void> { typedef mln::Object<void> super; }; + +template <typename E> +struct Top_Concept +{ + typedef Top_Concept<void> category; +protected: + Top_Concept() {} +}; + + +// Sub_Concept. + +template <> struct Sub_Concept<void> { typedef Top_Concept<void> super; }; + +template <typename E> +struct Sub_Concept +{ + typedef Sub_Concept<void> category; +protected: + Sub_Concept() {} +}; + + +// test. + +struct test : Sub_Concept< test > +{ + void is_test() {} +}; + + +namespace mln +{ + + namespace trait + { + +// template <> +// struct set_precise_unary_< op_uminus, test > +// { +// typedef bool ret; +// }; + +// template <typename T> +// struct set_unary_< op_uminus, Sub_Concept, T > +// { +// typedef int ret; +// }; + +// template <typename T> +// struct set_unary_< op_uminus, Top_Concept, T > +// { +// typedef float ret; +// }; + + } // mln::trait + +} // mln + + +int main() +{ + using namespace mln; + +// { +// mln_trait_op_uminus_(test) tmp; // bool if precise +// bool* b = &tmp; +// *b = true; +// } + +// { +// mln_trait_op_uminus_(test) tmp; // int if no precise def and both sub and top defs +// void* v = tmp; +// } + +// { +// mln_trait_op_uminus_(test) tmp; float if only top def +// void* v = tmp; +// } + + { + mln_trait_op_uminus_(test) tmp; // test if no def here (default is id, given for Object) + tmp.is_test(); + } + +} Index: tests/core_category.cc --- tests/core_category.cc (revision 0) +++ tests/core_category.cc (revision 0) @@ -0,0 +1,40 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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 tests/core_category.cc + * + * \brief Tests on mln::category. + */ + +#include <mln/core/category.hh> + + +int main() +{ + using namespace mln; + +} Index: tests/trait_op_plus.cc --- tests/trait_op_plus.cc (revision 1221) +++ tests/trait_op_plus.cc (working copy) @@ -41,6 +41,7 @@ template <typename T> struct my_image2d : Image< my_image2d<T> > { + void m() {} }; @@ -87,5 +88,6 @@ { my_image2d<float>* ptr; mln_trait_op_plus_(my_image2d<int>, my_image2d<float>) tmp = *ptr; + tmp.m(); } } Index: mln/trait/op_plus.hh --- mln/trait/op_plus.hh (revision 1221) +++ mln/trait/op_plus.hh (working copy) @@ -50,9 +50,8 @@ /// Default definition of op_plus is given by the promote trait. - template <template <class> class Category_L, typename L, - template <class> class Category_R, typename R> - struct set_binary_< op_plus, Category_L, L, Category_R, R > + template < typename L, typename R > + struct set_binary_< op_plus, Object, L, Object, R > : public promote< L, R > { Index: mln/trait/promote.hh --- mln/trait/promote.hh (revision 1221) +++ mln/trait/promote.hh (working copy) @@ -38,6 +38,10 @@ namespace mln { + // Fwd decl. + template <typename E> struct Object; + + namespace trait { @@ -50,8 +54,8 @@ /// Default case when the same type is involved twice: return this /// type. - template <template <class> class Category, typename T> - struct set_binary_< promote, Category, T, Category, T > + template <typename T> + struct set_binary_< promote, Object, T, Object, T > { typedef T ret; }; Index: mln/trait/solve.hh --- mln/trait/solve.hh (revision 1221) +++ mln/trait/solve.hh (working copy) @@ -41,8 +41,12 @@ { + /// Flag type for an undefined trait. struct undefined; + /// Flag type for a trait multiply undefined. + struct multiply_defined; + // Unary case. @@ -57,7 +61,12 @@ template < template <class> class Name, template <class> class Category_T, typename T > - struct set_unary_ + struct set_unary_; // Fwd decl. + + + template < template <class> class Name, + typename T > + struct set_unary_< Name, Unknown, T > // Blocker; top of inheritance. { typedef undefined ret; }; @@ -67,6 +76,32 @@ { template < template <class> class Name, + typename Super_Category_T, typename T > + struct set_unary_super_; + + template < template <class> class Name, + template <class> class Super_Category_T, typename T > + struct set_unary_super_< Name, Super_Category_T<void>, T > + : + public set_unary_< Name, Super_Category_T, T > + { + }; + + } // end of namespace mln::trait::internal + + + template < template <class> class Name, + template <class> class Category_T, typename T > + struct set_unary_ : internal::set_unary_super_< Name, + typename Category_T<void>::super, T > + { + }; + + + namespace internal + { + + template < template <class> class Name, template <class> class Category_T, typename T > struct helper_choose_unary_ { @@ -106,9 +141,33 @@ template < template <class, class> class Name, + typename L, + typename R > + struct set_precise_binary_ + { + typedef undefined ret; + }; + + + template < template <class, class> class Name, template <class> class Category_L, typename L, template <class> class Category_R, typename R > - struct set_binary_ + struct set_binary_; // Fwd decl. + + + template < template <class, class> class Name, + typename L, + template <class> class Category_R, typename R > + struct set_binary_< Name, Unknown, L, Category_R, R > // Left blocker. + { + typedef undefined ret; + }; + + + template < template <class, class> class Name, + template <class> class Category_L, typename L, + typename R > + struct set_binary_< Name, Category_L, L, Unknown, R > // Right blocker. { typedef undefined ret; }; @@ -117,7 +176,7 @@ template < template <class, class> class Name, typename L, typename R > - struct set_precise_binary_ + struct set_binary_< Name, Unknown, L, Unknown, R > // Blocker. { typedef undefined ret; }; @@ -126,6 +185,84 @@ namespace internal { + // Nota bene: Seq means "super or equal". + template < template <class, class> class Name, + typename Seq_Category_L, typename L, + typename Seq_Category_R, typename R > + struct set_binary_super_; + + template < template <class, class> class Name, + template <class> class Seq_Category_L, typename L, + template <class> class Seq_Category_R, typename R > + struct set_binary_super_< Name, + Seq_Category_L<void>, L, + Seq_Category_R<void>, R > + : + public virtual set_binary_< Name, + Seq_Category_L, L, + Seq_Category_R, R > + { + }; + + template < typename L_ret, typename R_ret > + struct merge_binary_ret_ + { + typedef multiply_defined ret; + }; + + template < typename LR_ret > + struct merge_binary_ret_< LR_ret, LR_ret > + { + typedef LR_ret ret; + }; + + template < typename L_ret > + struct merge_binary_ret_< L_ret, undefined > + { + typedef L_ret ret; + }; + + template < typename R_ret > + struct merge_binary_ret_< undefined, R_ret > + { + typedef R_ret ret; + }; + + template <> + struct merge_binary_ret_< undefined, undefined > + { + typedef undefined ret; + }; + + } // end of namespace mln::trait::internal + + + template < template <class, class> class Name, + template <class> class Category_L, typename L, + template <class> class Category_R, typename R > + struct set_binary_ + { + // Construct a treillis in a static recursive way! + + typedef typename internal::set_binary_super_< Name, + typename Category_L<void>::super, L, + Category_R<void>, R >::ret + L_ret; + + typedef typename internal::set_binary_super_< Name, + Category_L<void>, L, + typename Category_R<void>::super, R >::ret + R_ret; + + typedef typename internal::merge_binary_ret_< L_ret, R_ret >::ret ret; + // FIXME: Do we need to handle this search with a priority? + // FIXME: for a result can be found in both branches... + }; + + + namespace internal + { + template < template <class, class> class Name, template <class> class Category_L, typename L, template <class> class Category_R, typename R > Index: mln/trait/op_uminus.hh --- mln/trait/op_uminus.hh (revision 1221) +++ mln/trait/op_uminus.hh (working copy) @@ -39,10 +39,13 @@ namespace mln { + // Fwd decl. + template <typename E> struct Object; + + namespace trait { - template <typename T> struct op_uminus : public solve_unary<op_uminus, T> { @@ -50,8 +53,8 @@ /// Default definition of op_uminus is the input type itself. - template <template <class> class Category, typename T> - struct set_unary_< op_uminus, Category, T > + template <typename T> + struct set_unary_< op_uminus, Object, T > { typedef T ret; }; Index: mln/core/image_if.hh --- mln/core/image_if.hh (revision 1221) +++ mln/core/image_if.hh (working copy) @@ -35,17 +35,51 @@ # include <mln/core/internal/image_if_base.hh> + +# define Super mln::internal::image_if_base_< I, F, image_if<I,F> > + + namespace mln { + // Fwd decl. + template <typename I, typename F> struct image_if; + + + // internal::data_. + + namespace internal + { + + template <typename I, typename F> + struct data_< image_if<I,F> > : data_< Super > + { + data_(I& ima, const F& f); + }; + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename I, typename F> + struct image_< image_if<I,F> > : trait::image_< Super > + { + }; + + } // end of namespace mln::trait + + + /*! \brief An image class FIXME. * */ template <typename I, typename F> - struct image_if : public internal::image_if_base< I, F > + struct image_if : public Super { /// Skeleton. - typedef image_if< tag::image_<I>, F > skeleton; + typedef image_if< tag::image_<I>, tag::function_<F> > skeleton; /// Constructor from an image \p ima and a predicate \p f. image_if(I& ima, const F& f); @@ -58,6 +92,25 @@ }; + // init_. + + template <typename I, typename F> + void init_(tag::function_t, F& f, const image_if<I,F>& model) + { + f = model.domain().predicate(); + } + + template <typename I, typename F, typename J> + void init_(tag::image_t, image_if<I,F>& target, const J& model) + { + I ima; + init_(tag::image, ima, exact(model)); + F f; + init_(tag::function, f, exact(model)); + target.init_(ima, f); + } + + // Operators. // Image | Function_p2b. @@ -73,6 +126,19 @@ # ifndef MLN_INCLUDE_ONLY + // internal::data_ + + namespace internal + { + + template <typename I, typename F> + data_< image_if<I,F> >::data_(I& ima, const F& f) + : data_< Super >(ima, f) + { + } + + } + // image_if<I,F> template <typename I, typename F> @@ -89,7 +155,9 @@ template <typename I, typename F> image_if<I,F>::operator image_if<const I,F>() const { - image_if<const I,F> tmp(this->data_->ima_, this->data_->pset_); + mln_precondition(this->has_data()); + image_if<const I,F> tmp(this->data_->ima_, + this->data_->pset_.predicate()); return tmp; } @@ -116,4 +184,7 @@ } // end of namespace mln +# undef Super + + #endif // ! MLN_CORE_IMAGE_IF_HH Index: mln/core/category.hh --- mln/core/category.hh (revision 1221) +++ mln/core/category.hh (working copy) @@ -43,6 +43,20 @@ struct Unknown; + template <> + struct Unknown<void> + { + typedef Unknown<void> super; + // Unknown is used to terminate the meta-program that solves a + // call to a trait. This meta-program can browse several branches + // at the same time---if the trait takes 2 types as arguments, the + // program runs over the trellis formed by the "couples of + // categories"--- and when the end of one branch is reached, we do + // not want the program to end; so it continues on that branch + // with the no-op "jump to the super type of Unknown"! + }; + + template <typename T> struct category { @@ -50,17 +64,6 @@ }; - // The case of built-in types. - - template <typename E> - struct Built_In; - - template <> struct category< int > { typedef Built_In<void> ret; }; - template <> struct category< float > { typedef Built_In<void> ret; }; - template <> struct category< double > { typedef Built_In<void> ret; }; - // FIXME: ... - - } // end of namespace mln Index: mln/core/internal/image_if_base.hh --- mln/core/internal/image_if_base.hh (revision 1221) +++ mln/core/internal/image_if_base.hh (working copy) @@ -42,30 +42,33 @@ namespace mln { + namespace internal { - // Fwd decl. - template <typename I, typename F> struct image_if_base; + template <typename I, typename F, typename E> struct image_if_base_; + + // data_. - template <typename I, typename F> - struct data_< image_if_base<I,F> > + template <typename I, typename F, typename E> + struct data_< image_if_base_<I,F,E> > { data_(I& ima, const F& f); - data_(I& ima, const pset_if<mln_pset(I), F>& pset); I ima_; pset_if<mln_pset(I), F> pset_; }; + } // end of namespace mln::internal + + namespace trait { - template <typename I, typename F> - struct image_< image_if_base<I,F> > : default_image_morpher_< I, mln_value(I), - image_if_base<I,F> > + template <typename I, typename F, typename E> + struct image_< mln::internal::image_if_base_<I,F,E> > : default_image_morpher_< I, mln_value(I), E > { private: typedef mln_trait_image_data(I) I_data_; @@ -85,119 +88,86 @@ } // end of namespace mln::trait + + namespace internal { - /*! \brief An base image class for image_if FIXME. + /*! \brief An base image class for image_if_'something. * */ - template <typename I, typename F> - struct image_if_base : public internal::image_domain_morpher_< I, - pset_if<mln_pset(I),F>, - image_if_base<I,F> > + template <typename I, typename F, typename E> + struct image_if_base_ : public internal::image_domain_morpher_< I, pset_if<mln_pset(I),F>, E > { - /// Skeleton. - typedef image_if_base< tag::image_<I>, F > skeleton; - - /// Constructor from an image \p ima and a predicate \p f. - image_if_base(I& ima, const F& f); - /// Constructor without argument. - image_if_base(); + /// Give the definition domain. + const pset_if<mln_pset(I), F>& domain() const; - /// Initialization. void init_(I& ima, const F& f); - /// Initialization. - void init_(I& ima, const pset_if<mln_pset(I), F>& pset); + protected: - /// Test if a pixel value is accessible at \p p. - bool owns_(const mln_psite(I)& p) const; + /// Constructor from an image \p ima and a predicate \p f. + image_if_base_(I& ima, const F& f); - /// Give the definition domain. - const pset_if<mln_pset(I), F>& domain() const; + /// Constructor without argument. + image_if_base_(); }; # ifndef MLN_INCLUDE_ONLY - // init_ +// // init_ - template <typename I, typename F> - void init_(tag::function_t, F& f, const image_if_base<I,F>& model) - { - f = model.domain().predicate(); - } +// template <typename I, typename F, typename E> +// void init_(tag::function_t, F& f, const image_if_base_<I,F,E>& model) +// { +// f = model.domain().predicate(); +// } + +// template <typename I, typename F, typename E, typename J> +// void init_(tag::image_t, image_if_base_<I,F,E>& target, const J& model) +// { +// I ima; +// init_(tag::image, ima, exact(model)); +// F f; +// init_(tag::function, f, exact(model)); +// target.init_(ima, f); +// } - template <typename I, typename F, typename J> - void init_(tag::image_t, image_if_base<I,F>& target, const J& model) - { - I ima; - init_(tag::image, ima, model); - F f; - init_(tag::function, f, model); - target.init_(ima, f); - // Alternative code: - // pset_if<mln_pset(I), F> pset; - // init_(tag::domain, pset, model); - // target.init_(ima, pset); - } + // internal::data_< image_if_base_<I,S> > - // internal::data_< image_if_base<I,S> > - - template <typename I, typename F> - data_< image_if_base<I,F> >::data_(I& ima, const F& f) + template <typename I, typename F, typename E> + data_< image_if_base_<I,F,E> >::data_(I& ima, const F& f) : ima_(ima), pset_(ima.domain() | f) { } - template <typename I, typename F> - data_< image_if_base<I,F> >::data_(I& ima, const pset_if<mln_pset(I), F>& pset) - : ima_(ima), - pset_(pset) - { - } + // image_if_base_<I,F,E> - // image_if_base<I,F> - - template <typename I, typename F> - image_if_base<I,F>::image_if_base() + template <typename I, typename F, typename E> + image_if_base_<I,F,E>::image_if_base_() { } - template <typename I, typename F> - image_if_base<I,F>::image_if_base(I& ima, const F& f) + template <typename I, typename F, typename E> + image_if_base_<I,F,E>::image_if_base_(I& ima, const F& f) { init_(ima, f); } - template <typename I, typename F> + template <typename I, typename F, typename E> void - image_if_base<I,F>::init_(I& ima, const F& f) + image_if_base_<I,F,E>::init_(I& ima, const F& f) { mln_precondition(! this->has_data()); - this->data_ = new internal::data_< image_if_base<I,F> >(ima, f); + this->data_ = new internal::data_<E>(ima, f); } - template <typename I, typename F> - void - image_if_base<I,F>::init_(I& ima, const pset_if<mln_pset(I), F>& pset) - { - mln_precondition(! this->has_data()); - this->data_ = new internal::data_< image_if_base<I,F> >(ima, pset); - } - - template <typename I, typename F> - bool - image_if_base<I,F>::owns_(const mln_psite(I)& p) const - { - return this->data_->pset_.has(p); - } - - template <typename I, typename F> + template <typename I, typename F, typename E> const pset_if<mln_pset(I), F>& - image_if_base<I,F>::domain() const + image_if_base_<I,F,E>::domain() const { return this->data_->pset_; } @@ -210,4 +180,3 @@ #endif // ! MLN_CORE_IMAGE_IF_BASE_HH - Index: mln/core/internal/exact.hh --- mln/core/internal/exact.hh (revision 1221) +++ mln/core/internal/exact.hh (working copy) @@ -65,11 +65,10 @@ typedef T ret; }; - template <typename E, typename T> - yes_ exact_selector_(Object<E>*, T*); + template <typename E> + yes_ exact_selector_(Object<E>*); - template <typename T> - no_ exact_selector_(void*, T* t); + no_ exact_selector_(void*); template <typename E, typename T> E* exact_run_(Object<E>* t, T*); @@ -80,7 +79,7 @@ template <typename T> struct exact_ { - enum { id = sizeof(exact_selector_(make_<T>::ptr(),make_<T>::ptr())) }; + enum { id = sizeof(exact_selector_(make_<T>::ptr())) }; typedef typename exact_ret_<id, T>::ret ret; static ret* run(T* t) { @@ -91,7 +90,7 @@ template <typename T> struct exact_<const T> { - enum { id = sizeof(exact_selector_(make_<T>::ptr(),make_<T>::ptr())) }; + enum { id = sizeof(exact_selector_(make_<T>::ptr())) }; typedef const typename exact_ret_<id, T>::ret ret; static ret* run(const T* t) { Index: mln/core/image_if_value.hh --- mln/core/image_if_value.hh (revision 1221) +++ mln/core/image_if_value.hh (working copy) @@ -34,85 +34,164 @@ */ # include <mln/core/internal/image_if_base.hh> +# include <mln/metal/unconst.hh> + + +# define F fun::eq_p2b_expr_< pw::value_<mlc_unconst(I)>, pw::cst_<mln_value(I)> > +# define Super mln::internal::image_if_base_< I, F, image_if_value<I> > + namespace mln { + // Fwd decl. + template <typename I> struct image_if_value; + + + // internal::data_. + + namespace internal + { + + template <typename I> + struct data_< image_if_value<I> > : data_< Super > + { + data_(I& ima, const F& f); + }; + + } // end of namespace mln::internal + + + namespace trait + { + + template <typename I> + struct image_< image_if_value<I> > : trait::image_< Super > + { + }; + + } // end of namespace mln::trait + + + /*! \brief An image class FIXME. * */ - template <typename I, typename F> - struct image_if_value : public internal::image_if_base< I, F > + template <typename I> + struct image_if_value : public Super { /// Skeleton. - typedef image_if_value< tag::image_<I>, tag::function_<F> > skeleton; + typedef image_if_value< tag::image_<I> > skeleton; + + /// Natural constructor from an image \p ima and a value \p v. + image_if_value(I& ima, const mln_value(I)& v); - /// Constructor from an image \p ima and a predicate \p f. + /// Ancestral constructor from an image \p ima and a function \p f. image_if_value(I& ima, const F& f); /// Constructor without argument. image_if_value(); - /// Const promotion via convertion. - operator image_if_value<const I, F>() const; + // FIXME: Conversion below does *not* work automatically. + /// Const promotion via conversion. + operator image_if_value<const I> () const; }; + + + // init_. + + template <typename I> + void init_(tag::function_t, F& f, const image_if_value<I>& model) + { + f = model.domain().predicate(); + } + + template <typename I, typename J> + void init_(tag::image_t, image_if_value<I>& target, const J& model) + { + I ima; + init_(tag::image, ima, exact(model)); + F f; + init_(tag::function, f, exact(model)); + target.init_(ima, f); + } + + + // Operators. // Image | value. template <typename I> - image_if_value< I, - fun::eq_p2b_expr_< pw::value_<I>, - pw::cst_<mln_value(I)> > > + image_if_value<I> operator | (Image<I>& ima, const mln_value(I)& v); template <typename I> - image_if_value< const I, - fun::eq_p2b_expr_< pw::value_<I>, - pw::cst_<mln_value(I)> > > + image_if_value<const I> operator | (const Image<I>& ima, const mln_value(I)& v); + + # ifndef MLN_INCLUDE_ONLY - // image_if_value<I,F> + // image_if_value<I> - template <typename I, typename F> - image_if_value<I,F>::image_if_value() + template <typename I> + image_if_value<I>::image_if_value() { } - template <typename I, typename F> - image_if_value<I,F>::image_if_value(I& ima, const F& f) + template <typename I> + image_if_value<I>::image_if_value(I& ima, const F& f) { this->init_(ima, f); } - template <typename I, typename F> - image_if_value<I,F>::operator image_if_value<const I, F>() const + template <typename I> + image_if_value<I>::image_if_value(I& ima, const mln_value(I)& v) { - image_if_value<const I, F> tmp(this->data_->ima_, this->data_->pset_); + this->init_(ima, pw::value(ima) = pw::cst(v)); + } + + template <typename I> + image_if_value<I>::operator image_if_value<const I>() const + { + mln_precondition(this->has_data()); + image_if_value<const I> tmp(this->data_->ima_, + this->data_->pset_.predicate); return tmp; } + // internal::data_< image_if_value<I> > + + namespace internal + { + + template <typename I> + data_< image_if_value<I> >::data_(I& ima, const F& f) + : data_< Super >(ima, f) + { + } + + } + // Operators. template <typename I> - image_if_value< I, - fun::eq_p2b_expr_< pw::value_<I>, - pw::cst_<mln_value(I)> > > + image_if_value<I> operator | (Image<I>& ima, const mln_value(I)& v) { - return ima | (pw::value(ima) = pw::cst(v)); + image_if_value<I> tmp(exact(ima), v); + return tmp; } template <typename I> - image_if_value< const I, - fun::eq_p2b_expr_< pw::value_<I>, - pw::cst_<mln_value(I)> > > + image_if_value<const I> operator | (const Image<I>& ima, const mln_value(I)& v) { - return ima | (pw::value(ima) = pw::cst(v)); + image_if_value<const I> tmp(exact(ima), v); + return tmp; } # endif // ! MLN_INCLUDE_ONLY @@ -120,4 +199,8 @@ } // end of namespace mln +# undef Super +# undef F + + #endif // ! MLN_CORE_IMAGE_IF_VALUE_HH Index: mln/core/ops.hh --- mln/core/ops.hh (revision 1221) +++ mln/core/ops.hh (working copy) @@ -34,6 +34,7 @@ # include <mln/core/concept/object.hh> # include <mln/core/exact.hh> +# include <mln/value/builtin.hh> # include <mln/trait/op_plus.hh> # include <mln/trait/op_times.hh> Index: mln/core/concept/image.hh --- mln/core/concept/image.hh (revision 1221) +++ mln/core/concept/image.hh (working copy) @@ -48,6 +48,16 @@ { + // Fwd decl. + template <typename E> struct Image; + + // Image category flag type. + template <> + struct Image<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation of image classes. * Index: mln/core/concept/function.hh --- mln/core/concept/function.hh (revision 1221) +++ mln/core/concept/function.hh (working copy) @@ -39,6 +39,16 @@ namespace mln { + // Fwd decl. + template <typename E> struct Function; + + // Function category flag type. + template <> + struct Function<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation of function-objects. * Index: mln/core/concept/meta_accumulator.hh --- mln/core/concept/meta_accumulator.hh (revision 1221) +++ mln/core/concept/meta_accumulator.hh (working copy) @@ -49,6 +49,16 @@ namespace mln { + // Fwd decl. + template <typename E> struct Meta_Accumulator; + + // Meta_Accumulator category flag type. + template <> + struct Meta_Accumulator<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation of meta accumulators. * Index: mln/core/concept/value_set.hh --- mln/core/concept/value_set.hh (revision 1221) +++ mln/core/concept/value_set.hh (working copy) @@ -32,12 +32,23 @@ * \brief Definition of the concept of mln::Value_Set. */ -# include <mln/core/concept/value_iterator.hh> +# include <mln/core/concept/value_iterator.hh> // FIXME: Why not object.hh? namespace mln { + // Fwd decl. + template <typename E> struct Value_Set; + + // Value_Set category flag type. + template <> + struct Value_Set<void> + { + typedef Object<void> super; + }; + + /*! \brief Base class for implementation classes of sets of values. * * \see mln::doc::Value_Set for a complete documentation of this Index: mln/core/concept/weighted_window.hh --- mln/core/concept/weighted_window.hh (revision 1221) +++ mln/core/concept/weighted_window.hh (working copy) @@ -40,6 +40,17 @@ namespace mln { + // Fwd decl. + template <typename E> struct Weighted_Window; + + // Weighted_Window category flag type. + template <> + struct Weighted_Window<void> + { + typedef Object<void> super; + }; + + /*! \brief Base class for implementation classes that are * weighted_windows. * Index: mln/core/concept/browsing.hh --- mln/core/concept/browsing.hh (revision 1221) +++ mln/core/concept/browsing.hh (working copy) @@ -38,6 +38,17 @@ namespace mln { + // Fwd decl. + template <typename E> struct Browsing; + + // Browsing category flag type. + template <> + struct Browsing<void> + { + typedef Object<void> super; + }; + + /*! \brief Base class for implementation classes that are browsings. * * \see mln::doc::Browsing for a complete documentation of this Index: mln/core/concept/dpoint.hh --- mln/core/concept/dpoint.hh (revision 1221) +++ mln/core/concept/dpoint.hh (working copy) @@ -39,6 +39,16 @@ namespace mln { + // Fwd decl. + template <typename E> struct Dpoint; + + // Dpoint category flag type. + template <> + struct Dpoint<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation of delta-point classes. * Index: mln/core/concept/object.hh --- mln/core/concept/object.hh (revision 1221) +++ mln/core/concept/object.hh (working copy) @@ -37,6 +37,7 @@ # include <iostream> # include <mln/core/macros.hh> +# include <mln/core/category.hh> # include <mln/core/contract.hh> # include <mln/core/internal/fixme.hh> # include <mln/trace/all.hh> @@ -59,6 +60,17 @@ namespace mln { + // Fwd decl. + template <typename E> struct Object; + + // Object category flag type. + template <> + struct Object<void> + { + typedef Unknown<void> super; + }; + + /*! \brief Base class for almost every class defined in milena. * * The parameter \a E is the exact type. Index: mln/core/concept/neighborhood.hh --- mln/core/concept/neighborhood.hh (revision 1221) +++ mln/core/concept/neighborhood.hh (working copy) @@ -38,6 +38,17 @@ namespace mln { + // Fwd decl. + template <typename E> struct Neighborhood; + + // Neighborhood category flag type. + template <> + struct Neighborhood<void> + { + typedef Object<void> super; + }; + + /*! \brief Base class for implementation classes that are neighborhoods. * * \see mln::doc::Neighborhood for a complete documentation of this Index: mln/core/concept/window.hh --- mln/core/concept/window.hh (revision 1221) +++ mln/core/concept/window.hh (working copy) @@ -39,6 +39,16 @@ namespace mln { + // Fwd decl. + template <typename E> struct Window; + + // Window category flag type. + template <> + struct Window<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation classes that are windows. * Index: mln/core/concept/value.hh --- mln/core/concept/value.hh (revision 1221) +++ mln/core/concept/value.hh (working copy) @@ -38,6 +38,17 @@ namespace mln { + // Fwd decl. + template <typename E> struct Value; + + // Value category flag type. + template <> + struct Value<void> + { + typedef Object<void> super; + }; + + /*! \brief Base class for implementation classes of values. * * \see mln::doc::Value for a complete documentation of this class @@ -96,6 +107,7 @@ # include <mln/value/cast.hh> +# include <mln/value/builtin.hh> #endif // ! MLN_CORE_CONCEPT_VALUE_HH Index: mln/core/concept/point_site.hh --- mln/core/concept/point_site.hh (revision 1221) +++ mln/core/concept/point_site.hh (working copy) @@ -38,10 +38,19 @@ namespace mln { - // Fwd decl (used in the "category" definition). - template <typename P> struct Point; + // FIXME: Hack is "Point" instead of "Points_Site"; change it! + // Fwd decl. + template <typename E> struct Point; + + // Point_Site category flag type. + template <> + struct Point<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation classes of the notion of * "point site". Index: mln/core/concept/accumulator.hh --- mln/core/concept/accumulator.hh (revision 1221) +++ mln/core/concept/accumulator.hh (working copy) @@ -41,6 +41,16 @@ namespace mln { + // Fwd decl. + template <typename E> struct Accumulator; + + // Accumulator category flag type. + template <> + struct Accumulator<void> + { + typedef Object<void> super; + }; + /*! \brief Base class for implementation of accumulators. * Index: mln/value/graylevel.hh --- mln/value/graylevel.hh (revision 1221) +++ mln/value/graylevel.hh (working copy) @@ -74,9 +74,6 @@ /// Op encoding_t. operator enc() const; - /// Op graylevel. - operator graylevel() const; - /// Op<. bool operator<(const graylevel<n>& rhs) const; @@ -168,13 +165,6 @@ } template <unsigned n> - graylevel<n>::operator graylevel() const - { - gray tmp(n, val_); - return tmp; - } - - template <unsigned n> graylevel<n>::operator typename graylevel<n>::enc() const { return val_; Index: mln/value/float01_.hh --- mln/value/float01_.hh (revision 1221) +++ mln/value/float01_.hh (working copy) @@ -50,7 +50,7 @@ /// General float01-level class on n bits. template <unsigned n> class float01_ - : public internal::value_like_< double, + : public internal::value_like_< float, float01_<n> > { public: @@ -62,25 +62,25 @@ float01_(); /// Ctor. - float01_(const double val); + float01_(const float val); /// Access to std type. - double value() const; + float value() const; void set_ind(unsigned long val); enc value_ind() const; /// Op encoding_t. - operator double() const; + operator float() const; - /// Op float01_. - operator float01_() const; + /// Op float01. + operator float01() const; /// Op<. bool operator<(const float01_<n>& rhs) const; - float01_<n>& operator=(const double val); + float01_<n>& operator=(const float val); /// Op=. // bool operator=(const float01_<n>& rhs) const; @@ -134,7 +134,7 @@ bool operator=(const float01_<n>& lhs, const float01_<n>& rhs); template <unsigned n> - bool approx_equal(const float01_<n>& lhs, const double f); + bool approx_equal(const float01_<n>& lhs, const float f); # ifndef MLN_INCLUDE_ONLY @@ -147,7 +147,7 @@ } template <unsigned n> - float01_<n>::float01_(const double val) + float01_<n>::float01_(const float val) : val_( int(val * (mln_card_(float01_<n>) - 1)) ) { mln_precondition(val >= 0); @@ -155,10 +155,10 @@ } template <unsigned n> - double + float float01_<n>::value() const { - return (double(val_) / (mln_card_(float01_<n>) - 1)); + return (float(val_) / (mln_card_(float01_<n>) - 1)); } template <unsigned n> @@ -177,7 +177,7 @@ template <unsigned n> float01_<n>& - float01_<n>::operator=(const double val) + float01_<n>::operator=(const float val) { mln_precondition(val >= 0); mln_precondition(val <= 1); @@ -186,16 +186,16 @@ } template <unsigned n> - float01_<n>::operator float01_() const + float01_<n>::operator float01() const { float01 tmp(n, val_); return tmp; } template <unsigned n> - float01_<n>::operator double() const + float01_<n>::operator float() const { - return double(val_) / (mln_card_(float01_<n>) - 1); + return float(val_) / (mln_card_(float01_<n>) - 1); } template <unsigned n> @@ -223,7 +223,7 @@ } template <unsigned n> - bool approx_equal(const float01_<n>& lhs, const double f) + bool approx_equal(const float01_<n>& lhs, const float f) { return float01(lhs) = float01_<n>(f); } Index: mln/value/builtin.hh --- mln/value/builtin.hh (revision 0) +++ mln/value/builtin.hh (revision 0) @@ -0,0 +1,63 @@ +// Copyright (C) 2007 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 +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library 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 this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library 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. + +#ifndef MLN_VALUE_BUILTIN_HH +# define MLN_VALUE_BUILTIN_HH + +/*! \file mln/value/builtin.hh + * \brief Some definitions about builtins. + */ + + +namespace mln +{ + + // Fwd decl. + template <typename E> struct Value; + + + // The case of built-in types. + + template <typename E> + struct Built_In + { + typedef Value<void> super; // Builtins belong to a sub-category of values. + }; + + template <> struct category< int > { typedef Built_In<void> ret; }; + template <> struct category< float > { typedef Built_In<void> ret; }; + template <> struct category< double > { typedef Built_In<void> ret; }; + // FIXME: ... + + +} // end of namespace mln + + +# include <mln/core/concept/value.hh> + + +#endif // ! MLN_VALUE_BUILTIN_HH Index: mln/value/float01.hh --- mln/value/float01.hh (revision 1221) +++ mln/value/float01.hh (working copy) @@ -52,10 +52,10 @@ public: /// Encoding associated type. - typedef double enc; + typedef float enc; /// Equivalent associated type. - typedef double equiv; + typedef float equiv; /// Ctor. float01(); @@ -65,10 +65,10 @@ float01(const float01_<N>& val); /// Ctor. - float01(unsigned nbits, double val); + float01(unsigned nbits, float val); /// Access to std type. - double value() const; + float value() const; unsigned long value_ind() const; unsigned nbits() const; @@ -137,13 +137,13 @@ { } - float01::float01(unsigned nbits, double val) + float01::float01(unsigned nbits, float val) : nbits_(nbits), val_(unsigned(val * internal::two_pow_n_minus_1(nbits))) { } - double float01::value() const + float float01::value() const { mln_invariant(nbits_ != 0); return double(val_) / internal::two_pow_n_minus_1(nbits_); Index: mln/labeling/estimate.hh --- mln/labeling/estimate.hh (revision 1221) +++ mln/labeling/estimate.hh (working copy) @@ -33,7 +33,7 @@ * \brief Compute the estimate pixel value. */ -# include <mln/core/image_if.hh> +# include <mln/core/image_if_value.hh> # include <mln/accu/compute.hh> @@ -60,6 +60,8 @@ mln_accu_with(A, util::pix<I>)::result estimate(const Image<I>& input, const mln_value(I)& val) { +// void* v = (input | val); +// return 0; return accu::compute<A>(input | val); }
participants (1)
-
Thierry Geraud