https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)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