
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add pixel in milena. * tests/pixel.cc: New. * mln/core/pixel.hh: New. * mln/core/concept/genpixel.hh: New. * mln/core/internal/force_exact.hh (mln_internal_add_force_exact_): Remove. (force_exact): New. * mln/convert/to_dpoint.hh, * mln/core/dpoints_piter.hh, * mln/core/concept/genpoint.hh, * mln/core/internal/coord_impl.hh, * mln/core/internal/box_impl.hh: Update. mln/convert/to_dpoint.hh | 2 mln/core/concept/genpixel.hh | 126 +++++++++++++++++++++++++++++++ mln/core/concept/genpoint.hh | 23 ++--- mln/core/dpoints_piter.hh | 2 mln/core/internal/box_impl.hh | 20 +--- mln/core/internal/coord_impl.hh | 49 ++++-------- mln/core/internal/force_exact.hh | 45 +++++++---- mln/core/pixel.hh | 158 +++++++++++++++++++++++++++++++++++++++ tests/pixel.cc | 61 +++++++++++++++ 9 files changed, 415 insertions(+), 71 deletions(-) Index: tests/pixel.cc --- tests/pixel.cc (revision 0) +++ tests/pixel.cc (revision 0) @@ -0,0 +1,61 @@ +// 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/pixel.cc + * + * \brief Tests on mln::pixel. + */ + +#include <mln/core/pixel.hh> +#include <mln/core/image2d_b.hh> + + +int main() +{ + using namespace mln; + + typedef image2d_b<int> I; + I ima(3, 3); + + { + pixel<I> pxl(ima); + pxl.site() = make::point2d(1, 1); + *pxl = 51; + mln_assertion(ima.at(1,1) = 51); + } + + { + pixel<const I> pxl(ima); + pxl.site() = make::point2d(1, 1); + ima.at(1,1) = 51; + mln_assertion(*pxl = 51); + + // hopefully the code below does not compile: + // *pxl = 0; + // assignment of read-only location + } +} Index: mln/convert/to_dpoint.hh --- mln/convert/to_dpoint.hh (revision 1010) +++ mln/convert/to_dpoint.hh (working copy) @@ -52,7 +52,7 @@ template <typename P> mln_dpoint(P) to_dpoint(const GenPoint<P>& p_) { - const P& p = p_.force_exact_(); + const P& p = internal::force_exact<P>(p_); mln_dpoint(P) tmp; for (unsigned i = 0; i < P::dim; ++i) tmp[i] = p[i]; Index: mln/core/pixel.hh --- mln/core/pixel.hh (revision 0) +++ mln/core/pixel.hh (revision 0) @@ -0,0 +1,158 @@ +// 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_PIXEL_HH +# define MLN_CORE_PIXEL_HH + +/*! \file mln/core/pixel.hh + * + * \brief Definition of the generic pixel class mln::pixel. + */ + +# include <mln/core/concept/genpixel.hh> + + +namespace mln +{ + + + template <typename I> + struct pixel_lvalue + { + typedef mln_lvalue(I) ret; + }; + + template <typename I> + struct pixel_lvalue< const I > + { + typedef mln_rvalue(I) ret; + }; + + + + /*! \brief Generic pixel class. + * + * The parameter is \c I the type of the image it belongs to. + */ + template <typename I> + struct pixel : public Object< pixel<I> >, + public GenPixel< pixel<I> > + { + typedef mln_psite(I) psite; + typedef mln_value(I) value; + + pixel(I& ima); + pixel(I& ima, const psite& p); + + const I& image() const; + + const psite& site() const; + psite& site(); + + mln_rvalue(I) operator*() const; + typename pixel_lvalue<I>::ret operator*(); + + const value* address() const; + value* address(); + + protected: + + I& ima_; + psite p_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + pixel<I>::pixel(I& image) + : ima_(image) + { + } + + template <typename I> + pixel<I>::pixel(I& image, const psite& p) + : ima_(image), + p_(p) + { + } + + template <typename I> + const I& + pixel<I>::image() const + { + return ima_; + } + + template <typename I> + const mln_psite(I)& + pixel<I>::site() const + { + return p_; + } + + template <typename I> + mln_psite(I)& + pixel<I>::site() + { + return p_; + } + + template <typename I> + mln_rvalue(I) + pixel<I>::operator*() const + { + return ima_(p_); + } + + template <typename I> + typename pixel_lvalue<I>::ret + pixel<I>::operator*() + { + return ima_(p_); + } + + template <typename I> + const mln_value(I)* + pixel<I>::address() const + { + return & ima_(p_); + } + + template <typename I> + mln_value(I)* + pixel<I>::address() + { + return & ima_(p_); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_PIXEL_HH Index: mln/core/dpoints_piter.hh --- mln/core/dpoints_piter.hh (revision 1010) +++ mln/core/dpoints_piter.hh (working copy) @@ -112,7 +112,7 @@ dpoints_fwd_piter<D>::dpoints_fwd_piter(const Dps& dps, const GenPoint<Pref>& p_ref) : dps_(exact(dps).vec()), - p_ref_(* p_ref.force_exact_().pointer()) + p_ref_(* internal::force_exact<Pref>(p_ref).pointer()) { invalidate(); } Index: mln/core/concept/genpoint.hh --- mln/core/concept/genpoint.hh (revision 1010) +++ mln/core/concept/genpoint.hh (working copy) @@ -77,8 +77,6 @@ coord operator[](unsigned i) const; */ - mln_internal_add_force_exact_(GenPoint<E>) - protected: GenPoint(); @@ -210,8 +208,10 @@ std::ostream& operator<<(std::ostream& ostr, const GenPoint<P>& p); + # ifndef MLN_INCLUDE_ONLY + template <typename E> GenPoint<E>::GenPoint() { @@ -227,12 +227,13 @@ m2 = 0; } + template <typename Pl, typename Pr> bool operator=(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs) { // FIXME: mlc::same_grid<Pl, Pr>::check(); - const Pl& lhs_ = lhs.force_exact_(); - const Pr& rhs_ = rhs.force_exact_(); + const Pl& lhs_ = internal::force_exact<Pl>(lhs); + const Pr& rhs_ = internal::force_exact<Pr>(rhs); mlc::same_point<Pl, Pr>::check(); for (unsigned i = 0; i < Pl::dim; ++i) if (lhs_[i] != rhs_[i]) @@ -244,8 +245,8 @@ bool operator<(const GenPoint<Pl>& lhs, const GenPoint<Pr>& rhs) { // FIXME: mlc::same_grid<Pl, Pr>::check(); - const Pl& lhs_ = lhs.force_exact_(); - const Pr& rhs_ = rhs.force_exact_(); + const Pl& lhs_ = internal::force_exact<Pl>(lhs); + const Pr& rhs_ = internal::force_exact<Pr>(rhs); for (unsigned i = 0; i < Pl::dim; ++i) { if (lhs_[i] = rhs_[i]) @@ -262,8 +263,8 @@ mlc::equal<mln_dpoint(Pl), mln_dpoint(Pr)>::check(); // FIXME: mlc::same_grid<Pl, Pr>::check(); mlc::same_coord<Pl, Pr>::check(); - const Pl& lhs_ = lhs.force_exact_(); - const Pr& rhs_ = rhs.force_exact_(); + const Pl& lhs_ = internal::force_exact<Pl>(lhs); + const Pr& rhs_ = internal::force_exact<Pr>(rhs); mln_dpoint(Pl) tmp; for (unsigned i = 0; i < Pl::dim; ++i) tmp[i] = lhs_[i] - rhs_[i]; @@ -275,7 +276,7 @@ mln_point(P) operator+(const GenPoint<P>& lhs, const mln_dpoint(P)& rhs) { - const P& lhs_ = lhs.force_exact_(); + const P& lhs_ = internal::force_exact<P>(lhs); mln_point(P) tmp; for (unsigned i = 0; i < P::dim; ++i) tmp[i] = lhs_[i] + rhs[i]; @@ -286,7 +287,7 @@ mln_point(P) operator-(const GenPoint<P>& lhs, const mln_dpoint(P)& rhs) { - const P& lhs_ = lhs.force_exact_(); + const P& lhs_ = internal::force_exact<P>(lhs); mln_point(P) tmp; for (unsigned i = 0; i < P::dim; ++i) tmp[i] = lhs_[i] - rhs[i]; @@ -296,7 +297,7 @@ template <typename P> std::ostream& operator<<(std::ostream& ostr, const GenPoint<P>& p) { - const P& p_ = p.force_exact_(); + const P& p_ = internal::force_exact<P>(p); ostr << '('; for (unsigned i = 0; i < P::dim; ++i) Index: mln/core/concept/genpixel.hh --- mln/core/concept/genpixel.hh (revision 0) +++ mln/core/concept/genpixel.hh (revision 0) @@ -0,0 +1,126 @@ +// 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_CONCEPT_GENPIXEL_HH +# define MLN_CORE_CONCEPT_GENPIXEL_HH + +/*! \file mln/core/concept/genpixel.hh + * \brief Definition of the concept of mln::Genpixel. + */ + +# include <mln/core/concept/object.hh> + +# include <mln/core/macros.hh> +# include <mln/core/contract.hh> +# include <mln/core/internal/force_exact.hh> + + +namespace mln +{ + + // FIXME: \class GenPixel GenPixel.hh "mln/core/concept/doc/GenPixel.hh" + + /*! \brief Base class for implementation classes that are pixels or that + * have the behavior of pixels. + * + * "GenPixel" is "Generalized Pixel" for short. + * + * \warning This class does \em not derive from mln::Object; it is + * for use as a parallel hierarchy. + * + * \see mln::doc::GenPixel for a complete documentation of this + * class contents. + */ + template <typename E> + struct GenPixel + { + + /* + typedef image; // not const! + typedef psite; + typedef rvalue; + + const image& image() const; + const psite& psite() const; // FIXME ou cpy + + rvalue operator*() const; + + const value* address() const; + */ + + protected: + GenPixel(); + + }; + + /*! \brief Print a generalized pixel \p p into the output stream \p + * ostr. + * + * \param[in,out] ostr An output stream. + * \param[in] p A generalized pixel. + * + * \return The modified output stream \p ostr. + * + * \relates mln::GenPixel + */ + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>& p); + + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename E> + GenPixel<E>::GenPixel() + { + // FIXME +// int dim = E::dim; +// mln_invariant(dim > 0); +// dim = 0; +// typedef mln_point(E) point; +// typedef mln_dpoint(E) dpoint; +// typedef mln_coord(E) coord; +// const point* (E::*m1)() const = & E::pointer; +// m1 = 0; +// coord (E::*m2)(unsigned i) const = & E::operator[]; +// m2 = 0; + } + + + template <typename P> + std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>& pxl) + { + return ostr << pxl.psite() << '@' << & pxl.image(); + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_CONCEPT_GENPIXEL_HH Index: mln/core/internal/force_exact.hh --- mln/core/internal/force_exact.hh (revision 1010) +++ mln/core/internal/force_exact.hh (working copy) @@ -30,11 +30,20 @@ /*! \file mln/core/internal/force_exact.hh * - * \brief Definition of a macro for internal use only. + * \brief Definition of a violent cast for internal use only. + * + * \internal */ -/*! \brief Macro to add a violent exact cast method. + +namespace mln +{ + + namespace internal + { + + /*! \brief Violent cast. * * \internal * @@ -45,18 +54,28 @@ * * \see mln::exact */ - -# define mln_internal_add_force_exact_(Type) \ - \ - E& force_exact_() const \ - { \ - static const E* exact_obj; \ - static const Type& exact_obj_ref = *exact_obj; \ - static const int exact_offset = \ - (const char*)(void*)(&exact_obj_ref) \ - - (const char*)(void*)( exact_obj); \ - return *(E*)((char*)(this) - exact_offset); \ + template <typename E, typename T> + E& force_exact(const T& ref) + { + /* + static const E exact_obj; + static const Type& exact_obj_ref = exact_obj; + static const int exact_offset + (const char*)(void*)(&exact_obj_ref) + - (const char*)(void*)(&exact_obj); + return *(E*)((char*)(this_) - exact_offset); + */ + static const E* exact_obj; + static const T& exact_obj_ref = *exact_obj; + static const int exact_offset + (const char*)(void*)(&exact_obj_ref) + - (const char*)(void*)( exact_obj); + return *(E*)((char*)(&ref) - exact_offset); } + } // end of namespace mln::internal + +} // end of namespace mln + #endif // ! MLN_CORE_INTERNAL_FORCE_EXACT_HH Index: mln/core/internal/coord_impl.hh --- mln/core/internal/coord_impl.hh (revision 1010) +++ mln/core/internal/coord_impl.hh (working copy) @@ -44,13 +44,6 @@ namespace internal { - template <typename E> - struct coord_impl_base_ - { - mln_internal_add_force_exact_(coord_impl_base_<E>) - }; - - // coord_impl /*! \brief Implementation class to equip generalized points with @@ -63,7 +56,6 @@ template <typename C, typename E> struct coord_impl_<1, C, E> - : coord_impl_base_<E> { C ind() const; private: @@ -73,7 +65,6 @@ template <typename C, typename E> struct coord_impl_<2, C, E> - : coord_impl_base_<E> { C row() const; C col() const; @@ -81,7 +72,6 @@ template <typename C, typename E> struct coord_impl_<3, C, E> - : coord_impl_base_<E> { C sli() const; C row() const; @@ -96,7 +86,6 @@ template <typename C, typename E> struct mutable_coord_impl_<1, C, E> - : coord_impl_base_<E> { C ind() const; C& ind(); @@ -104,7 +93,6 @@ template <typename C, typename E> struct mutable_coord_impl_<2, C, E> - : coord_impl_base_<E> { C row() const; C& row(); @@ -114,7 +102,6 @@ template <typename C, typename E> struct mutable_coord_impl_<3, C, E> - : coord_impl_base_<E> { C sli() const; C& sli(); @@ -134,7 +121,7 @@ template <typename C, typename E> C coord_impl_<1, C, E>::ind() const { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } // 2 @@ -142,13 +129,13 @@ template <typename C, typename E> C coord_impl_<2, C, E>::row() const { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C coord_impl_<2, C, E>::col() const { - return this->force_exact_()[1]; + return internal::force_exact<E>(*this)[1]; } // 3 @@ -156,19 +143,19 @@ template <typename C, typename E> C coord_impl_<3, C, E>::sli() const { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C coord_impl_<3, C, E>::row() const { - return this->force_exact_()[1]; + return internal::force_exact<E>(*this)[1]; } template <typename C, typename E> C coord_impl_<3, C, E>::col() const { - return this->force_exact_()[2]; + return internal::force_exact<E>(*this)[2]; } @@ -179,13 +166,13 @@ template <typename C, typename E> C mutable_coord_impl_<1, C, E>::ind() const { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C& mutable_coord_impl_<1, C, E>::ind() { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } // 2 @@ -193,25 +180,25 @@ template <typename C, typename E> C mutable_coord_impl_<2, C, E>::row() const { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C& mutable_coord_impl_<2, C, E>::row() { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C mutable_coord_impl_<2, C, E>::col() const { - return this->force_exact_()[1]; + return internal::force_exact<E>(*this)[1]; } template <typename C, typename E> C& mutable_coord_impl_<2, C, E>::col() { - return this->force_exact_()[1]; + return internal::force_exact<E>(*this)[1]; } // 3 @@ -219,37 +206,37 @@ template <typename C, typename E> C mutable_coord_impl_<3, C, E>::sli() const { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C& mutable_coord_impl_<3, C, E>::sli() { - return this->force_exact_()[0]; + return internal::force_exact<E>(*this)[0]; } template <typename C, typename E> C mutable_coord_impl_<3, C, E>::row() const { - return this->force_exact_()[1]; + return internal::force_exact<E>(*this)[1]; } template <typename C, typename E> C& mutable_coord_impl_<3, C, E>::row() { - return this->force_exact_()[1]; + return internal::force_exact<E>(*this)[1]; } template <typename C, typename E> C mutable_coord_impl_<3, C, E>::col() const { - return this->force_exact_()[2]; + return internal::force_exact<E>(*this)[2]; } template <typename C, typename E> C& mutable_coord_impl_<3, C, E>::col() { - return this->force_exact_()[2]; + return internal::force_exact<E>(*this)[2]; } # endif // ! MLN_INCLUDE_ONLY Index: mln/core/internal/box_impl.hh --- mln/core/internal/box_impl.hh (revision 1010) +++ mln/core/internal/box_impl.hh (working copy) @@ -45,13 +45,6 @@ namespace internal { - template <typename E> - struct box_impl_base_ - { - mln_internal_add_force_exact_(box_impl_base_<E>) - }; - - // box_impl /*! \brief Implementation class to equip objects having a bounding @@ -64,7 +57,6 @@ template <typename C, typename E> // FIXME: Add an extra param to replace 'unsigned'. struct box_impl_<2, C, E> - : box_impl_base_<E> { /// Give the number of rows. unsigned nrows() const; @@ -95,37 +87,37 @@ template <typename C, typename E> unsigned box_impl_<2, C, E>::nrows() const { - return this->force_exact_().bbox().len(0); + return internal::force_exact<E>(*this).bbox().len(0); } template <typename C, typename E> C box_impl_<2, C, E>::min_row() const { - return this->force_exact_().bbox().pmin()[0]; + return internal::force_exact<E>(*this).bbox().pmin()[0]; } template <typename C, typename E> C box_impl_<2, C, E>::max_row() const { - return this->force_exact_().bbox().pmax()[0]; + return internal::force_exact<E>(*this).bbox().pmax()[0]; } template <typename C, typename E> unsigned box_impl_<2, C, E>::ncols() const { - return this->force_exact_().bbox().len(1); + return internal::force_exact<E>(*this).bbox().len(1); } template <typename C, typename E> C box_impl_<2, C, E>::min_col() const { - return this->force_exact_().bbox().pmin()[1]; + return internal::force_exact<E>(*this).bbox().pmin()[1]; } template <typename C, typename E> C box_impl_<2, C, E>::max_col() const { - return this->force_exact_().bbox().pmax()[1]; + return internal::force_exact<E>(*this).bbox().pmax()[1]; } # endif // ! MLN_INCLUDE_ONLY