Commit ef1feee9 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

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.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1049 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent d7cfbdbf
2007-08-27 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.
2007-08-27 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Renaming.
......
......@@ -66,6 +66,9 @@ namespace mln
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 @@ namespace mln
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
......
// 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
......@@ -78,7 +78,7 @@ namespace mln
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 @@ namespace mln
/// 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,12 +99,16 @@ namespace mln
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
{
......@@ -117,7 +123,7 @@ namespace mln
}
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 @@ namespace mln
}
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
......
......@@ -43,6 +43,11 @@ namespace mln
{
/*! \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 @@ namespace mln
};
/*! \brief Selector for image inheritance (fast or regular).
*
* \internal
*/
template <typename Is_fast, typename E>
struct select_image_concept_;
......@@ -77,8 +85,10 @@ namespace mln
* \internal
*/
template <typename S, typename E>
struct image_base_ : public select_image_concept_< typename trait::is_fast<E>::ret,
E >
struct image_base_
: public select_image_concept_< typename trait::is_fast<E>::ret,
E >
{
/// Point_Set associated type.
typedef S pset;
......@@ -113,6 +123,9 @@ namespace mln
/// 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_();
};
......@@ -120,6 +133,11 @@ namespace mln
# 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 @@ namespace mln
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
......
......@@ -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>
......
......@@ -196,6 +196,7 @@ namespace mln
vect_needs_update_ = true;
bb_needs_update_ = true;
}
return *this;
}
template <typename P>
......
......@@ -37,14 +37,17 @@ namespace mln
// 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 @@ namespace mln
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 @@ namespace mln
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;
}
......
// 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
......@@ -34,7 +34,6 @@
*/
# include <mln/core/vec_p.hh>
# include <mln/core/internal/fixme.hh>
namespace mln
......
......@@ -60,16 +60,16 @@ namespace mln
* \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 @@ namespace mln
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),
......
......@@ -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 @@ int main()
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);
}
......@@ -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 @@ int main()
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_);
}
// 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.