URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-03-08 Frederic Bour <bour(a)lrde.epita.fr>
Add work on meta functions and thru morpher.
* sandbox/fred/fun/abs.hh: New.
* sandbox/fred/fun/cos.hh: New.
* sandbox/fred/fun/fun.cc: New.
Some tests don't pass, see FIXMEs (operator==(rgb::red_t,int) ?)
* sandbox/fred/fun/inc.hh: New.
* sandbox/fred/fun/meta_function.hh: New.
* sandbox/fred/fun/norm.hh: New.
* sandbox/fred/fun/red.hh: New.
* sandbox/fred/fun/thru.cc: New.
* sandbox/fred/fun/thru_morpher.hh: New.
Constness of thru_image has to be corrected.
* sandbox/fred/fun/unary.hh: New.
* sandbox/fred/fun: New.
---
abs.hh | 40 ++++++++
cos.hh | 46 ++++++++++
fun.cc | 103 ++++++++++++++++++++++
inc.hh | 43 +++++++++
meta_function.hh | 132 +++++++++++++++++++++++++++++
norm.hh | 96 +++++++++++++++++++++
red.hh | 44 +++++++++
thru.cc | 30 ++++++
thru_morpher.hh | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
unary.hh | 115 +++++++++++++++++++++++++
10 files changed, 898 insertions(+)
Index: trunk/milena/sandbox/fred/fun/cos.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/cos.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/cos.hh (revision 3498)
@@ -0,0 +1,46 @@
+#ifndef COS_HH
+# define COS_HH
+
+# include "unary.hh"
+# include <mln/value/concept/floating.hh>
+# include <mln/math/acos.hh>
+# include <mln/math/cos.hh>
+
+namespace mln
+{
+ // COS, bijective
+ namespace fun
+ {
+ template <typename T>
+ struct cos : unary<cos, T> {};
+ }
+
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_<fun::cos, mln::value::Floating, T>
+ {
+ typedef set_unary_ ret;
+ typedef T result;
+ typedef T argument;
+ typedef T& lvalue;
+
+ static result read(const argument& x)
+ {
+ return math::cos(x);
+ }
+
+ static void write(lvalue l, const result& x)
+ {
+ l = math::acos(x);
+ }
+ };
+ }
+
+ namespace meta
+ {
+ typedef unary<fun::cos> cos;
+ }
+}
+
+#endif /* ! COS_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/abs.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/abs.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/abs.hh (revision 3498)
@@ -0,0 +1,40 @@
+#ifndef ABS_HH
+# define ABS_HH
+
+# include "unary.hh"
+# include <mln/value/concept/scalar.hh>
+# include <mln/math/abs.hh>
+
+namespace mln
+{
+ // ABS, pure
+ namespace fun
+ {
+ template <typename T>
+ struct abs : unary<abs, T> {};
+ }
+
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_<fun::abs, mln::value::Scalar, T>
+ {
+ typedef set_unary_ ret;
+ typedef T result;
+ typedef T argument;
+ typedef T& lvalue;
+
+ static result read(const argument& x)
+ {
+ return math::abs(x);
+ }
+ };
+ }
+
+ namespace meta
+ {
+ typedef unary<fun::abs> abs;
+ }
+}
+
+#endif /* ! ABS_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/thru.cc
===================================================================
--- trunk/milena/sandbox/fred/fun/thru.cc (revision 0)
+++ trunk/milena/sandbox/fred/fun/thru.cc (revision 3498)
@@ -0,0 +1,30 @@
+// Meta functions test
+#include "cos.hh"
+#include "thru_morpher.hh"
+
+#include <mln/core/image/image2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/all.hh>
+#include <iostream>
+
+#define dbg_print(val) std::cout << #val << "\n\t -> \t"
<< (val) << std::endl
+int main()
+{
+ using namespace mln;
+
+ meta::cos cos;
+ typedef image2d<float> I;
+ I ima(5, 5);
+
+ image2d<value::int_u8> tmp(5, 5);
+ debug::iota(tmp);
+ data::fill_with_image(ima, tmp);
+
+ debug::println(ima);
+ debug::println(thru(meta::cos(), ima));
+
+ thru_image<I, mln::fun::cos<float> > ima2 = thru(meta::cos(), ima);
+ data::fill_with_image(ima2, (pw::value(tmp) - pw::cst(13.0f)) / pw::cst(12.0f) |
tmp.domain());
+
+ debug::println(ima);
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/inc.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/inc.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/inc.hh (revision 3498)
@@ -0,0 +1,43 @@
+#ifndef INC_HH
+# define INC_HH
+
+# include "unary.hh"
+
+namespace mln
+{
+ // INC, bijective
+ namespace fun
+ {
+ template <typename T>
+ struct inc : unary<inc, T> {};
+ }
+
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_<fun::inc, mln::value::Scalar, T>
+ {
+ typedef set_unary_ ret;
+ typedef T result;
+ typedef T argument;
+ typedef T& lvalue;
+
+ static result read(const argument& x)
+ {
+ return x + 1;
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l = r - 1;
+ }
+ };
+ }
+
+ namespace meta
+ {
+ typedef unary<fun::inc> inc;
+ }
+}
+
+#endif /* ! INC_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/red.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/red.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/red.hh (revision 3498)
@@ -0,0 +1,44 @@
+#ifndef RED_HH
+# define RED_HH
+
+# include "unary.hh"
+# include <mln/value/rgb.hh>
+
+namespace mln
+{
+ // RED, assignable
+ namespace fun
+ {
+ template <typename T>
+ struct red : unary<red, T> {};
+ }
+
+ namespace trait
+ {
+ template <unsigned n>
+ struct set_precise_unary_<fun::red, mln::value::rgb<n> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::value::rgb<n> argument;
+ typedef typename argument::red_t result;
+ typedef argument& lvalue;
+
+ static result read(const argument& x)
+ {
+ return x.red();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.red() = r;
+ }
+ };
+ }
+
+ namespace meta
+ {
+ typedef unary<fun::red> red;
+ }
+}
+
+#endif /* ! RED_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/meta_function.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/meta_function.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/meta_function.hh (revision 3498)
@@ -0,0 +1,132 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// 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 F 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_CONCEPT_META_FUNCTION_HH
+# define MLN_CORE_CONCEPT_META_FUNCTION_HH
+
+/// \file mln/core/concept/meta_function.hh
+///
+/// Definition of the concept of mln::Meta_Function.
+
+# include <mln/core/concept/object.hh>
+# include <mln/core/concept/function.hh>
+
+
+# define mln_fun_with(F, T) \
+typename F::template with< T >::ret
+
+# define mln_fun_with_(F, T) \
+F::with< T >::ret
+
+
+# define mln_fun_result(F, T) \
+typename F::template with< T >::ret::result
+
+
+# define mln_fun_result_(F, T) \
+F::with< T >::ret::result
+
+
+
+namespace mln
+{
+
+ // Fwd decl.
+ template <typename E> struct Meta_Function;
+
+ // Meta_Function category flag type.
+ template <>
+ struct Meta_Function<void>
+ {
+ typedef Object<void> super;
+ };
+
+
+ /*! \brief Base class for implementation of meta functions.
+ *
+ * The parameter \a E is the exact type.
+ *
+ * \see mln::doc::Meta_Function for a complete documentation of
+ * this class contents.
+ */
+ template <typename E>
+ struct Meta_Function : public Object<E>
+ {
+ typedef Meta_Function<void> category;
+ protected:
+ Meta_Function();
+ };
+
+
+ namespace fun
+ {
+
+ // To be specialized when some state (attributes) have to be transfered
+ // from the meta-function to the function.
+ // Warning: the first argument has to be an object with the exact type.
+ template <typename M, typename T>
+ mln_fun_with(M, T)
+ unmeta(const M&, T);
+
+ template <typename M, typename T>
+ void
+ unmeta(const Meta_Function<M>&, T); // Safety.
+
+ } // end of namespace mln::fun
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename E>
+ inline
+ Meta_Function<E>::Meta_Function()
+ {
+ // FIXME: Check "with" on E.
+ }
+
+ namespace fun
+ {
+
+ template <typename M, typename T>
+ inline
+ mln_fun_with(M, T)
+ unmeta(const M&, T)
+ {
+ mlc_is_a(M, Meta_Function)::check();
+ mln_fun_with(M, T) a;
+ return a;
+ }
+
+ } // end of namespace mln::fun
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_CONCEPT_META_FUNCTION_HH
Index: trunk/milena/sandbox/fred/fun/norm.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/norm.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/norm.hh (revision 3498)
@@ -0,0 +1,96 @@
+#ifndef NORM_HH
+# define NORM_HH
+
+# include "unary.hh"
+# include <mln/norm/all.hh>
+
+namespace mln
+{
+ // NORMS, reversible
+ namespace fun
+ {
+ namespace norm
+ {
+ template <typename T>
+ struct l1 : unary<l1, T> {};
+
+ template <typename T>
+ struct l2 : unary<l2, T> {};
+
+ template <typename T>
+ struct linfty : unary<linfty, T> {};
+ }
+ }
+
+ namespace trait
+ {
+ template <unsigned n, typename T>
+ struct set_precise_unary_<fun::norm::l1, mln::algebra::vec<n, T> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::algebra::vec<n, T> argument;
+ typedef argument& lvalue;
+ typedef mln_sum_product(argument,argument) result;
+
+ static result read(const argument& x)
+ {
+ return mln::norm::l1(x);
+ }
+
+ static void write(lvalue l, const result& x)
+ {
+ l = l / read(l) * x;
+ }
+ };
+
+ template <unsigned n, typename T>
+ struct set_precise_unary_<fun::norm::l2, mln::algebra::vec<n, T> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::algebra::vec<n, T> argument;
+ typedef argument& lvalue;
+ typedef mln_sum_product(argument,argument) result;
+
+ static result read(const argument& x)
+ {
+ return mln::norm::l2(x);
+ }
+
+ static void write(lvalue l, const result& x)
+ {
+ l = l / read(l) * x;
+ }
+ };
+
+ template <unsigned n, typename T>
+ struct set_precise_unary_<fun::norm::linfty, mln::algebra::vec<n, T> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::algebra::vec<n, T> argument;
+ typedef argument& lvalue;
+ typedef mln_sum_product(argument,argument) result;
+
+ static result read(const argument& x)
+ {
+ return mln::norm::linfty(x);
+ }
+
+ static void write(lvalue l, const result& x)
+ {
+ l = l / read(l) * x;
+ }
+ };
+ }
+
+ namespace meta
+ {
+ namespace norm
+ {
+ typedef unary<fun::norm::l1> l1;
+ typedef unary<fun::norm::l2> l2;
+ typedef unary<fun::norm::linfty> linfty;
+ }
+ }
+}
+
+#endif /* ! NORM_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/fun.cc
===================================================================
--- trunk/milena/sandbox/fred/fun/fun.cc (revision 0)
+++ trunk/milena/sandbox/fred/fun/fun.cc (revision 3498)
@@ -0,0 +1,103 @@
+// Meta functions test
+#include "abs.hh"
+#include "cos.hh"
+#include "inc.hh"
+#include "norm.hh"
+#include "red.hh"
+
+#include <iostream>
+
+#define dbg_print(val) std::cout << #val << "\n\t -> \t"
<< (val) << std::endl
+int main()
+{
+ mln::meta::abs abs;
+ mln::meta::cos cos;
+ mln::meta::inc inc;
+ mln::meta::red red;
+
+ mln::meta::norm::l1 l1;
+ mln::meta::norm::l2 l2;
+ mln::meta::norm::linfty linfty;
+
+ std::cout << "Read only tests." << std::endl;
+ std::cout << "----------------" << std::endl;
+
+ // ABS
+ mln_invariant(abs(-1) == 1);
+ dbg_print(abs(-1));
+ dbg_print(abs(-3.1415926535));
+
+ // INC
+ mln_invariant(inc(-1) == 0);
+ dbg_print(inc(-1));
+ dbg_print(inc(-3.1415926535));
+
+ // COS
+ mln_invariant(cos(0.) == 1.);
+ dbg_print(cos(0.));
+ dbg_print(cos(mln::math::acos(0.5)));
+
+ // RED
+ mln_invariant(red(mln::value::rgb8(8,13,21)) == 8);
+ dbg_print(red(mln::value::rgb8(8,13,21)));
+
+ // NORM
+ mln::algebra::vec<3, double> v;
+ v[0] = 1;
+ v[1] = -1;
+ v[2] = 0;
+ dbg_print(v);
+ dbg_print(l1(v));
+ dbg_print(l2(v));
+ dbg_print(linfty(v));
+
+ std::cout << "Read/Write tests." << std::endl;
+ std::cout << "-----------------" << std::endl;
+
+ // INC
+ {
+ int x;
+ dbg_print(inc(x) = 1);
+ mln_invariant(inc(x) == 1);
+ dbg_print(inc(x));
+ dbg_print(x);
+ }
+
+ // COS
+ {
+ double x;
+ dbg_print(cos(x) = 1.);
+ mln_invariant(cos(x) == 1.);
+ dbg_print(x);
+ }
+
+ // RED
+ {
+ mln::value::rgb8 rgb(8,13,21);
+ dbg_print(rgb);
+ dbg_print(red(rgb) = 0);
+// FIXME: Doesn't compile! mln_invariant(red(rgb) == 0);
+ dbg_print(rgb);
+ }
+
+ // NORM
+ {
+ dbg_print(v);
+ dbg_print(l1(v) = 1.0);
+ dbg_print(l1(v));
+ dbg_print(v);
+// mln_invariant(l1(v) == 1.0); FIXME: check with epsilon
+
+ dbg_print(l2(v) = 1.0);
+ dbg_print(l2(v));
+ dbg_print(v);
+// mln_invariant(l2(v) == 1.0);
+
+ dbg_print(linfty(v) = 1.0);
+ dbg_print(linfty(v));
+ dbg_print(v);
+// mln_invariant(linfty(v) == 1.0);
+ }
+
+ std::cout << "All invariants passed." << std::endl;
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/thru_morpher.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/thru_morpher.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/thru_morpher.hh (revision 3498)
@@ -0,0 +1,249 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// 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 THRU_HH
+# define THRU_HH
+
+# include <mln/core/internal/image_value_morpher.hh>
+# include "meta_function.hh"
+
+// FIXME: constness of thru_image
+
+namespace mln
+{
+
+ // Forward declaration.
+ template <typename I, typename F> struct thru_image;
+
+
+ namespace internal
+ {
+
+ /// Data structure for \c mln::thru_image<I>.
+ template <typename I, typename F>
+ struct data< thru_image<I, F> >
+ {
+ data(I& ima, const F& f);
+
+ I ima_;
+ // FIXME: value or pointer or whatever ?
+ F f_;
+ };
+
+ } // end of namespace mln::internal
+
+
+ namespace trait
+ {
+
+ template <typename I, typename F>
+ struct image_< thru_image<I, F> > : image_< I > // Same as I
except...
+ {
+ // ...these changes.
+ typedef trait::image::category::value_morpher category;
+ typedef mln_internal_trait_image_speed_from(I) speed; // Un-fastest.
+ typedef trait::image::value_access::computed value_access;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ // FIXME: Doc!
+
+ template <typename I, typename F>
+ class thru_image : public internal::image_value_morpher< I, typename F::result,
thru_image<I,F> >
+ {
+ public:
+
+ /// Skeleton.
+ typedef thru_image<tag::image_<I>, F> skeleton;
+
+ /// Point_Site associated type.
+ typedef mln_psite(I) psite;
+
+ /// Value associated type.
+ typedef typename F::result value;
+
+ /// Type returned by the read-write pixel value operator.
+ typedef typename F::lresult lvalue;
+
+ /// Return type of read-only access.
+ typedef typename F::result rvalue;
+
+ thru_image();
+ thru_image(I& ima);
+ thru_image(I& ima, const F& f);
+
+ // Initialize an empty image.
+ void init_(I& ima, const F& f);
+
+ rvalue operator()(const mln_psite(I)& p) const;
+
+ lvalue operator()(const mln_psite(I)& p);
+
+ /// Const promotion via conversion.
+ operator thru_image<const I, F>() const;
+ };
+
+ template <typename I, typename F>
+ thru_image<I, F> thru(const mln::Function<F>& f,
+ Image<I>& ima);
+
+ template <typename I, typename F>
+ thru_image<const I, F> thru(const mln::Function<F>& f,
+ const Image<I>& ima);
+
+ template <typename I, typename M>
+ thru_image<I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, Image<I>& ima);
+
+ template <typename I, typename M>
+ thru_image<const I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, const Image<I>& ima);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // internal::data< thru_image<I,S> >
+
+ namespace internal
+ {
+
+ template <typename I, typename F>
+ inline
+ data< thru_image<I, F> >::data(I& ima, const F& f)
+ : ima_(ima),
+ f_(f)
+ {
+ }
+
+ } // end of namespace mln::internal
+
+ // thru_image<I>
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::thru_image()
+ {
+ }
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::thru_image(I& ima, const F& f)
+ {
+ mln_precondition(ima.is_valid());
+ init_(ima, f);
+ }
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::thru_image(I& ima)
+ {
+ mln_precondition(ima.is_valid());
+ init_(ima, mln_value(I)());
+ }
+
+ template <typename I, typename F>
+ inline
+ void
+ thru_image<I, F>::init_(I& ima, const F& f)
+ {
+ mln_precondition(! this->is_valid());
+ mln_precondition(ima.is_valid());
+ this->data_ = new internal::data< thru_image<I, F> >(ima, f);
+ }
+
+ template <typename I, typename F>
+ inline
+ typename thru_image<I, F>::rvalue
+ thru_image<I, F>::operator()(const mln_psite(I)& p) const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_(this->data_->ima_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ typename thru_image<I, F>::lvalue
+ thru_image<I, F>::operator()(const mln_psite(I)& p)
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->f_(this->data_->ima_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ thru_image<I, F>::operator thru_image<const I, F>() const
+ {
+ thru_image<const I, F> tmp(this->data_->ima_,
this->data_->default_value_);
+ return tmp;
+ }
+
+ // thru
+ template <typename I, typename F>
+ thru_image<I, F> thru(const mln::Function<F>& f,
+ Image<I>& ima)
+ {
+ thru_image<I, F> tmp(exact(ima), exact(f));
+ return tmp;
+ }
+
+ template <typename I, typename F>
+ thru_image<const I, F> thru(const mln::Function<F>& f,
+ const Image<I>& ima)
+ {
+ thru_image<const I, F> tmp(exact(ima), exact(f));
+ return tmp;
+ }
+
+ template <typename I, typename M>
+ thru_image<I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, Image<I>& ima)
+ {
+ typedef mln_fun_with(M, mln_value(I)) F;
+ thru_image<I, F> tmp(exact(ima), F());
+
+ return tmp;
+ }
+
+ template <typename I, typename M>
+ thru_image<const I, mln_fun_with(M, mln_value(I))>
+ thru(const mln::Meta_Function<M>& f, const Image<I>& ima)
+ {
+ typedef mln_fun_with(M, mln_value(I)) F;
+ thru_image<const I, F> tmp(exact(ima), F());
+
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! THRU_HH
Index: trunk/milena/sandbox/fred/fun/unary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/unary.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/unary.hh (revision 3498)
@@ -0,0 +1,115 @@
+#ifndef UNARY_HH
+# define UNARY_HH
+
+# include <mln/trait/solve.hh>
+# include <mln/fun/essential.hh>
+# include <mln/fun/internal/resolve.hh>
+# include "meta_function.hh"
+
+namespace mln
+{
+ // UNARY
+ namespace fun
+ {
+ namespace internal
+ {
+ template <typename Impl>
+ struct unary_modifier
+ {
+ typedef typename Impl::result result;
+ typedef typename Impl::argument argument;
+ typedef typename Impl::lvalue lvalue;
+ typedef unary_modifier lresult;
+
+ // FIXME: argument or lvalue? ~~~
+ unary_modifier(argument& x)
+ : x_(&x)
+ {
+ }
+
+ result to_result() const
+ {
+ return Impl::read(*x_);
+ };
+
+ operator result() const
+ {
+ return to_result();
+ };
+
+ const result& operator = (const result& r) const
+ {
+ Impl::write(*x_, r);
+ return r;
+ }
+
+ private:
+ argument *x_;
+ };
+ }
+
+ template <template <class> class Fun, typename T>
+ struct unary : mln::Function_v2v< Fun<T> >
+ {
+ // FIXME: mln_fun_internal_resolve? Fun<T> is not defined at this point...
+ // so mln_is_a(Fun<T>, Function) won't work.
+ typedef typename mln::trait::solve_unary< Fun, T >::ret impl;
+
+ typedef typename impl::result result;
+ typedef typename impl::argument argument;
+ typedef typename impl::lvalue lvalue;
+ typedef internal::unary_modifier<impl> lresult;
+
+ result operator () (const argument& value) const
+ {
+ return impl::read(value);
+ }
+
+ lresult operator () (argument& value) const
+ {
+ return lresult(value);
+ }
+
+ void set(lvalue l, const result& r) const
+ {
+ impl::write(l, r);
+ }
+ };
+ }
+
+ namespace meta
+ {
+ template <template <class> class F>
+ struct unary : mln::Meta_Function< unary<F> >
+ {
+ template <typename T>
+ typename F<T>::result operator()(const T& v) const
+ {
+ F<T> tmp;
+ return tmp(v);
+ }
+
+ template <typename T>
+ typename F<T>::lresult operator()(T& v) const
+ {
+ F<T> tmp;
+ return tmp(v);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef F<T> ret;
+ };
+ };
+ }
+
+}
+
+template <typename Impl>
+std::ostream& operator << (std::ostream& o, const
mln::fun::internal::unary_modifier<Impl>& m)
+{
+ return o << m.to_result();
+}
+
+#endif /* ! UNARY_HH */
\ No newline at end of file