
2006-11-06 Thierry GERAUD <theo@tegucigalpa.lrde.epita.fr> Add morpher::stack_rw. * olena/tests/morphers/stack_rw_morpher.cc: New. * olena/tests/morphers/Makefile.am: Update. * olena/oln/morpher/stack_rw.hh: New. * olena/oln/Makefile.am: Update. * olena/oln/debug/print.hh (print): Store loop 2D bounds. * olena/oln/core/abstract/functions.hh (fun_rw): New. * olena/oln/morpher/two_way.hh (ima_): Change type to pointer. (two_way): New ctor for class value::two_way. (read_, write_): New methods. (operator, value): Call read_. (operator=): Call write_. * olena/oln/morpher/stack.hh (N): New. * olena/oln/value/two_way.hh (two_way): New ctor decl. (ima_): Change type to pointer. (read_, write_): New method decls. Index: olena/tests/morphers/Makefile.am =================================================================== --- olena/tests/morphers/Makefile.am (revision 694) +++ olena/tests/morphers/Makefile.am (working copy) @@ -24,6 +24,7 @@ count_rw_morpher \ slice_morpher \ stack_morpher \ + stack_rw_morpher \ two_way_morpher \ value_cast \ with_lut \ @@ -36,6 +37,7 @@ count_rw_morpher_SOURCES = count_rw_morpher.cc slice_morpher_SOURCES = slice_morpher.cc stack_morpher_SOURCES = stack_morpher.cc +stack_rw_morpher_SOURCES = stack_rw_morpher.cc two_way_morpher_SOURCES = two_way_morpher.cc value_cast_SOURCES = value_cast.cc with_lut_SOURCES = with_lut.cc Index: olena/tests/morphers/stack_rw_morpher.cc =================================================================== --- olena/tests/morphers/stack_rw_morpher.cc (revision 0) +++ olena/tests/morphers/stack_rw_morpher.cc (revision 0) @@ -0,0 +1,59 @@ +// Copyright (C) 2006 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. + +/// Test the "read-write stack morpher". + +#include <cassert> + +#include <oln/core/traits.hh> +#include <oln/basics2d.hh> +#include <oln/morpher/stack_rw.hh> +#include <oln/debug/print.hh> + + + +int main() +{ + using namespace oln; + using xtd::vec; + using xtd::mk_vec; + + typedef image2d<int> I; + typedef vec<2,int> vec_t; + + I ima_0(3, 3); + I ima_1(3, 3); + point2d p(0,0); + + morpher::stack_rw<2,I> ima_v = stack_rw(ima_0, ima_1); + + ima_v(p) = mk_vec(5, 1); + debug::print(ima_v); + + std::cout << ima_v(p) << std::endl; + std::cout << ima_0(p) << ' ' << ima_1(p) << std::endl; +} Index: olena/oln/debug/print.hh =================================================================== --- olena/oln/debug/print.hh (revision 694) +++ olena/oln/debug/print.hh (working copy) @@ -86,9 +86,15 @@ void print(const abstract::classical_2d_image<I>& input, std::ostream& ostr) { - for (int row = min_row(input); row <= max_row(input); ++row) + const oln_coord(I) + min_row = oln::min_row(input), + max_row = oln::max_row(input); + for (oln_coord(I) row = min_row; row <= max_row; ++row) { - for (int col = min_col(input); col <= max_col(input); ++col) + const oln_coord(I) + min_col = oln::min_col(input), + max_col = oln::max_col(input); + for (oln_coord(I) col = min_col; col <= max_col; ++col) { point2d p(row, col); if (input.has(p)) Index: olena/oln/core/abstract/functions.hh =================================================================== --- olena/oln/core/abstract/functions.hh (revision 694) +++ olena/oln/core/abstract/functions.hh (working copy) @@ -39,9 +39,8 @@ // Fwd decl. - namespace morpher { - template <typename I, typename F> class two_way; - } + namespace morpher { template <typename I, typename F> class two_way; } + namespace value { template <typename I, typename F> class two_way; } namespace abstract @@ -76,14 +75,33 @@ public oln::type { public: + template <typename I> oln::morpher::two_way<I, E> operator()(oln::abstract::mutable_image<I>& input) const; + protected: fun_v2w2v(); }; + // FIXME: Value1 -> Value2 *and* Value2 -> Value1. + + template <typename E> + struct fun_rw : public virtual stc::any__simple<E>, + public oln::type + { + public: + + template <typename I> + oln::morpher::two_way<I, E> + operator()(oln::abstract::mutable_image<I>& input) const; + + protected: + fun_rw(); + }; + + // Point -> Point. template <typename E> @@ -113,6 +131,11 @@ } template <typename E> + fun_rw<E>::fun_rw() + { + } + + template <typename E> fun_p2p<E>::fun_p2p() { } Index: olena/oln/Makefile.am =================================================================== --- olena/oln/Makefile.am (revision 694) +++ olena/oln/Makefile.am (working copy) @@ -190,6 +190,7 @@ morpher/tags.hh \ morpher/slice.hh \ morpher/stack.hh \ + morpher/stack_rw.hh \ morpher/thru_fun.hh \ morpher/thru_mfun.hh \ morpher/two_way.hh \ Index: olena/oln/morpher/two_way.hh =================================================================== --- olena/oln/morpher/two_way.hh (revision 694) +++ olena/oln/morpher/two_way.hh (working copy) @@ -170,18 +170,28 @@ two_way<I,F>::two_way(I& ima, F fun, const oln_psite(I)& p) - : ima_(ima), + : ima_(&ima), fun_(fun), p_(p) { } + // Ctor. + template <typename I, typename F> + two_way<I,F>::two_way(I& ima, + const oln_psite(I)& p) + : ima_(&ima), + fun_(), + p_(p) + { + } + // Read. template <typename I, typename F> template <typename V> two_way<I,F>::operator V() const { - return fun_.direct(ima_(p_)); + return read_(fun_); } // Explicit read. @@ -189,7 +199,7 @@ typename F::result_type two_way<I,F>::value() const { - return fun_.direct(ima_(p_)); + return read_(fun_); } // Write. @@ -199,10 +209,47 @@ two_way<I,F>& two_way<I,F>::operator=(const V& value) { - ima_(p_) = fun_.reverse(value); + write_(fun_, value); return *this; } + // fun_v2w2v + + template <typename I, typename F> + template <typename E, typename V> + void + two_way<I,F>::write_(const oln::abstract::fun_v2w2v<E>& f, const V& value) + { + (*ima_)(p_) = f.exact().reverse(value); + } + + template <typename I, typename F> + template <typename E> + typename E::result_type + two_way<I,F>::read_(const oln::abstract::fun_v2w2v<E>& f) const + { + return f.exact().direct((*ima_)(p_)); + } + + // fun_rw + + template <typename I, typename F> + template <typename E, typename V> + void + two_way<I,F>::write_(const oln::abstract::fun_rw<E>& f, const V& value) + { + f.exact().write(*ima_, p_, value); + } + + template <typename I, typename F> + template <typename E> + typename E::result_type + two_way<I,F>::read_(const oln::abstract::fun_rw<E>& f) const + { + return f.exact().read(*ima_, p_); + } + + // Op <<. template <typename I, typename F> std::ostream& operator<<(std::ostream& ostr, Index: olena/oln/morpher/stack.hh =================================================================== --- olena/oln/morpher/stack.hh (revision 694) +++ olena/oln/morpher/stack.hh (working copy) @@ -82,6 +82,8 @@ public: + enum { N = n }; // FIXME: Hum... + stack(const xtd::vec<n, I>& images); xtd::vec<n, oln_value(I)> impl_op_read(const psite_t& p) const; Index: olena/oln/morpher/stack_rw.hh =================================================================== --- olena/oln/morpher/stack_rw.hh (revision 0) +++ olena/oln/morpher/stack_rw.hh (revision 0) @@ -0,0 +1,248 @@ +// Copyright (C) 2006 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 OLN_MORPHER_STACK_RW_HH +# define OLN_MORPHER_STACK_RW_HH + +# include <xtd/vec.hh> +# include <oln/value/two_way.hh> +# include <oln/morpher/two_way.hh> +# include <oln/morpher/internal/image_value_morpher.hh> + + + +namespace oln +{ + + namespace morpher + { + // Forward declaration. + template <unsigned n, typename I> struct stack_rw; + + } // end of namespace oln::morpher + + + template <unsigned n, typename T> + struct rwvec : public oln::abstract::fun_rw< rwvec<n,T> > + { + typedef xtd::vec<n,T> result_type; + + template <typename I> + xtd::vec<n,T> read(const I& input, const oln_point(I)& p) const + { + return input(p); + } + + template <typename I> + void write(I& input, const oln_point(I)& p, const xtd::vec<n,T>& v) const + { + for (unsigned i = 0; i < I::N; ++i) + input.image(i)(p) = v[i]; + } + }; + + + /// Super type. + template <unsigned n, typename I> + struct set_super_type< morpher::stack_rw<n, I> > + { + typedef morpher::stack_rw<n, I> self_t; + typedef morpher::internal::image_value_morpher<I, self_t> ret; + }; + + template <unsigned n, typename I> + struct vtypes< morpher::stack_rw<n, I> > + { + typedef morpher::stack_rw<n, I> self_t; + typedef rwvec<n, oln_value(I)> fun_t; + public: + typedef mlc::true_ is_computed_type; + typedef xtd::vec<n, oln_value(I)> value_type; + }; + + template <unsigned n, typename I> + struct single_vtype< morpher::stack_rw<n, I>, typedef_::lvalue_type > + { + typedef morpher::stack_rw<n, I> self_t; + typedef rwvec<n, oln_value(I)> fun_t; + typedef value::two_way<self_t, fun_t> ret; + }; + + template <unsigned n, typename I> + struct single_vtype< morpher::stack_rw<n, I>, typedef_::rvalue_type > + { + typedef xtd::vec<n, oln_value(I)> ret; + }; + + + + namespace morpher + { + + /// "Stack of images" morpher with "read-write" capabilities. + + template <unsigned n, typename I> + class stack_rw : public internal::image_value_morpher< I, stack_rw<n, I> > + { + private: + + typedef stack_rw<n, I> self_t; + typedef internal::image_value_morpher<I, self_t> super_t; + + typedef oln_psite(self_t) psite_t; + typedef oln_rvalue(self_t) rvalue_t; + typedef oln_lvalue(self_t) lvalue_t; + + public: + + enum { N = n }; // FIXME: Hum... + + stack_rw(const xtd::vec<n, I>& images); + + xtd::vec<n, oln_value(I)> impl_op_read(const psite_t& p) const; + lvalue_t impl_op_readwrite(const psite_t& p); + + const I& image(unsigned i) const; + I& image(unsigned i); + + protected: + xtd::vec<n, I> images_; + }; + + +# ifndef OLN_INCLUDE_ONLY + + template <unsigned n, typename I> + stack_rw<n, I>::stack_rw(const xtd::vec<n, I>& images) : + super_t(images[0]), + images_(images) + { + } + + template <unsigned n, typename I> + xtd::vec<n, oln_value(I)> + stack_rw<n, I>::impl_op_read(const typename stack_rw<n, I>::psite_t& p) const + { + xtd::vec<n, oln_value(I)> tmp; + for (unsigned i = 0; i < n; ++i) + tmp[i] = images_[i](p); + return tmp; + } + + template <unsigned n, typename I> + typename stack_rw<n, I>::lvalue_t + stack_rw<n, I>::impl_op_readwrite(const typename stack_rw<n, I>::psite_t& p) + { + lvalue_t tmp(*this, p); + return tmp; + } + + template <unsigned n, typename I> + const I& + stack_rw<n, I>::image(unsigned i) const + { + precondition(i < n); + return images_[i]; + } + + template <unsigned n, typename I> + I& + stack_rw<n, I>::image(unsigned i) + { + precondition(i < n); + return images_[i]; + } + +# endif + + } // end of namespace oln::morpher + + + template <typename I> + morpher::stack_rw<2, I> + stack_rw(abstract::mutable_image<I>& image_0, + abstract::mutable_image<I>& image_1); + + template <typename I> + morpher::stack_rw<3, I> + stack_rw(abstract::mutable_image<I>& image_0, + abstract::mutable_image<I>& image_1, + abstract::mutable_image<I>& image_2); + + template <typename I> + morpher::stack_rw<4, I> + stack_rw(abstract::mutable_image<I>& image_0, + abstract::mutable_image<I>& image_1, + abstract::mutable_image<I>& image_2, + abstract::mutable_image<I>& image_3); + + +# ifndef OLN_INCLUDE_ONLY + + + template <typename I> + morpher::stack_rw<2, I> + stack_rw(abstract::mutable_image<I>& image_0, + abstract::mutable_image<I>& image_1) + { + morpher::stack_rw<2, I> tmp(xtd::mk_vec(image_0.exact(), + image_1.exact())); + return tmp; + } + + template <typename I> + morpher::stack_rw<3, I> + stack_rw(abstract::mutable_image<I>& image_0, + abstract::mutable_image<I>& image_1, + abstract::mutable_image<I>& image_2) + { + morpher::stack_rw<3, I> tmp(xtd::mk_vec(image_0.exact(), + image_1.exact(), + image_2.exact())); + return tmp; + } + + template <typename I> + morpher::stack_rw<4, I> + stack_rw(abstract::mutable_image<I>& image_0, + abstract::mutable_image<I>& image_1, + abstract::mutable_image<I>& image_2, + abstract::mutable_image<I>& image_3) + { + morpher::stack_rw<4, I> tmp(xtd::mk_vec(image_0.exact(), + image_1.exact(), + image_2.exact(), + image_3.exact())); + return tmp; + } + +# endif + +} // end of namespace oln + + +#endif // ! OLN_MORPHER_STACK_RW_HH Index: olena/oln/value/two_way.hh =================================================================== --- olena/oln/value/two_way.hh (revision 694) +++ olena/oln/value/two_way.hh (working copy) @@ -50,6 +50,10 @@ two_way(I& ima, F fun, const oln_psite(I)& p); + + // Ctor. + two_way(I& ima, + const oln_psite(I)& p); // Read. template <typename V> @@ -63,9 +67,32 @@ two_way<I,F>& operator=(const V& value); protected: - I ima_; + + I* ima_; F fun_; const oln_psite(I)& p_; + + private: + + // oln::abstract::fun_v2w2v + // Two-way function defined by "direct : v -> w" and "reverse : w -> v". + + template <typename E, typename V> + void write_(const oln::abstract::fun_v2w2v<E>& f, const V& value); + + template <typename E> + typename E::result_type + read_(const oln::abstract::fun_v2w2v<E>& f) const; + + // oln::abstract::fun_rw<E> + // Two-way function defined by "read(ima, p)" and "write(ima, p, v)" + + template <typename E, typename V> + void write_(const oln::abstract::fun_rw<E>& f, const V& value); + + template <typename E> + typename E::result_type + read_(const oln::abstract::fun_rw<E>& f) const; };