URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-01 Frederic Bour <bour(a)lrde.epita.fr>
Add exo3 "assignable" functions part, correct other parts.
* rush/exo3/Makefile: Added assignable target.
* rush/exo3/assignable.cc: New.
* rush/exo3/assignable.cc: New.
* rush/exo3/exo3_1.cc: Renamed to...
* rush/exo3/exo3_fun_area.cc: New.
* rush/exo3/exo3_2.cc: Renamed to...
* rush/exo3/exo3_fun_generator.cc: New.
---
Makefile | 10 -
assignable.cc | 251 ++++++++++++++++++++++++++++++++++
exo3_fun_area.cc | 313 ++++++++++++++++++++++++++++++++++++++++++
exo3_fun_generator.cc | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 935 insertions(+), 5 deletions(-)
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_fun_generator.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_fun_generator.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_fun_generator.cc (revision 3452)
@@ -0,0 +1,366 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/trait/all.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+
+namespace exo3
+{
+ // Se code est un peu ... sale, et tente de répondre aux problèmes
+ // techniques apparus lors de la présentation (bonus ?).
+
+ // mln::trait::solve se spécialise pour des template <class T>
+ // en premier paramètre.
+ // Afin de transmettre plusieurs types, on passe par
+ // T = couple<TExact, TAux>. On 'hérite' de la catégorie de TExact.
+ // Utiliser pour le générateur de (méta)fonctions.
+ template <typename TExact, typename TAux>
+ struct couple
+ {
+ typedef TExact Exact;
+ typedef typename mln::category<Exact>::ret category;
+
+ typedef TAux Aux;
+ };
+
+ // Crée un type unique vide pour un type donné, évite une instantation ?!
+ // (inutile probablement, dans le doute...).
+ template <typename U>
+ struct uniq
+ {
+ };
+
+ // Get attribute from attribute "E" exact.
+ template <typename E>
+ typename E::result
+ get_attribute(uniq<E>, const E& exact)
+ {
+ return exact.to_result();
+ }
+
+ // area
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::card<I> >, const
E& exact)
+ {
+ return exact.area();
+ }
+
+ // volume
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::volume<I> >, const
E& exact)
+ {
+ return exact.volume();
+ }
+}
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct from_accu_t;
+ template <typename T> struct solve_from_accu;
+ }
+
+ namespace meta
+ {
+ template <template <class> class A>
+ struct from_accu
+ {
+ template <typename T>
+ typename fun::v2v::from_accu_t< exo3::couple<T, A<T> >
>::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::from_accu_t< exo3::couple<T, A<T> > > f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::from_accu_t< exo3::couple<T, A<T> > > ret;
+ };
+ };
+ }
+ }
+
+ namespace trait
+ {
+ template <typename TE, typename TA>
+ struct set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE, TA>
>
+ {
+ typedef set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE,
TA> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const TE& t1)
+ {
+ return exo3::get_attribute(exo3::uniq<TA>(), t1);
+ }
+ };
+
+ } // mln::trait
+
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T>
+ struct from_accu_t;
+
+ template <typename TE, typename TA>
+ struct from_accu_t< exo3::couple<TE, TA> > : mln::Function_v2v<
from_accu_t< exo3::couple<TE, TA> > >
+ {
+ typedef mln_fun_internal_resolve(from_accu_t) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const TE& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ template <typename A>
+ struct solve_from_accu
+ {
+ // FIXME: Not sure whether inheritance is the right way...
+ // But templated typedef are not currently available.
+ template <typename E>
+ struct ret : from_accu_t< exo3::couple< E, A > >
+ {
+ };
+ };
+ }
+ }
+
+}
+
+namespace exo3
+{
+ template <typename F, typename G>
+ struct functors_compose_
+ : mln::Function_p2v< functors_compose_<F, G> >
+ {
+ typedef typename F::result result;
+
+ functors_compose_() {}
+ functors_compose_(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+}
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename TG, typename TA>
+ struct set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG,
TA> >
+ {
+ typedef set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG,
TA> > ret;
+ typedef exo3::functors_compose_<fun::v2v::from_accu_t<
exo3::couple<typename TG::result, TA> >, TG> result;
+
+ static
+ result
+ exec(const TG& g)
+ {
+ return exo3::functors_compose_<fun::v2v::from_accu_t< exo3::couple<typename
TG::result, TA> >, TG>
+ (fun::v2v::from_accu_t<exo3::couple<typename TG::result, TA> >(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) != p)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+
+ // Surcharger les operateurs uniquement pour les builtins...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les fonctions utilisant
mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm
sharpness minvol minarea (inclusive or)"
+ << std::endl;
+ abort();
+}
+
+int main(int argc, char **argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> I;
+
+ float l_sharpness;
+ unsigned l_minvol;
+ unsigned l_minarea;
+ I input;
+
+ if (argc < 5)
+ usage(argv);
+
+ io::pgm::load(input, argv[1]);
+
+ l_sharpness = atof(argv[2]);
+ l_minvol = atoi(argv[3]);
+ l_minarea = atoi(argv[4]);
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(input, c4(),
+ level::sort_psites_decreasing(input),
+ morpho::attribute::sharpness<I>(), l_sharpness));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::from_accu< mln::morpho::attribute::volume > vol;
+ mln::fun::meta::from_accu< mln::morpho::attribute::card > area;
+
+ io::pbm::save((vol(s) > l_minvol || area(s) > l_minarea) | input.domain(),
"out.pbm");
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_fun_area.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_fun_area.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_fun_area.cc (revision 3452)
@@ -0,0 +1,313 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/trait/all.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct area;
+ }
+
+ /// Meta function for area calculation
+ namespace meta
+ {
+
+ struct area
+ {
+ template <typename T>
+ typename fun::v2v::area<T>::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::area<T> f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::area<T> ret;
+ };
+ };
+
+ } // end of namespace mln::fun::meta
+
+ /// Function for area calculation
+ namespace v2v
+ {
+
+ template <typename T>
+ struct area : mln::Function_v2v< area<T> >
+ {
+ typedef mln_fun_internal_resolve(area) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const T& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ /// Function_p2v composition
+ namespace p2v
+ {
+ template <typename F, typename G>
+ struct composition_t
+ : mln::Function_p2v< composition_t<F, G> >
+ {
+ typedef typename F::result result;
+
+ composition_t() {}
+ composition_t(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+ } // end of namespace mln::fun::p2v
+
+ } // end of namespace mln::fun
+
+ /// fun::v2v::area trait for composition
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_< fun::v2v::area, Accumulator, T >
+ {
+ typedef set_unary_< fun::v2v::area, Accumulator, T > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const T& t1)
+ {
+ return t1.area();
+ }
+ };
+
+ template <typename I>
+ struct set_precise_unary_< fun::v2v::area, mln::morpho::attribute::card<I>
>
+ {
+ typedef set_precise_unary_< fun::v2v::area,
mln::morpho::attribute::card<I> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const mln::morpho::attribute::card<I>& t1)
+ {
+ return t1.to_result();
+ }
+ };
+
+ template <typename G>
+ struct set_unary_<fun::v2v::area, mln::Function_p2v, G>
+ {
+ typedef set_unary_<fun::v2v::area, mln::Function_p2v, G> ret;
+ typedef fun::p2v::composition_t<fun::v2v::area<typename G::result>, G>
result;
+
+ static
+ result
+ exec(const G& g)
+ {
+ return fun::p2v::composition_t<fun::v2v::area<typename G::result>, G>
+ (fun::v2v::area<typename G::result>(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+// for purpose of testing.
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) != p)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+} // end of namespace exo3_filter
+
+namespace exo3_filter
+{
+ // Le but est de surcharger les operateurs uniquement pour les Built_In<>...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les Function<> utilisant
mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.pgm
sharpness minarea maxarea"
+ << std::endl;
+ abort();
+}
+
+int main(int argc, char **argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ typedef image2d<int_u8> I;
+
+ float l_sharpness;
+ unsigned l_minarea;
+ unsigned l_maxarea;
+ I input;
+
+ if (argc < 5)
+ usage(argv);
+
+ io::pgm::load(input, argv[1]);
+
+ l_sharpness = atof(argv[2]);
+ l_minarea = atoi(argv[3]);
+ l_maxarea = atoi(argv[4]);
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(input, c4(),
+ level::sort_psites_decreasing(input),
+ morpho::attribute::sharpness<I>(), l_sharpness));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::area area;
+ io::pbm::save((area(s) > l_minarea && area(s) < l_maxarea) |
input.domain(), "out.pbm");
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/assignable.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/assignable.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/assignable.cc (revision 3452)
@@ -0,0 +1,251 @@
+#include <mln/core/concept/all.hh>
+#include <mln/fun/all.hh>
+#include <mln/trait/all.hh>
+#include <mln/fun/meta/green.hh>
+#include <mln/fun/v2w2v/cos.hh>
+#include <mln/fun/v2w_w2v/norm.hh>
+
+// Main definition, use solve_unary to find "implementation"
+// Usage: assignable< mln::fun::v2w2v::cos<double > cos;
+template <typename F>
+struct assignable : mln::trait::solve_unary<assignable, F>::ret
+{
+};
+
+// Meta for assignable
+// Usage: meta::assignable< mln::fun::v2w2v::cos > meta_cos;
+namespace meta
+{
+ template <template <class> class T>
+ struct assignable
+ {
+ template <typename V>
+ struct with
+ {
+ typedef ::assignable< T<V> > ret;
+ };
+
+ template <typename V>
+ typename with<V>::ret::result
+ operator() (const V& value) const
+ {
+ return typename with<V>::ret()(value);
+ }
+
+ template <typename V>
+ typename with<V>::ret::lresult
+ operator() (V& value) const
+ {
+ return typename with<V>::ret()(value);
+ }
+ };
+
+ template <template <class, class> class T>
+ struct assignable_bin
+ {
+ template <typename V, typename R>
+ struct with
+ {
+ typedef ::assignable< T<V, R> > ret;
+ };
+ };
+};
+
+// Tricks to play with templates
+namespace tricky
+{
+ // Disgusting: used to subsitute only according to certain condition (sfinae)
+ template <typename C1, typename C2 = void,
+ typename C3 = void, typename C4 = void>
+ struct subst_test
+ {
+ typedef void ret;
+ };
+
+ // Reinstantiate a template with another parameter
+ template <typename Tmpl, typename E>
+ struct reinstantiate;
+
+ template <template <class> class Tmpl, typename T, typename E>
+ struct reinstantiate<Tmpl<T>, E>
+ {
+ typedef Tmpl<E> ret;
+ };
+
+ template <typename T, template <class> class>
+ struct if_is_templated;
+
+ template <template <class> class Tmpl, typename M>
+ struct if_is_templated< Tmpl<M>, Tmpl >
+ {
+ };
+}
+
+// Internal namespace for assignable functor
+namespace internal
+{
+ namespace assignable
+ {
+ //
+ template <typename F, typename X, typename V>
+ void
+ compute_inv(const mln::Function_v2w_w2v<F>& f, X& x, const V& v)
+ {
+ x = mln::exact(f).f_1(v, x);
+ };
+
+ template <typename F, typename X, typename V>
+ void
+ compute_inv(const mln::Function_v2w2v<F>& f, X& x, const V& v)
+ {
+ x = mln::exact(f).f_1(v);
+ };
+
+ template <typename F, typename X>
+ struct modifier
+ {
+ modifier(X& x, const F& f)
+ : x_(&x), f_(&f)
+ {
+ }
+
+ operator const X& () const
+ { return *x_; };
+
+ operator X& ()
+ { return *x_; };
+
+ template <typename V>
+ const V& operator= (const V& v)
+ {
+ compute_inv(*f_, *x_, v);
+ return v;
+ }
+
+ private:
+ X *x_;
+ const F* f_;
+ };
+
+ // Solve modifiable type: do we need a modifier or can we directly set thru lvalue ?
+ template <typename F, typename V>
+ struct solve_value
+ {
+ typedef typename F::result ret;
+ };
+
+ template <typename F>
+ struct solve_value<F, typename tricky::subst_test< typename F::value >::ret
>
+ {
+ typedef typename F::value ret;
+ };
+
+ // Solve modifiable type: do we need a modifier or can we directly set thru lvalue ?
+ template <typename F, typename Dummy>
+ struct solve_lresult
+ {
+ typedef modifier<F, typename F::result> ret;
+
+ template <typename V>
+ static inline
+ ret
+ modify(V& value, const F& thru)
+ {
+ return ret(value, thru);
+ }
+ };
+
+ template <typename F>
+ struct solve_lresult<F, typename tricky::subst_test<
tricky::if_is_templated<typename F::F, mln::function> >::ret >
+ {
+ typedef typename F::lresult ret;
+
+ template <typename X>
+ static inline
+ ret
+ modify(X& value, const F& thru)
+ {
+ (void)thru;
+ return mln::function<F>().write(value);
+ }
+ };
+
+ template <typename F>
+ struct function_assign : public tricky::reinstantiate<typename F::category,
function_assign<F> >::ret
+ {
+ typedef F function;
+ typedef typename function::result result;
+ typedef typename solve_value<function, void>::ret value;
+ typedef solve_lresult<function, void> lresult_solve;
+ typedef typename lresult_solve::ret lresult;
+
+ inline
+ result
+ operator() (const value& t) const
+ {
+ return f_.read(t);
+ }
+
+ inline
+ lresult
+ operator() (value& t)
+ {
+ return lresult_solve::modify(t, f_);
+ }
+
+ protected:
+ F f_;
+ };
+ }
+}
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename F>
+ struct set_unary_< ::assignable, Function_v2w2v, F >
+ {
+ typedef ::internal::assignable::function_assign<F> ret;
+ };
+
+ template <typename F>
+ struct set_unary_< ::assignable, Function_v2w_w2v, F >
+ {
+ typedef ::internal::assignable::function_assign<F> ret;
+ };
+
+ };
+
+};
+
+#define print_dbg(expr) std::cout << #expr "\t\t == " << (expr)
<< std::endl
+int main()
+{
+ mln::value::rgb8 p;
+ double x;
+
+ assignable< mln::fun::v2w2v::cos<double> > cos;
+ assignable< mln::meta::red<mln::value::rgb8> > red;
+ assignable< mln::meta::green<mln::value::rgb8> > green;
+ assignable< mln::meta::blue<mln::value::rgb8> > blue;
+
+ meta::assignable< mln::fun::v2w2v::cos > meta_cos;
+ meta::assignable< mln::meta::green > meta_green;
+
+ print_dbg(cos(x) = 0);
+ print_dbg(x);
+ print_dbg(meta_cos(x) = 1);
+ print_dbg(x);
+
+ print_dbg(red(p) = 0);
+ print_dbg(green(p) = 127);
+ print_dbg(blue(p) = 255);
+ print_dbg(p);
+
+ print_dbg(meta_green(p) = 0);
+ print_dbg(p);
+
+};
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/Makefile
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 3451)
+++ trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 3452)
@@ -1,9 +1,9 @@
-TARGETS=exo3_1 exo3_2 inverse
+TARGETS=exo3_fun_area exo3_fun_generator assignable
OLENADIR=../../../../..
MILENADIR=$(OLENADIR)/milena
-CXXFLAGS=-I$(MILENADIR) -I./ -W -Wall -O2
+CXXFLAGS+=-I$(MILENADIR) -I./ -W -Wall -O2
CXX=g++
LD=g++
LDFLAGS=
@@ -11,9 +11,9 @@
all: $(TARGETS)
-exo3_1: exo3_1.o
-exo3_2: exo3_2.o
-inverse: inverse.o
+exo3_fun_area: exo3_fun_area.o
+exo3_fun_generator: exo3_fun_generator.o
+assignable: assignable.o
$(TARGETS):
$(LD) $(LDFLAGS) -o $@ $<