https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Handle const promotion for morphers. * mln/core/internal/image_adaptor.hh (operator I): New. (pset_): Remove; uncompatible with temporary pset. (domain): Change sig. * mln/core/inplace.hh: New. * tests/line2d.cc: Augment; use inplace. * mln/core/sub_image.hh: New. * tests/sub_image.cc: New. * mln/core/safe.hh (safe): New overload; const version. (safe_image): Update. (default_value): New. (operator safe_image<const I>): New. * tests/safe_image.cc: Augment. * mln/core/queue_p.hh (push): Fix missing return. * mln/core/internal/image_base.hh: Add doc. * mln/core/pset_if_piter.hh (fixme): Remove include; useless. * mln/core/vec_p_piter.hh: Likewise. * mln/make/box2d: Change arg list (all min first). * tests/to_image.cc: Update. mln/core/image_if.hh | 10 ++ mln/core/inplace.hh | 63 ++++++++++++++++++ mln/core/internal/image_adaptor.hh | 19 +++-- mln/core/internal/image_base.hh | 27 +++++-- mln/core/pset_if_piter.hh | 1 mln/core/queue_p.hh | 1 mln/core/safe.hh | 62 +++++++++++++---- mln/core/sub_image.hh | 129 +++++++++++++++++++++++++++++++++++++ mln/core/vec_p_piter.hh | 1 mln/make/box2d.hh | 10 +- tests/line2d.cc | 9 ++ tests/safe_image.cc | 30 +++++++- tests/sub_image.cc | 53 +++++++++++++++ tests/to_image.cc | 4 - 14 files changed, 378 insertions(+), 41 deletions(-) Index: tests/sub_image.cc --- tests/sub_image.cc (revision 0) +++ tests/sub_image.cc (revision 0) @@ -0,0 +1,53 @@ +// 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/sub_image.cc + * + * \brief Tests on mln::sub_image. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/sub_image.hh> +#include <mln/core/inplace.hh> + +#include <mln/level/fill.hh> +#include <mln/debug/println.hh> + + +int main() +{ + using namespace mln; + + image2d_b<int> ima(8, 8); + level::fill(ima, 0); + debug::println(ima); + + level::fill(inplace(ima | make::box2d(1,1, 3,3)), 5); + level::fill(inplace(ima | make::box2d(4,4, 6,6)), 1); + + debug::println(ima); +} Index: tests/line2d.cc --- tests/line2d.cc (revision 1048) +++ tests/line2d.cc (working copy) @@ -33,10 +33,13 @@ #include <iterator> #include <mln/core/image2d_b.hh> +#include <mln/core/sub_image.hh> +#include <mln/core/inplace.hh> #include <mln/level/fill.hh> #include <mln/level/compare.hh> #include <mln/draw/line.hh> +#include <mln/debug/println.hh> int main() @@ -56,4 +59,10 @@ level::paste(pw::cst(true) | l, ima2); mln_assertion(ima2 = ima); + + image2d_b<bool> ima3(10,10); + level::fill(ima3, false); + level::fill(inplace(ima3 | l), true); + + mln_assertion(ima3 = ima); } Index: tests/to_image.cc --- tests/to_image.cc (revision 1048) +++ tests/to_image.cc (working copy) @@ -47,9 +47,9 @@ { using namespace mln; - box2d box_3x3 = make::box2d(-1,+1, -1,+1); + box2d box_3x3 = make::box2d(-1,-1, +1,+1); // ^^^^^ ^^^^^ - // rows cols + // from to // center point // V Index: tests/safe_image.cc --- tests/safe_image.cc (revision 1048) +++ tests/safe_image.cc (working copy) @@ -32,7 +32,6 @@ #include <mln/core/image2d_b.hh> #include <mln/core/safe.hh> -#include <mln/level/paste.hh> int main() @@ -41,9 +40,30 @@ typedef image2d_b<int> I; I ima(1, 1); - safe_image<I> ima_ = safe(ima); + point2d + in = make::point2d(0, 0), + out = make::point2d(-999, -999); + + { + safe_image<I> ima_ = safe(ima, 7); + + ima_(in) = 51; + mln_assertion(ima_(in) = 51); + + ima_(out) = 0; + mln_assertion(ima_(out) = 7); + + // test "image_adaptor_<..>::operator I() const" + I ima2 = ima_; + const I ima3 = ima_; + } + + { + safe_image<const I> ima_ = safe(ima, 7); + + ima(in) = 51; + mln_assertion(ima_(in) = 51); + mln_assertion(ima_(out) = 7); + } - point2d p = make::point2d(-5, -1); - ima_(p) = 0; - level::paste(ima, ima_); } Index: mln/core/image_if.hh --- mln/core/image_if.hh (revision 1048) +++ mln/core/image_if.hh (working copy) @@ -66,6 +66,9 @@ typedef image_if<mln_ch_value(I,T), F> ret; }; + /// Const promotion via convertion. + operator image_if<const I, F>() const; + protected: pset pset_; @@ -110,6 +113,13 @@ return pset_; } + template <typename I, typename F> + image_if<I,F>::operator image_if<const I, F>() const + { + image_if<const I, F> tmp(this->adaptee_, this->f_); + return tmp; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/queue_p.hh --- mln/core/queue_p.hh (revision 1048) +++ mln/core/queue_p.hh (working copy) @@ -196,6 +196,7 @@ vect_needs_update_ = true; bb_needs_update_ = true; } + return *this; } template <typename P> Index: mln/core/safe.hh --- mln/core/safe.hh (revision 1048) +++ mln/core/safe.hh (working copy) @@ -37,14 +37,17 @@ // FIXME: Doc! template <typename I> - struct safe_image : public internal::image_adaptor_< I, safe_image<I> > + class safe_image : public internal::image_adaptor_< I, safe_image<I> > { - typedef internal::image_adaptor_< I, safe_image<I> > super; + typedef internal::image_adaptor_< I, safe_image<I> > super_; + public: - safe_image(Image<I>& ima); + safe_image(I& ima, const mln_value(I)& default_value); mln_rvalue(I) operator()(const mln_psite(I)& p) const; - mln_lvalue(I) operator()(const mln_psite(I)& p); + + typedef typename super_::lvalue lvalue; + lvalue operator()(const mln_psite(I)& p); template <typename U> struct change_value @@ -52,20 +55,33 @@ typedef safe_image<mln_ch_value(I, U)> ret; }; + /// Const promotion via convertion. + operator safe_image<const I>() const; + + protected: + mln_value(I) default_value_; }; template <typename I> - safe_image<I> safe(Image<I>& ima); + safe_image<I> safe(Image<I>& ima, + mln_value(I) default_value = mln_value(I)()); + + template <typename I> + safe_image<const I> safe(const Image<I>& ima, + mln_value(I) default_value = mln_value(I)()); # ifndef MLN_INCLUDE_ONLY + // safe_image<I> + template <typename I> - safe_image<I>::safe_image(Image<I>& ima) - : super(exact(ima)) + safe_image<I>::safe_image(I& ima, const mln_value(I)& default_value) + : super_(exact(ima)), + default_value_(default_value) { } @@ -73,26 +89,44 @@ mln_rvalue(I) safe_image<I>::operator()(const mln_psite(I)& p) const { - static mln_value(I) tmp; if (! this->owns_(p)) - return tmp; + return default_value_; return this->adaptee_(p); } template <typename I> - mln_lvalue(I) + typename safe_image<I>::lvalue safe_image<I>::operator()(const mln_psite(I)& p) { - static mln_value(I) tmp; + static mln_value(I) forget_it_; if (! this->owns_(p)) - return tmp; + // so default_value_ is returned but cannot be modified + return forget_it_ = default_value_; return this->adaptee_(p); } template <typename I> - safe_image<I> safe(Image<I>& ima) + safe_image<I>::operator safe_image<const I>() const + { + safe_image<const I> tmp(this->adaptee_, default_value_); + return tmp; + } + + // safe + + template <typename I> + safe_image<I> safe(Image<I>& ima, + mln_value(I) default_value) + { + safe_image<I> tmp(exact(ima), default_value); + return tmp; + } + + template <typename I> + safe_image<const I> safe(const Image<I>& ima, + mln_value(I) default_value) { - safe_image<I> tmp(ima); + safe_image<const I> tmp(exact(ima), default_value); return tmp; } Index: mln/core/internal/image_adaptor.hh --- mln/core/internal/image_adaptor.hh (revision 1048) +++ mln/core/internal/image_adaptor.hh (working copy) @@ -78,7 +78,7 @@ bool owns_(const psite& p) const; /// Give the definition domain. - const S& domain() const; + const mln_pset(I)& domain() const; /// Give the set of values. const vset& values() const; @@ -89,6 +89,8 @@ /// Read-write access of pixel value at point site \p p. lvalue operator()(const psite& p); + /// Convertion to the underlying (adapted) image. + operator I() const; protected: I& adaptee_; @@ -97,13 +99,17 @@ image_adaptor_(I& adaptee); }; - // FIXME: image_const_adaptor_ - # ifndef MLN_INCLUDE_ONLY template <typename I, typename E, typename S> + image_adaptor_<I,E,S>::image_adaptor_(I& adaptee) + : adaptee_(adaptee) + { + } + + template <typename I, typename E, typename S> bool image_adaptor_<I,E,S>::has_data() const { return adaptee_.has_data(); @@ -117,7 +123,7 @@ } template <typename I, typename E, typename S> - const S& + const mln_pset(I)& image_adaptor_<I,E,S>::domain() const { mln_precondition(exact(this)->has_data()); @@ -148,9 +154,10 @@ } template <typename I, typename E, typename S> - image_adaptor_<I,E,S>::image_adaptor_(I& adaptee) - : adaptee_(adaptee) + image_adaptor_<I,E,S>::operator I() const { + mln_precondition(exact(this)->has_data()); + return adaptee_; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/internal/image_base.hh --- mln/core/internal/image_base.hh (revision 1048) +++ mln/core/internal/image_base.hh (working copy) @@ -43,6 +43,11 @@ { + /*! \brief Return the lvalue type when an image with type \c I is + * morphed. + * + * \internal + */ template <typename I> struct morpher_lvalue_ { @@ -56,7 +61,10 @@ }; - + /*! \brief Selector for image inheritance (fast or regular). + * + * \internal + */ template <typename Is_fast, typename E> struct select_image_concept_; @@ -77,7 +85,9 @@ * \internal */ template <typename S, typename E> - struct image_base_ : public select_image_concept_< typename trait::is_fast<E>::ret, + struct image_base_ + + : public select_image_concept_< typename trait::is_fast<E>::ret, E > { /// Point_Set associated type. @@ -113,6 +123,9 @@ /// Give the number of points of the image domain. std::size_t npoints() const; + + // FIXME: Add owns_(p) based on has(p)? + protected: image_base_(); }; @@ -121,6 +134,11 @@ # ifndef MLN_INCLUDE_ONLY template <typename S, typename E> + image_base_<S,E>::image_base_() + { + } + + template <typename S, typename E> bool image_base_<S,E>::has(const psite& p) const { @@ -144,11 +162,6 @@ return exact(this)->domain().npoints(); } - template <typename S, typename E> - image_base_<S,E>::image_base_() - { - } - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::internal Index: mln/core/sub_image.hh --- mln/core/sub_image.hh (revision 0) +++ mln/core/sub_image.hh (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. + +#ifndef MLN_CORE_SUB_IMAGE_HH +# define MLN_CORE_SUB_IMAGE_HH + +# include <mln/core/internal/image_adaptor.hh> + + +namespace mln +{ + + // FIXME: Doc! + + template <typename I, typename S> + class sub_image : public internal::image_adaptor_< I, + sub_image<I,S>, + S > + { + typedef internal::image_adaptor_<I, sub_image<I,S>, S> super_; + public: + + sub_image(I& ima, const S& pset); + + bool owns_(const mln_psite(I)& p) const; + + template <typename U> + struct change_value + { + typedef internal::fixme ret; + }; + + const S& domain() const; + + /// Const promotion via convertion. + operator sub_image<const I, S>() const; + + protected: + const S& pset_; + }; + + + + template <typename I, typename S> + sub_image<const I, S> operator|(const Image<I>& ima, const Point_Set<S>& pset); + + template <typename I, typename S> + sub_image<I, S> operator|(Image<I>& ima, const Point_Set<S>& pset); + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename S> + sub_image<I,S>::sub_image(I& ima, const S& pset) + : super_(ima), + pset_(pset) + { + } + + template <typename I, typename S> + bool + sub_image<I,S>::owns_(const mln_psite(I)& p) const + { + return this->domain().has(p); + } + + template <typename I, typename S> + const S& + sub_image<I,S>::domain() const + { + return pset_; + } + + template <typename I, typename S> + sub_image<I,S>::operator sub_image<const I, S>() const + { + sub_image<const I, S> tmp(this->adaptee_, this->pset_); + return tmp; + } + + // operator + + template <typename I, typename S> + sub_image<const I, S> + operator|(const Image<I>& ima, const Point_Set<S>& pset) + { + sub_image<const I, S> tmp(exact(ima), exact(pset)); + return tmp; + } + + template <typename I, typename S> + sub_image<I, S> + operator|(Image<I>& ima, const Point_Set<S>& pset) + { + sub_image<I, S> tmp(exact(ima), exact(pset)); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_SUB_IMAGE_HH Index: mln/core/pset_if_piter.hh --- mln/core/pset_if_piter.hh (revision 1048) +++ mln/core/pset_if_piter.hh (working copy) @@ -35,7 +35,6 @@ # include <mln/core/concept/point_iterator.hh> # include <mln/core/internal/piter_adaptor.hh> -# include <mln/core/internal/fixme.hh> # include <mln/core/pset_if.hh> Index: mln/core/vec_p_piter.hh --- mln/core/vec_p_piter.hh (revision 1048) +++ mln/core/vec_p_piter.hh (working copy) @@ -34,7 +34,6 @@ */ # include <mln/core/vec_p.hh> -# include <mln/core/internal/fixme.hh> namespace mln Index: mln/core/inplace.hh --- mln/core/inplace.hh (revision 0) +++ mln/core/inplace.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_CORE_INPLACE_HH +# define MLN_CORE_INPLACE_HH + +/*! \file mln/core/inplace.hh + * \brief Definition of the mln::inplace routine. + */ + +# include <mln/core/exact.hh> + + +namespace mln +{ + + /*! \brief Routine to make temporary objects become mutable. + * + * \warning This routine is not safe! FIXME: Explain. + */ + template <typename E> + E& inplace(const Object<E>& temp); + + + +# ifndef MLN_INCLUDE_ONLY + + template <typename E> + E& inplace(const Object<E>& temp) + { + return const_cast<E&>( exact(temp) ); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_INPLACE_HH Index: mln/make/box2d.hh --- mln/make/box2d.hh (revision 1048) +++ mln/make/box2d.hh (working copy) @@ -60,16 +60,16 @@ * \overload * * \param[in] min_row Index of the top most row. - * \param[in] max_row Index of the botton most row. * \param[in] min_col Index of the left most column. + * \param[in] max_row Index of the botton most row. * \param[in] max_col Index of the right most column. * * \pre \p max_row >= \p min_row and \p max_col >= \p min_col. * * \return A 2D box. */ - mln::box2d box2d(int min_row, int max_row, - int min_col, int max_col); + mln::box2d box2d(int min_row, int min_col, + int max_row, int max_col); # ifndef MLN_INCLUDE_ONLY @@ -82,8 +82,8 @@ return tmp; } - mln::box2d box2d(int min_row, int max_row, - int min_col, int max_col) + mln::box2d box2d(int min_row, int min_col, + int max_row, int max_col) { mln_precondition(max_row >= min_row && max_col >= min_col); mln::box2d tmp(make::point2d(min_row, min_col),