2006-11-06 Thierry GERAUD <theo(a)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;
};