
2006-11-06 Thierry GERAUD <theo@tegucigalpa.lrde.epita.fr> Add oln::morpher::two_way_rw. * ChangeLog: Fix file dir in previous entry. * tests/morphers/two_way_rw_morpher.cc: New. * tests/morphers/Makefile.am: Update. * oln/morpher/two_way_rw.hh: New. * oln/Makefile.am: Update. * oln/morpher/two_way.hh (value::two_way): Move impl into... * oln/value/two_way.hxx: ...this new file. * oln/core/abstract/functions.hh (fun_rw): Update. * oln/morpher/count_rw.hh (count_rw): Move impl into guards. * oln/morpher/stack_rw.hh (include): Update. Index: tests/morphers/two_way_rw_morpher.cc =================================================================== --- tests/morphers/two_way_rw_morpher.cc (revision 0) +++ tests/morphers/two_way_rw_morpher.cc (revision 0) @@ -0,0 +1,75 @@ +// 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 "two-way read-write" morpher. + +# include <cassert> + +# include <oln/basics2d.hh> +# include <oln/morpher/two_way_rw.hh> + + + + +struct norm_t : public oln::abstract::fun_rw< norm_t > +{ + typedef float result_type; + + template <typename I> + float read(const I& input, const oln_point(I)& p) const + { + return xtd::L2_norm(input(p)); + } + + template <typename I> + void write(I& input, const oln_point(I)& p, float val) const + { + float old_norm = xtd::L2_norm(input(p)); + assert(old_norm != 0); + input(p) *= val / old_norm; + } +}; + + + +int main() +{ + norm_t norm; + + using namespace oln; + using xtd::vec; + using xtd::mk_vec; + + typedef image2d< vec<2,float> > image_t; + + image_t ima(1, 1); + point2d p(0, 0); + + ima(p) = mk_vec(5,1); + norm(ima)(p) = 1; + assert(xtd::L2_norm(ima(p)) == 1); +} Index: tests/morphers/Makefile.am =================================================================== --- tests/morphers/Makefile.am (revision 695) +++ tests/morphers/Makefile.am (working copy) @@ -26,6 +26,7 @@ stack_morpher \ stack_rw_morpher \ two_way_morpher \ + two_way_rw_morpher \ value_cast \ with_lut \ \ @@ -39,6 +40,7 @@ stack_morpher_SOURCES = stack_morpher.cc stack_rw_morpher_SOURCES = stack_rw_morpher.cc two_way_morpher_SOURCES = two_way_morpher.cc +two_way_rw_morpher_SOURCES = two_way_rw_morpher.cc value_cast_SOURCES = value_cast.cc with_lut_SOURCES = with_lut.cc Index: oln/core/abstract/functions.hh =================================================================== --- oln/core/abstract/functions.hh (revision 695) +++ oln/core/abstract/functions.hh (working copy) @@ -39,7 +39,10 @@ // Fwd decl. - namespace morpher { template <typename I, typename F> class two_way; } + namespace morpher { + template <typename I, typename F> class two_way; + template <typename I, typename F> class two_way_rw; + } namespace value { template <typename I, typename F> class two_way; } @@ -85,7 +88,7 @@ }; - // FIXME: Value1 -> Value2 *and* Value2 -> Value1. + // (Image, Point) -> Value2 *and* (Image, Point, Value2) -> Value1. template <typename E> struct fun_rw : public virtual stc::any__simple<E>, @@ -94,7 +97,7 @@ public: template <typename I> - oln::morpher::two_way<I, E> + oln::morpher::two_way_rw<I, E> operator()(oln::abstract::mutable_image<I>& input) const; protected: Index: oln/Makefile.am =================================================================== --- oln/Makefile.am (revision 695) +++ oln/Makefile.am (working copy) @@ -194,6 +194,7 @@ morpher/thru_fun.hh \ morpher/thru_mfun.hh \ morpher/two_way.hh \ + morpher/two_way_rw.hh \ morpher/value_cast.hh \ morpher/with_lut.hh \ \ @@ -208,6 +209,7 @@ value/rw_counter.hh \ value/tags.hh \ value/two_way.hh \ + value/two_way.hxx \ \ basics1d.hh \ basics2d.hh \ Index: oln/morpher/two_way.hh =================================================================== --- oln/morpher/two_way.hh (revision 695) +++ oln/morpher/two_way.hh (working copy) @@ -159,127 +159,10 @@ } // end of namespace oln::morpher +} // end of namespace oln -# ifndef OLN_INCLUDE_ONLY - namespace value - { +# include <oln/value/two_way.hxx> - // Ctor. - template <typename I, typename F> - two_way<I,F>::two_way(I& ima, - F fun, - const oln_psite(I)& p) - : 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 read_(fun_); - } - - // Explicit read. - template <typename I, typename F> - typename F::result_type - two_way<I,F>::value() const - { - return read_(fun_); - } - - // Write. - - template <typename I, typename F> - template <typename V> - two_way<I,F>& - two_way<I,F>::operator=(const V& 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, - const two_way<I,F>& proxy) - { - return ostr << proxy.value(); - } - - } // end of namespace oln::value - - - namespace abstract - { - - template <typename F> - template <typename I> - oln::morpher::two_way<I, F> - fun_v2w2v<F>::operator()(oln::abstract::mutable_image<I>& input) const - { - morpher::two_way<I, F> tmp(input.exact(), this->exact()); - return tmp; - } - - } // end of namespace oln::abstract - -# endif - - - -} // end of namespace oln - - #endif // ! OLN_MORPHER_TWO_WAY_HH Index: oln/morpher/count_rw.hh =================================================================== --- oln/morpher/count_rw.hh (revision 694) +++ oln/morpher/count_rw.hh (working copy) @@ -143,6 +143,17 @@ template <typename I> morpher::count_rw_<I> + count_rw(oln::abstract::mutable_image<I>& input); + + template <typename I> + morpher::count_rw_<I> + count_rw(const oln::abstract::mutable_image<I>& input); + + +# ifndef OLN_INCLUDE_ONLY + + template <typename I> + morpher::count_rw_<I> count_rw(oln::abstract::mutable_image<I>& input) { morpher::count_rw_<I> tmp(input.exact()); @@ -159,7 +170,9 @@ return tmp; } +# endif + } // end of namespace oln Index: oln/morpher/two_way_rw.hh =================================================================== --- oln/morpher/two_way_rw.hh (revision 0) +++ oln/morpher/two_way_rw.hh (revision 0) @@ -0,0 +1,160 @@ +// 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_TWO_WAY_RW_HH +# define OLN_MORPHER_TWO_WAY_RW_HH + +# include <oln/value/two_way.hh> +# include <oln/morpher/internal/image_value_morpher.hh> + + +namespace oln +{ + + namespace morpher + { + // Forward declaration. + template <typename Image, typename Fun> struct two_way_rw; + + } // end of namespace oln::morpher + + + /// Super type. + template <typename Image, typename Fun> + struct set_super_type< morpher::two_way_rw<Image, Fun> > + { + typedef morpher::two_way_rw<Image, Fun> self_t; + typedef morpher::internal::image_value_morpher<Image, self_t> ret; + }; + + + template <typename Image, typename Fun> + struct vtypes< morpher::two_way_rw<Image, Fun> > + { + typedef morpher::two_way_rw<Image, Fun> self_t; + public: + typedef mlc::true_ is_computed_type; + + typedef typename Fun::result_type value_type; + typedef value::two_way<Image, Fun> lvalue_type; + }; + + template <typename Image, typename Fun> + struct single_vtype< morpher::two_way_rw<Image, Fun>, typedef_::rvalue_type > + { + typedef typename Fun::result_type ret; + }; + + + namespace morpher + { + + /// 'Image thru Function' morpher. + template <typename Image, typename Fun> + class two_way_rw : public internal::image_value_morpher< Image, + morpher::two_way_rw<Image, Fun> > + { + private: + + typedef two_way_rw<Image, Fun> self_t; + + typedef internal::image_value_morpher<Image, self_t> super_t; + using super_t::image_; + + typedef oln_rvalue(self_t) rvalue_t; + typedef oln_lvalue(self_t) lvalue_t; + typedef oln_psite(self_t) psite_t; + + public: + + two_way_rw(oln::abstract::mutable_image<Image>& image); + + two_way_rw(oln::abstract::mutable_image<Image>& image, + const oln::abstract::fun_rw<Fun>& fun); + + rvalue_t impl_op_read(const psite_t& p) const; + lvalue_t impl_op_readwrite(const psite_t& p); + + protected: + + Fun fun_; + }; + + + namespace ERROR + { + + struct FIXME; + + } // end of namespace oln::morpher::ERROR + + +# ifndef OLN_INCLUDE_ONLY + + // public + + template <typename Image, typename Fun> + two_way_rw<Image, Fun>::two_way_rw(oln::abstract::mutable_image<Image>& image) : + super_t(image.exact()), + fun_() + { + } + + template <typename Image, typename Fun> + two_way_rw<Image, Fun>::two_way_rw(oln::abstract::mutable_image<Image>& image, + const oln::abstract::fun_rw<Fun>& fun) : + super_t(image.exact()), + fun_(fun.exact()) + { + } + + template <typename Image, typename Fun> + typename two_way_rw<Image, Fun>::rvalue_t + two_way_rw<Image, Fun>::impl_op_read(const typename two_way_rw<Image, Fun>::psite_t& p) const + { + return fun_.read(this->delegate(), p); + } + + template <typename Image, typename Fun> + typename two_way_rw<Image, Fun>::lvalue_t + two_way_rw<Image, Fun>::impl_op_readwrite(const typename two_way_rw<Image, Fun>::psite_t& p) + { + typename two_way_rw<Image, Fun>::lvalue_t tmp(this->delegate(), p); + return tmp; + } + +# endif + + } // end of namespace oln::morpher + +} // end of namespace oln + + +# include <oln/value/two_way.hxx> + + +#endif // ! OLN_MORPHER_TWO_WAY_RW_HH Index: oln/morpher/stack_rw.hh =================================================================== --- oln/morpher/stack_rw.hh (revision 695) +++ oln/morpher/stack_rw.hh (working copy) @@ -30,7 +30,6 @@ # include <xtd/vec.hh> # include <oln/value/two_way.hh> -# include <oln/morpher/two_way.hh> # include <oln/morpher/internal/image_value_morpher.hh> @@ -245,4 +244,7 @@ } // end of namespace oln +# include <oln/value/two_way.hxx> + + #endif // ! OLN_MORPHER_STACK_RW_HH Index: oln/value/two_way.hxx =================================================================== --- oln/value/two_way.hxx (revision 0) +++ oln/value/two_way.hxx (revision 0) @@ -0,0 +1,168 @@ +// 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_VALUE_TWO_WAY_HXX +# define OLN_VALUE_TWO_WAY_HXX + +# include <oln/value/two_way.hh> + + +# ifndef OLN_INCLUDE_ONLY + +namespace oln +{ + + namespace value + { + + // Ctor. + template <typename I, typename F> + two_way<I,F>::two_way(I& ima, + F fun, + const oln_psite(I)& p) + : 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 read_(fun_); + } + + // Explicit read. + template <typename I, typename F> + typename F::result_type + two_way<I,F>::value() const + { + return read_(fun_); + } + + // Write. + + template <typename I, typename F> + template <typename V> + two_way<I,F>& + two_way<I,F>::operator=(const V& 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, + const two_way<I,F>& proxy) + { + return ostr << proxy.value(); + } + + } // end of namespace oln::value + + + namespace abstract + { + + template <typename F> + template <typename I> + oln::morpher::two_way<I, F> + fun_v2w2v<F>::operator()(oln::abstract::mutable_image<I>& input) const + { + morpher::two_way<I, F> tmp(input.exact(), this->exact()); + return tmp; + } + + template <typename F> + template <typename I> + oln::morpher::two_way_rw<I, F> + fun_rw<F>::operator()(oln::abstract::mutable_image<I>& input) const + { + morpher::two_way_rw<I, F> tmp(input, *this); + return tmp; + } + + } // end of namespace oln::abstract + + +} // end of namespace oln + + +# endif // ! OLN_INCLUDE_ONLY + + +#endif // ! OLN_VALUE_TWO_WAY_HXX