1050: Add 'decorated image' morpher.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add 'decorated image' morpher. * mln/core/decorated_image.hh: New. * mln/core/internal/image_adaptor.hh (adaptee): New. * mln/metal/unconst.hh: New. * mln/metal/vec.hh (vec): New ctors. (operator=): New. * mln/metal/make: New directory. * mln/metal/make/vec.hh: New. * mln/value/proxy: New. * mln/value/stack.hh (helper_stack_image_lvalue_): New. (read_, write_): New. (operator()): Fix. (stack): New overload for n=2 and I mutable. * tests/decorated_image.cc: New. * tests/stack.cc: Augment. mln/core/decorated_image.hh | 208 ++++++++++++++++++++++ mln/core/internal/image_adaptor.hh | 20 ++ mln/core/safe.hh | 2 mln/metal/make/vec.hh | 108 +++++++++++ mln/metal/unconst.hh | 58 ++++++ mln/metal/vec.hh | 33 +++ mln/value/proxy.hh | 335 +++++++++++++++++++++++++++++++++++++ mln/value/stack.hh | 102 +++++++++-- tests/decorated_image.cc | 67 +++++++ tests/stack.cc | 13 - 10 files changed, 927 insertions(+), 19 deletions(-) Index: tests/stack.cc --- tests/stack.cc (revision 1049) +++ tests/stack.cc (working copy) @@ -42,8 +42,13 @@ typedef image2d_b<int> I; - I ima(2, 3); - debug::iota(ima); - debug::println(ima); - debug::println(value::stack(ima, ima)); + box2d b = make::box2d(1, 1); + image2d_b<int> ima5(b), ima1(b); + + point2d p = make::point2d(0, 0); + metal::vec<2, int> v = metal::make::vec(5, 1); + + value::stack(ima5, ima1)(p) = v; + mln_assertion(value::stack(ima5, ima1)(p) = v); + mln_assertion(ima5(p) = 5 && ima1(p) = 1); } Index: tests/decorated_image.cc --- tests/decorated_image.cc (revision 0) +++ tests/decorated_image.cc (revision 0) @@ -0,0 +1,67 @@ +// 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/decorated_image.cc + * + * \brief Tests on mln::decorated_image. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/decorated_image.hh> + + +unsigned count_read = 0, count_write = 0; + +template <typename I> +struct counter +{ + void reading(const I& ima, const mln_psite(I)& p) const + { + ++count_read; + } + void writing(I&, const mln_psite(I)&, const mln_value(I)&) + { + ++count_write; + } +}; + + +int main() +{ + using namespace mln; + + typedef image2d_b<int> I; + I ima(1, 1); + point2d p = make::point2d(0, 0); + + decorated_image< I, counter<I> > ima_ = decorate(ima, counter<I>()); + ima_(p) = ima_(p) = 51; + mln_assertion(count_read = 1 && count_write = 2); + + const I& imac = ima; + decorated_image< const I, counter<I> > cima_ = decorate(imac, counter<I>()); +} Index: mln/core/decorated_image.hh --- mln/core/decorated_image.hh (revision 0) +++ mln/core/decorated_image.hh (revision 0) @@ -0,0 +1,208 @@ +// 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_DECORATED_IMAGE_HH +# define MLN_CORE_DECORATED_IMAGE_HH + +# include <mln/core/internal/image_adaptor.hh> +# include <mln/value/proxy.hh> + + +namespace mln +{ + + // FIXME: Doc! + + template <typename I, typename D> + class decorated_image : public internal::image_adaptor_< I, decorated_image<I,D> > + { + typedef decorated_image<I, D> self_; + typedef internal::image_adaptor_< I, self_ > super_; + public: + + decorated_image(I& ima, const D& deco); + ~decorated_image(); + + typedef mln_value(I) value; + typedef mln::value::proxy<const self_> rvalue; + typedef mln::value::proxy<self_> lvalue; + + rvalue operator()(const mln_psite(I)& p) const; + lvalue operator()(const mln_psite(I)& p); + + mln_value(I) read_(const mln_psite(I)& p) const; + void write_(const mln_psite(I)& p, const mln_value(I)& v); + + template <typename V> + struct change_value + { + typedef decorated_image<mln_ch_value(I, V), D> ret; + }; + + /// Const promotion via convertion. + operator decorated_image<const I, D>() const; + + /// Give the decoration. + const D& decoration() const; + + /// Give the decoration. + D& decoration(); + + protected: + D deco_; + }; + + + + template <typename I, typename D> + decorated_image<I,D> decorate(Image<I>& ima, + const D& decoration); + + template <typename I, typename D> + decorated_image<const I, D> decorate(const Image<I>& ima, + const D& decoration); + + + +# ifndef MLN_INCLUDE_ONLY + + // decorated_image<I,D> + + template <typename I, typename D> + decorated_image<I,D>::decorated_image(I& ima, const D& deco) + : super_(ima), + deco_(deco) + { + } + + template <typename I, typename D> + decorated_image<I,D>::~decorated_image() + { + void (D::*mr)(const I&, const mln_psite(I)&) const = & D::reading; + mr = 0; + typedef mlc_unconst(I) I_; + void (D::*mw)(I_&, const mln_psite(I_)&, const mln_value(I_)&) = & D::writing; + mw = 0; + } + + template <typename I, typename D> + mln::value::proxy< const decorated_image<I,D> > + decorated_image<I,D>::operator()(const mln_psite(I)& p) const + { + rvalue tmp(*this, p); + return tmp; + } + + template <typename I, typename D> + mln::value::proxy< decorated_image<I,D> > + decorated_image<I,D>::operator()(const mln_psite(I)& p) + { + lvalue tmp(*this, p); + return tmp; + } + + namespace internal + { + + template <typename I, typename D> + void + helper_decorated_image_write_(decorated_image<I,D>& ima, + const mln_psite(I)& p, const mln_value(I)& v) + { + ima.decoration().writing(ima.adaptee(), p, v); + ima.adaptee()(p) = v; + } + + template <typename I, typename D> + void + helper_decorated_image_write_(decorated_image<const I,D>&, + const mln_psite(I)&, const mln_value(I)&) + // FIXME: Static assertion instead. + ; + + } // end of namespace mln::internal + + template <typename I, typename D> + void + decorated_image<I,D>::write_(const mln_psite(I)& p, const mln_value(I)& v) + { + internal::helper_decorated_image_write_(*this, p, v); + } + + template <typename I, typename D> + mln_value(I) + decorated_image<I,D>::read_(const mln_psite(I)& p) const + { + deco_.reading(this->adaptee_, p); + return this->adaptee_(p); + } + + template <typename I, typename D> + decorated_image<I,D>::operator decorated_image<const I, D>() const + { + decorated_image<const I, D> tmp(this->adaptee_, deco_); + return tmp; + } + + template <typename I, typename D> + const D& + decorated_image<I,D>::decoration() const + { + return deco_; + } + + template <typename I, typename D> + D& + decorated_image<I,D>::decoration() + { + return deco_; + } + + // decorate + + template <typename I, typename D> + decorated_image<I, D> decorate(Image<I>& ima, + const D& decoration) + { + decorated_image<I, D> tmp(exact(ima), decoration); + return tmp; + } + + template <typename I, typename D> + decorated_image<const I, D> decorate(const Image<I>& ima, + const D& decoration) + { + decorated_image<const I, D> tmp(exact(ima), decoration); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_CORE_DECORATED_IMAGE_HH Index: mln/core/internal/image_adaptor.hh --- mln/core/internal/image_adaptor.hh (revision 1049) +++ mln/core/internal/image_adaptor.hh (working copy) @@ -92,6 +92,12 @@ /// Convertion to the underlying (adapted) image. operator I() const; + /// Give the adaptee (underlying adapted) image. + const I& adaptee() const; + + /// Give the adaptee (underlying adapted) image. + I& adaptee(); + protected: I& adaptee_; @@ -104,6 +110,20 @@ # ifndef MLN_INCLUDE_ONLY template <typename I, typename E, typename S> + const I& + image_adaptor_<I,E,S>::adaptee() const + { + return adaptee_; + } + + template <typename I, typename E, typename S> + I& + image_adaptor_<I,E,S>::adaptee() + { + return adaptee_; + } + + template <typename I, typename E, typename S> image_adaptor_<I,E,S>::image_adaptor_(I& adaptee) : adaptee_(adaptee) { Index: mln/core/safe.hh --- mln/core/safe.hh (revision 1049) +++ mln/core/safe.hh (working copy) @@ -80,7 +80,7 @@ template <typename I> safe_image<I>::safe_image(I& ima, const mln_value(I)& default_value) - : super_(exact(ima)), + : super_(ima), default_value_(default_value) { } Index: mln/metal/unconst.hh --- mln/metal/unconst.hh (revision 0) +++ mln/metal/unconst.hh (revision 0) @@ -0,0 +1,58 @@ +// 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_METAL_UNCONST_HH +# define MLN_METAL_UNCONST_HH + + +# define mlc_unconst(T) typename mln::metal::unconst< T >::ret + + +namespace mln +{ + + namespace metal + { + + template <typename T> + struct unconst + { + typedef T ret; + }; + + template <typename T> + struct unconst< const T > + { + typedef T ret; + }; + + } // end of namespace mln::metal + +} // end of namespace mln + + +#endif // ! MLN_METAL_UNCONST_HH Index: mln/metal/vec.hh --- mln/metal/vec.hh (revision 1049) +++ mln/metal/vec.hh (working copy) @@ -47,6 +47,9 @@ enum { dim = n }; typedef T coord; + vec(); + vec(T (&values)[n]); + T& operator[](unsigned i); T operator[](unsigned i) const; @@ -59,9 +62,25 @@ std::ostream& operator<<(std::ostream& ostr, const vec<n,T>& v); + template <unsigned n, typename T> + bool operator=(const vec<n,T>& lhs, const vec<n,T>& rhs); + + # ifndef MLN_INCLUDE_ONLY template <unsigned n, typename T> + vec<n,T>::vec() + { + } + + template <unsigned n, typename T> + vec<n,T>::vec(T (&values)[n]) + { + for (unsigned i = 0; i < n; ++i) + coord_[i] = values[i]; + } + + template <unsigned n, typename T> T& vec<n,T>::operator[](unsigned i) { @@ -77,6 +96,8 @@ return coord_[i]; } + // operators + template <unsigned n, typename T> std::ostream& operator<<(std::ostream& ostr, const vec<n,T>& v) { @@ -86,6 +107,15 @@ return ostr << ']'; } + template <unsigned n, typename T> + bool operator=(const vec<n,T>& lhs, const vec<n,T>& rhs) + { + for (unsigned i = 0; i < n; ++i) + if (lhs[i] != rhs[i]) + return false; + return true; + } + # endif // ! MLN_INCLUDE_ONLY @@ -94,4 +124,7 @@ } // end of namespace mln +# include <mln/metal/make/vec.hh> + + #endif // ! MLN_CORE_METAL_VEC_HH Index: mln/metal/make/vec.hh --- mln/metal/make/vec.hh (revision 0) +++ mln/metal/make/vec.hh (revision 0) @@ -0,0 +1,108 @@ +// 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_METAL_MAKE_VEC_HH +# define MLN_CORE_METAL_MAKE_VEC_HH + +# include <mln/metal/vec.hh> + + +namespace mln +{ + + namespace metal + { + + namespace make + { + + template <typename T> + mln::metal::vec<1,T> vec(T c0); + + template <typename T> + mln::metal::vec<2,T> vec(T c0, T c1); + + template <typename T> + mln::metal::vec<3,T> vec(T c0, T c1, T c2); + + template <typename T> + mln::metal::vec<4,T> vec(T c0, T c1, T c2, T c3); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename T> + mln::metal::vec<1,T> vec(T c0) + { + mln::metal::vec<1,T> tmp; + tmp[0] = c0; + return tmp; + } + + template <typename T> + mln::metal::vec<2,T> vec(T c0, T c1) + { + mln::metal::vec<2,T> tmp; + tmp[0] = c0; + tmp[1] = c1; + return tmp; + } + + template <typename T> + mln::metal::vec<3,T> vec(T c0, T c1, T c2) + { + mln::metal::vec<3,T> tmp; + tmp[0] = c0; + tmp[1] = c1; + tmp[2] = c2; + return tmp; + } + + template <typename T> + mln::metal::vec<4,T> vec(T c0, T c1, T c2, T c3) + { + mln::metal::vec<4,T> tmp; + tmp[0] = c0; + tmp[1] = c1; + tmp[2] = c2; + tmp[3] = c3; + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::metal::make + + } // end of namespace mln::metal + +} // end of namespace mln + + +# include <mln/metal/make/vec.hh> + + +#endif // ! MLN_CORE_METAL_MAKE_VEC_HH Index: mln/value/proxy.hh --- mln/value/proxy.hh (revision 0) +++ mln/value/proxy.hh (revision 0) @@ -0,0 +1,335 @@ +// 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_PROXY_HH +# define MLN_VALUE_PROXY_HH + +/*! \file mln/value/proxy.hh + * + * \brief Define a generic proxy class for an image pixel value. + */ + +# include <mln/core/concept/value.hh> +# include <mln/value/props.hh> +# include <mln/metal/unconst.hh> + + +namespace mln +{ + + namespace value + { + + + /*! \brief Generic proxy class for an image pixel value. + * + * The parameter \c I is an image type. + */ + template <typename I> + class proxy : public Value< proxy<I> > + { + public: + + /// Encoding associated type. + typedef void enc; // FIXME + + /// Equivalent associated type. + typedef mln_value(I) equiv; + + /// Constructor. + proxy(I& ima, const mln_psite(I)& p); + + /// Destructor. + ~proxy(); + + /// Assignment (write access); general version. + template <typename V> + proxy<I>& operator=(const V& v); + + /// Assignment (write access); replacement for default op. + proxy<I>& operator=(const proxy<I>& rhs); + + /// Assignment (write access); with other proxy. + template <typename II> + proxy<I>& operator=(const proxy<II>& rhs); + + /// Convertion (read access); general version. + template <typename V> + operator V() const; + + /// Convertion (read access); precise version. + operator mln_value(I)() const; + + /// Explicit read access. + mln_value(I) to_value() const; + + protected: + I& ima_; + mln_psite(I) p_; + }; + + + + /*! \brief Generic proxy class for an image pixel value. + * + * The parameter \c I is an image type. + */ + template <typename I> + class proxy< const I > : public Value< proxy<const I> > + { + public: + + /// Encoding associated type. + typedef void enc; // FIXME + + /// Equivalent associated type. + typedef mln_value(I) equiv; + + /// Constructor. + proxy(const I& ima, const mln_psite(I)& p); + + /// Destructor. + ~proxy(); + + /// Convertion (read access); general version. + template <typename V> + operator V() const; + + /// Convertion (read access); precise version. + operator mln_value(I)() const; + + /// Explicit read access. + mln_value(I) to_value() const; + + protected: + const I& ima_; + mln_psite(I) p_; + }; + + + + template <typename I> + bool operator=(const proxy<I>& lhs, const mln_value(I)& rhs); + + template <typename I> + bool operator=(const mln_value(I)& lhs, const proxy<I>& rhs); + + template <typename I, typename J> + bool operator=(const proxy<I>& lhs, const proxy<J>& rhs); + + + template <typename I> + bool operator<(const proxy<I>& lhs, const mln_value(I)& rhs); + + template <typename I> + bool operator<(const mln_value(I)& lhs, const proxy<I>& rhs); + + template <typename I, typename J> + bool operator<(const proxy<I>& lhs, const proxy<J>& rhs); + + + // FIXME: Ops such as +=, etc. + + + + template <typename I> + struct props< proxy<I> > : public props< mln_value(I) > + { + // Contents is inherited. + }; + + + + /*! \brief Print a value proxy \p x into the output stream \p ostr. + * + * \param[in,out] ostr An output stream. + * \param[in] x A value proxy. + * + * \return The modified output stream \p ostr. + */ + template <typename I> + std::ostream& operator<<(std::ostream& ostr, const proxy<I>& x); + + +# ifndef MLN_INCLUDE_ONLY + + // proxy<I> + + template <typename I> + proxy<I>::proxy(I& ima, const mln_psite(I)& p) + : ima_(ima), + p_(p) + { + } + + template <typename I> + proxy<I>::~proxy() + { + mln_value(I) (I::*mr)(const mln_psite(I)&) const = & I::read_; + mr = 0; + void (I::*mw)(const mln_psite(I)&, const mln_value(I)&) = & I::write_; + mw = 0; + } + + template <typename I> + template <typename V> + proxy<I>& + proxy<I>::operator=(const V& v) + { + ima_.write_(p_, v); + return *this; + } + + template <typename I> + proxy<I>& + proxy<I>::operator=(const proxy<I>& rhs) + { + this->operator=(rhs.to_value()); + return *this; + } + + template <typename I> + template <typename II> + proxy<I>& + proxy<I>::operator=(const proxy<II>& rhs) + { + this->operator=(rhs.to_value()); + return *this; + } + + template <typename I> + template <typename V> + proxy<I>::operator V() const + { + return ima_.read_(p_); + } + + template <typename I> + proxy<I>::operator mln_value(I)() const + { + return ima_.read_(p_); + } + + template <typename I> + mln_value(I) + proxy<I>::to_value() const + { + return ima_.read_(p_); + } + + // proxy<const I> + + template <typename I> + proxy<const I>::proxy(const I& ima, const mln_psite(I)& p) + : ima_(ima), + p_(p) + { + } + + template <typename I> + proxy<const I>::~proxy() + { + mln_value(I) (I::*mr)(const mln_psite(I)&) const = & I::read_; + mr = 0; + } + + template <typename I> + template <typename V> + proxy<const I>::operator V() const + { + return ima_.read_(p_); + } + + template <typename I> + proxy<const I>::operator mln_value(I)() const + { + return ima_.read_(p_); + } + + template <typename I> + mln_value(I) + proxy<const I>::to_value() const + { + return ima_.read_(p_); + } + + // operator << + + template <typename I> + std::ostream& operator<<(std::ostream& ostr, const proxy<I>& x) + { + return ostr << x.to_value(); + } + + // operator = + + template <typename I> + bool operator=(const proxy<I>& lhs, const mln_value(I)& rhs) + { + return lhs.to_value() = rhs; + } + + template <typename I> + bool operator=(const mln_value(I)& lhs, const proxy<I>& rhs) + { + return lhs = rhs.to_value(); + } + + template <typename I, typename J> + bool operator=(const proxy<I>& lhs, const proxy<J>& rhs) + { + return lhs.to_value() = rhs.to_value(); + } + + // operator < + + template <typename I> + bool operator<(const proxy<I>& lhs, const mln_value(I)& rhs) + { + return lhs.to_value() < rhs; + } + + template <typename I> + bool operator<(const mln_value(I)& lhs, const proxy<I>& rhs) + { + return lhs < rhs.to_value(); + } + + template <typename I, typename J> + bool operator<(const proxy<I>& lhs, const proxy<J>& rhs) + { + return lhs.to_value() < rhs.to_value(); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_INT_U_HH Index: mln/value/stack.hh --- mln/value/stack.hh (revision 1049) +++ mln/value/stack.hh (working copy) @@ -36,6 +36,7 @@ # include <mln/core/internal/image_base.hh> # include <mln/metal/vec.hh> # include <mln/value/set.hh> +# include <mln/value/proxy.hh> namespace mln @@ -44,6 +45,37 @@ namespace value { + // Fwd decl. + template <unsigned n, typename I> struct stack_image; + + + namespace internal + { + + template <unsigned n, typename I> + struct helper_stack_image_lvalue_ + { + typedef value::proxy< stack_image<n,I> > ret; + static ret make(stack_image<n,I>& ima, const mln_psite(I)& p) + { + ret tmp(ima, p); + return tmp; + } + }; + + template <unsigned n, typename I> + struct helper_stack_image_lvalue_< n, const I > + { + typedef metal::vec<n, mln_value(I)> ret; + static ret make(stack_image<n, const I>& ima, const mln_psite(I)& p) + { + return ima.read_(p); + } + }; + + } // end of namespace mln::value::internal + + /*! \brief FIXME * */ @@ -63,7 +95,7 @@ typedef value rvalue; /// Return type of read-write access. - typedef void lvalue; // FIXME + typedef typename internal::helper_stack_image_lvalue_<n,I>::ret lvalue; /// Value set associated type. typedef mln::value::set<value> vset; @@ -84,9 +116,11 @@ /// Read-only access of pixel value at point site \p p. rvalue operator()(const psite& p) const; + value read_(const psite& p) const; /// Read-write access of pixel value at point site \p p. - void operator()(const psite&); + lvalue operator()(const psite&); + void write_(const psite& p, const value& v); /// Give the set of values of the image. const vset& values() const; @@ -107,20 +141,17 @@ template <typename I> stack_image<2,const I> - stack(const Image<I>& ima1, const Image<I>& ima2) - { - mln_precondition(exact(ima1).domain() = exact(ima2).domain()); - metal::vec<2, const I*> imas; - imas[0] = & exact(ima1); - imas[1] = & exact(ima2); - stack_image<2, const I> tmp(imas); - return tmp; - } + stack(const Image<I>& ima1, const Image<I>& ima2); + template <typename I> + stack_image<2, I> + stack(Image<I>& ima1, Image<I>& ima2); # ifndef MLN_INCLUDE_ONLY + // stack_image<n, I> + template <unsigned n, typename I> stack_image<n,I>::stack_image(const metal::vec<n,I*>& imas) : imas_(imas) @@ -158,7 +189,7 @@ template <unsigned n, typename I> metal::vec<n, mln_value(I)> - stack_image<n,I>::operator()(const psite& p) const + stack_image<n,I>::read_(const psite& p) const { mln_precondition(this->owns_(p)); metal::vec<n, mln_value(I)> tmp; @@ -168,10 +199,27 @@ } template <unsigned n, typename I> + metal::vec<n, mln_value(I)> + stack_image<n,I>::operator()(const psite& p) const + { + return read_(p); + } + + template <unsigned n, typename I> void - stack_image<n,I>::operator()(const psite&) + stack_image<n,I>::write_(const psite& p, const value& v) + { + mln_precondition(this->owns_(p)); + // FIXME!!! + for (unsigned i = 0; i < n; ++i) + imas_[i]->operator()(p) = v[i]; + } + + template <unsigned n, typename I> + typename stack_image<n,I>::lvalue + stack_image<n,I>::operator()(const psite& p) { - mln_invariant(0); // FIXME: Turn into a compile-time error... + return internal::helper_stack_image_lvalue_<n,I>::make(*this, p); } template <unsigned n, typename I> @@ -181,6 +229,32 @@ return vset::the(); } + // stack(..) + + template <typename I> + stack_image<2, const I> + stack(const Image<I>& ima1, const Image<I>& ima2) + { + mln_precondition(exact(ima1).domain() = exact(ima2).domain()); + metal::vec<2, const I*> imas; + imas[0] = & exact(ima1); + imas[1] = & exact(ima2); + stack_image<2, const I> tmp(imas); + return tmp; + } + + template <typename I> + stack_image<2, I> + stack(Image<I>& ima1, Image<I>& ima2) + { + mln_precondition(exact(ima1).domain() = exact(ima2).domain()); + metal::vec<2, I*> imas; + imas[0] = & exact(ima1); + imas[1] = & exact(ima2); + stack_image<2, I> tmp(imas); + return tmp; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::value
participants (1)
-
Thierry Geraud