URL:
https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-03-13 Frederic Bour <bour(a)lrde.epita.fr>
fun update: add unary & binary composition.
* milena/sandbox/fred/fun/cos.hh,
* milena/sandbox/fred/fun/abs.hh:
WIP, switching from solve to nsolve.
* milena/sandbox/fred/fun/assignability.hh: New.
Traits to check function properties using sfinae (should be renamed).
* milena/sandbox/fred/fun/binary.hh: New. Binary function
* milena/sandbox/fred/fun/compose.hh: New. Compose function.
* milena/sandbox/fred/fun/composition.hh: New.
Composition result objects definition.
* milena/sandbox/fred/fun/cos.cc: New. Test for composition.
* milena/sandbox/fred/fun/fun.cc: WIP.
* milena/sandbox/fred/fun/meta_function.hh:
Added Meta_Function_v2v and Meta_Function_vv2v categories.
* milena/sandbox/fred/fun/nsolve.hh,
* milena/sandbox/fred/fun/nsolve_binary.hh,
* milena/sandbox/fred/fun/nsolve_unary.hh: New.
Original trait solver modification now based
on typename flag instead of template <class> class
* milena/sandbox/fred/fun/thru_morpher.hh: WIP.
* milena/sandbox/fred/fun/unary.hh: Update & redesign,
especially for composition.
---
abs.hh | 1
assignability.hh | 103 ++++++++++++++++++
binary.hh | 137 ++++++++++++++++++++++++
compose.hh | 71 ++++++++++++
composition.hh | 210 ++++++++++++++++++++++++++++++++++++++
cos.cc | 34 ++++++
cos.hh | 12 +-
fun.cc | 5
meta_function.hh | 71 ++++++++++++
nsolve.hh | 152 +++++++++++++++++++++++++++
nsolve_binary.hh | 302 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
nsolve_unary.hh | 171 +++++++++++++++++++++++++++++++
thru_morpher.hh | 1
unary.hh | 299 +++++++++++++++++++++++++++++++++++++++++++++++-------
14 files changed, 1526 insertions(+), 43 deletions(-)
Index: trunk/milena/sandbox/fred/fun/binary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/binary.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/binary.hh (revision 3519)
@@ -0,0 +1,137 @@
+#ifndef BINARY_HH
+# define BINARY_HH
+
+# include <mln/fun/essential.hh>
+# include "meta_function.hh"
+# include "nsolve.hh"
+# include "assignability.hh"
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace spe
+ {
+
+ // Forward declaration
+ template <typename Fun, typename T1, typename T2>
+ struct binary;
+
+ namespace impl
+ {
+
+ template <typename Fun, typename T1, typename T2>
+ struct binary_impl : mln::Function_v2v< binary<Fun, T1, T2> >
+ {
+ typedef mln_trait_nbinary(Fun, T1, T2) impl;
+
+ typedef typename impl::argument1 argument1;
+ typedef typename impl::argument2 argument2;
+ typedef typename impl::result result;
+
+ binary_impl()
+ : impl_()
+ {
+ }
+
+ binary_impl(const impl& f)
+ : impl_(f)
+ {
+ }
+
+ result operator () (const argument1& a, const argument2& b) const
+ {
+ return this->impl_.read(a, b);
+ }
+
+ protected:
+ impl impl_;
+ };
+
+ } // end of namespace mln::fun::spe::impl
+
+ template <typename Fun, typename T1, typename T2>
+ struct binary
+ : impl::binary_impl<Fun, T1, T2>
+ {
+ typedef impl::binary_impl<Fun, T1, T2> super;
+
+ binary()
+ : super()
+ {
+ }
+
+ binary(const typename super::impl& f)
+ : super(f)
+ {
+ }
+
+ using super::operator();
+ };
+
+ } // end of namespace mln::fun::spe
+
+ template <typename F>
+ struct binary : mln::Meta_Function_vv2v< binary<F> >
+ {
+
+ template <typename T1, typename T2>
+ struct with
+ {
+ typedef spe::binary<F, T1, T2> ret;
+ };
+
+ template <typename T1, typename T2>
+ typename with<T1, T2>::ret::result operator()(const T1& a, const T2&
b) const
+ {
+ typename with<T1, T2>::ret tmp;
+ return tmp(a, b);
+ }
+
+ };
+
+ template <typename F, typename P>
+ struct binary_param: binary<F>
+ {
+ typedef P param;
+
+ binary_param() {};
+ binary_param(const param& p) : p_(p) {};
+
+ void init(const param& p)
+ {
+ p_ = p;
+ }
+
+ param& parameter()
+ {
+ return p_;
+ }
+
+ protected:
+ param p_;
+ };
+
+ template <typename F>
+ struct binary_param<F, F>: binary<F>
+ {
+ typedef F param;
+
+ void init(const param& p)
+ {
+ exact(*this) = p;
+ }
+
+ param& parameter()
+ {
+ return exact(*this);
+ }
+ };
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif /* ! BINARY_HH */
Index: trunk/milena/sandbox/fred/fun/cos.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/cos.hh (revision 3518)
+++ trunk/milena/sandbox/fred/fun/cos.hh (revision 3519)
@@ -11,12 +11,15 @@
// COS, bijective
namespace fun
{
- template <typename T>
- struct cos : unary<cos, T> {};
+ struct cos : unary<cos> {};
}
namespace trait
{
+
+ namespace next
+ {
+
template <typename T>
struct set_unary_<mln::fun::cos, mln::value::Floating, T>
{
@@ -35,12 +38,11 @@
l = math::acos(x);
}
};
+
}
- namespace meta
- {
- typedef unary<mln::fun::cos> cos;
}
+
}
#endif /* ! COS_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/nsolve_unary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/nsolve_unary.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/nsolve_unary.hh (revision 3519)
@@ -0,0 +1,171 @@
+// Copyright (C) 2006, 2008 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 MLN_TRAIT_NSOLVE_UNARY_HH
+# define MLN_TRAIT_NSOLVE_UNARY_HH
+
+/*!
+ * \file mln/trait/solve_unary.hh
+ *
+ * \brief FIXME
+ *
+ *
+ */
+
+# include <mln/core/category.hh>
+# include <mln/core/routine/exact.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include "nsolve.hh"
+
+
+// FIXME: Just for the record (use it...)
+
+# ifndef MLN_DEBUG_TRAITS
+# endif // ! MLN_DEBUG_TRAITS
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ namespace internal
+ {
+
+
+ template < typename Name,
+ typename Category,
+ typename T >
+ struct trait_set_unary_;
+
+ template < typename Name,
+ template <class> class Category, typename _,
+ typename T >
+ struct trait_set_unary_< Name, Category<_>, T >
+ {
+ typedef typename mln::trait::next::set_unary_<Name, Category, T>::ret ret;
+ };
+
+
+ // Fwd decls.
+ template < typename Name,
+ typename Category, typename T >
+ struct get_unary_;
+
+
+ template < typename user_ret, /* != not_found and != undefined */
+ typename Name,
+ typename Category, typename T >
+ struct helper_get_unary_
+ {
+ typedef user_ret ret; // The user has defined 'ret' so we return it.
+ };
+
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_get_unary_< /* user_ret == */ not_found,
+ Name, Category, T >
+ {
+ typedef not_found ret; // End of search due to a blocker; 'ret' is not
found.
+ };
+
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_get_unary_< /* user_ret == */ undefined,
+ Name, Category, T >
+ {
+ typedef typename mln::internal::super_category_< Category, T >::ret
Super_Category;
+ typedef typename get_unary_<Name, Super_Category, T>::ret ret; // No user ret
definition => Recursion.
+ };
+
+
+ template < typename Name,
+ typename Category, typename T >
+ struct get_unary_
+ {
+ typedef typename trait_set_unary_<Name, Category, T>::ret user_ret; // First
get 'user_ret'
+ typedef helper_get_unary_<user_ret, Name, Category, T> helper; // Set the
helper to make a decision.
+ typedef mlc_ret(helper) ret; // Return.
+ };
+
+
+ template < typename precise_ret,
+ typename Name,
+ typename Category, typename T >
+ struct helper_choose_unary_wrt_ /* precise_ret != undefined */
+ {
+ typedef precise_ret ret; // -> A precise ret has
been defined so it is it.
+ };
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_choose_unary_wrt_< /* precise_ret == */ undefined,
+ Name, Category, T >
+ {
+ typedef typename get_unary_<Name, Category, T>::ret ret; // -> Go up into the
category inheritance
+ // to fetch a ret from 'set_unary_'s.
+ };
+
+ template < typename Name,
+ typename Category, typename T >
+ struct helper_solve_unary_
+ {
+ typedef typename set_precise_unary_<Name, T>::ret precise_ret;
+ typedef helper_choose_unary_wrt_< precise_ret, /* undefined or not (?) */
+ Name, Category, T> helper;
+ typedef mlc_ret(helper) ret;
+ };
+
+ } // end of namespace mln::trait::next::internal
+
+
+ template < typename Name,
+ typename T_ >
+ struct solve_unary
+ {
+ typedef mln_exact(T_) T;
+ typedef typename mln::category<T>::ret Category;
+ typedef internal::helper_solve_unary_< Name, Category, T > meta_code;
+ typedef typename meta_code::ret ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NSOLVE_UNARY_HH
Index: trunk/milena/sandbox/fred/fun/meta_function.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/meta_function.hh (revision 3518)
+++ trunk/milena/sandbox/fred/fun/meta_function.hh (revision 3519)
@@ -57,6 +57,8 @@
// Fwd decl.
template <typename E> struct Meta_Function;
+ template <typename E> struct Meta_Function_v2v;
+ template <typename E> struct Meta_Function_vv2v;
// Meta_Function category flag type.
template <>
@@ -81,6 +83,49 @@
Meta_Function();
};
+ /*----------------------.
+ | Unary meta function. |
+ `----------------------*/
+
+ template <>
+ struct Meta_Function_v2v<void> { typedef Meta_Function<void> super; };
+
+ /// Base class for implementation of function-objects from
+ /// value to value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
+ template <typename E>
+ struct Meta_Function_v2v : public Meta_Function<E>
+ {
+ typedef Meta_Function_v2v<void> category;
+
+ protected:
+ Meta_Function_v2v();
+ Meta_Function_v2v(const Meta_Function_v2v&);
+ };
+
+ /*-----------------------.
+ | Binary meta function. |
+ `-----------------------*/
+
+ template <>
+ struct Meta_Function_vv2v<void> { typedef Meta_Function<void> super; };
+
+ /// Base class for implementation of function-objects from
+ /// value to value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
+ template <typename E>
+ struct Meta_Function_vv2v : public Meta_Function<E>
+ {
+ typedef Meta_Function_vv2v<void> category;
+
+ protected:
+ Meta_Function_vv2v();
+ Meta_Function_vv2v(const Meta_Function_vv2v&);
+ };
namespace fun
{
@@ -109,6 +154,32 @@
// FIXME: Check "with" on E.
}
+ template <typename E>
+ inline
+ Meta_Function_v2v<E>::Meta_Function_v2v()
+ {
+ }
+
+ template <typename E>
+ inline
+ Meta_Function_v2v<E>::Meta_Function_v2v(const Meta_Function_v2v<E>&
rhs)
+ : Meta_Function<E>(rhs)
+ {
+ }
+
+ template <typename E>
+ inline
+ Meta_Function_vv2v<E>::Meta_Function_vv2v()
+ {
+ }
+
+ template <typename E>
+ inline
+ Meta_Function_vv2v<E>::Meta_Function_vv2v(const Meta_Function_vv2v<E>&
rhs)
+ : Meta_Function<E>(rhs)
+ {
+ }
+
namespace fun
{
Index: trunk/milena/sandbox/fred/fun/unary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/unary.hh (revision 3518)
+++ trunk/milena/sandbox/fred/fun/unary.hh (revision 3519)
@@ -1,18 +1,23 @@
#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"
+# include "nsolve.hh"
+# include "assignability.hh"
namespace mln
{
- // UNARY
+
namespace fun
{
+
+ // Forward declaration, for composition with unary::operator()(Fun)
+ struct compose;
+
namespace internal
{
+
template <typename Impl>
struct unary_modifier
{
@@ -22,14 +27,14 @@
typedef unary_modifier lresult;
// FIXME: argument or lvalue? ~~~
- unary_modifier(argument& x)
- : x_(&x)
+ unary_modifier(const Impl& impl, argument& x)
+ : x_(&x), impl_(&impl)
{
}
result to_result() const
{
- return Impl::read(*x_);
+ return impl_->read(*x_);
};
operator result() const
@@ -39,89 +44,307 @@
const result& operator = (const result& r) const
{
- Impl::write(*x_, r);
+ impl_->write(*x_, r);
return r;
}
private:
argument *x_;
+ const Impl *impl_;
};
- }
- template <template <class> class Fun, typename T>
- struct unary : mln::Function_v2v< Fun<T> >
+ } // end of namespace mln::fun::internal
+
+ namespace spe
+ {
+
+ // Forward declaration
+ template <typename Fun, typename T>
+ struct unary;
+
+ namespace impl
{
- // 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;
+ template <bool set, typename Fun, typename T>
+ struct unary_impl_set;
+
+ template <typename Fun, typename T>
+ struct unary_impl_set<false, Fun, T> : mln::Function_v2v< unary<Fun, T>
>
+ {
+ typedef mln_trait_nunary(Fun, T) impl;
+
+ typedef typename impl::argument argument;
typedef typename impl::result result;
+ typedef mln_trait_fun_param(impl) param_;
+ typedef mlc_if(mlc_equal(param_, void), impl, param_) init_param;
+
+ unary_impl_set() {}
+
+ unary_impl_set(const init_param& p) : impl_(p) {}
+
+ result operator () (const argument& value) const
+ {
+ return this->impl_.read(value);
+ }
+
+ protected:
+ impl impl_;
+ };
+
+ template <typename Fun, typename T>
+ struct unary_impl_set<true, Fun, T> : unary_impl_set<false, Fun, T>
+ {
+ typedef unary_impl_set<false, Fun, T> super;
+ typedef typename super::impl impl;
+
typedef typename impl::argument argument;
+ typedef typename impl::result result;
typedef typename impl::lvalue lvalue;
typedef internal::unary_modifier<impl> lresult;
- result operator () (const argument& value) const
+ unary_impl_set() {}
+ unary_impl_set(const typename super::init_param& p) : super(p) {}
+
+ void set(lvalue l, const result& r) const
{
- return impl::read(value);
+ this->impl_.write(l, r);
}
lresult operator () (argument& value) const
{
- return lresult(value);
+ return lresult(this->impl_, value);
}
- void set(lvalue l, const result& r) const
+ using super::operator();
+ };
+
+ template <bool set, typename Fun, typename T>
+ struct unary_impl_param;
+
+ template <typename Fun, typename T>
+ struct unary_impl_param<false, Fun, T>
+ : impl::unary_impl_set<mln_trait_fun_is_assignable_(mln_trait_nunary(Fun, T))::value,
Fun, T>
{
- impl::write(l, r);
- }
+ typedef impl::unary_impl_set<mln_trait_fun_is_assignable_(mln_trait_nunary(Fun,
T))::value, Fun, T> super;
+
+ unary_impl_param() {}
+ unary_impl_param(const typename super::init_param& p) : super(p) {}
};
- }
- namespace trait
+ template <typename Fun, typename T>
+ struct unary_impl_param<true, Fun, T>
+ : unary_impl_param<false, Fun, T>
{
+ typedef unary_impl_param<false, Fun, T> super;
- namespace fun
+ unary_impl_param() {}
+ unary_impl_param(const typename super::init_param& p) : super(p) {}
+
+ typedef typename super::param_ param;
+
+ void init(const param& p)
+ {
+ this->impl_.init(p);
+ }
+ };
+
+ } // end of namespace mln::fun::spe::impl
+
+ template <typename Fun, typename T>
+ struct unary
+ : impl::unary_impl_param<mln_trait_fun_is_parametrable_(mln_trait_nunary(Fun,
T))::value, Fun, T>
{
+ typedef impl::unary_impl_param<mln_trait_fun_is_parametrable_(mln_trait_nunary(Fun,
T))::value, Fun, T>
+ super;
+
+ unary() {}
+ unary(const typename super::init_param& p) : super(p) {}
+
+ using super::operator();
+ };
+
+ } // end of namespace mln::fun::spe
- /// Find correct implementation
template <typename F>
- struct is_assignable
+ struct unary;
+
+ namespace internal
+ {
+ template <typename T>
+ struct unary_with {};
+
+ template <bool has_param, typename M, typename T>
+ struct unary_with_param_helper;
+
+ template <typename M, typename T>
+ struct unary_with_param_helper<false, M, T>
+ {
+ typedef mln::fun::spe::unary<M, T> function;
+
+ static function inst(const M&)
+ {
+ return function();
+ };
+
+ };
+
+ template <typename M, typename T>
+ struct unary_with_param_helper<true, M, T>
{
- typedef metal::true_ ret;
+ typedef mln::fun::spe::unary<M, T> function;
+
+ static function inst(const M& m)
+ {
+ return function(m.parameter());
+ };
+
};
+ template <typename M, typename T>
+ struct unary_with_helper :
unary_with_param_helper<mln_trait_fun_is_parametrable_(M)::value, M, T>
+ {
+ typedef unary_with_param_helper<mln_trait_fun_is_parametrable_(M)::value, M, T>
super;
+ typedef typename super::function function;
+
+ static typename function::result call(const M& m, const T& x)
+ {
+ function f(super::inst(m));
+ return f(x);
}
+ static typename function::lresult lcall(const M& m, T& x)
+ {
+ function f(super::inst(m));
+ return f(x);
}
- namespace meta
+ static void set(const M& m, typename function::lvalue v, const T& x)
{
- template <template <class> class F>
- struct unary : mln::Meta_Function< unary<F> >
+ function f(super::inst(m));
+ f.set(v, x);
+ }
+
+ };
+
+ }
+
+ template <typename F>
+ struct unary: mln::Meta_Function_v2v< F >
{
+
+ template <typename T>
+ struct with {
+ typedef mln_trait_nunary(internal::unary_with<F>, T) impl;
+ typedef typename impl::function ret;
+ };
+
template <typename T>
- typename F<T>::result operator()(const T& v) const
+ typename with<T>::ret::result operator()(const T& v) const
{
- F<T> tmp;
- return tmp(v);
+ return with<T>::impl::call(exact(*this), v);
}
template <typename T>
- typename F<T>::lresult operator()(T& v) const
+ typename with<T>::ret::lresult operator()(T& v) const
{
- F<T> tmp;
- return tmp(v);
+ return with<T>::impl::lcall(exact(*this), v);
}
- template <typename T>
- struct with
+ template <typename T, typename R>
+ void set(T& v, const R& r) const
{
- typedef F<T> ret;
+ with<T>::impl::set(exact(*this), v, r);
+ }
+
};
+
+ template <typename F, typename P>
+ struct unary_param: unary<F>
+ {
+ typedef P param;
+
+ unary_param() {};
+ unary_param(const param& p) : p_(p) {};
+
+ void init(const param& p)
+ {
+ p_ = p;
+ }
+
+ param& parameter()
+ {
+ return p_;
+ }
+
+ const param& parameter() const
+ {
+ return p_;
+ }
+
+ protected:
+ param p_;
};
+
+ template <typename F>
+ struct unary_param<F, F>: unary<F>
+ {
+ typedef F param;
+
+ void init(const param& p)
+ {
+ exact(*this) = p;
+ }
+
+ param& parameter()
+ {
+ return exact(*this);
+ }
+
+ const param& parameter() const
+ {
+ return exact(*this);
+ }
+
+ };
+
+ } // end of namespace mln::fun
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ // Any type
+ template <typename F, typename T>
+ struct set_unary_< mln::fun::internal::unary_with<F>, mln::Object, T>
+ {
+ typedef mln::fun::internal::unary_with_helper<F, T> ret;
+ };
+
+ // Meta Function
+ template <typename F, typename G>
+ struct set_unary_< mln::fun::internal::unary_with<F>, mln::Meta_Function,
G>
+ {
+ // FIXME: Workaround for cyclic references (unary -> unary_with -> compose ->
unary)
+ template <typename T>
+ struct identity
+ {
+ typedef T ret;
+ };
+
+ typedef set_unary_ ret;
+ typedef typename identity<mln::fun::compose>::ret::template with<F, G>::ret
function;
+
+ static typename function::result call(const F& f, const G& g)
+ {
+ function tmp;
+ return tmp(f, g);
}
+ };
}
+ }
template <typename Impl>
std::ostream& operator << (std::ostream& o, const
mln::fun::internal::unary_modifier<Impl>& m)
@@ -129,4 +352,6 @@
return o << m.to_result();
}
+} // end of namespace mln
+
#endif /* ! UNARY_HH */
Index: trunk/milena/sandbox/fred/fun/assignability.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/assignability.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/assignability.hh (revision 3519)
@@ -0,0 +1,103 @@
+#ifndef ASSIGNABILITY_HH
+# define ASSIGNABILITY_HH
+
+# include <mln/metal/bexpr.hh>
+# include <mln/metal/if.hh>
+
+#define mln_trait_fun_is_assignable(Fun) typename mln::trait::fun::is_assignable< Fun
>::ret
+#define mln_trait_fun_is_assignable_(Fun) mln::trait::fun::is_assignable< Fun
>::ret
+#define mln_trait_fun_is_assignable__1comma(A, B) mln_trait_fun_is_assignable(A, B)
+#define mln_trait_fun_is_assignable__1comma_(A, B) mln_trait_fun_is_assignable_(A, B)
+
+#define mln_trait_fun_is_parametrable(Fun) typename mln::trait::fun::is_parametrable<
Fun >::ret
+#define mln_trait_fun_is_parametrable_(Fun) mln::trait::fun::is_parametrable< Fun
>::ret
+
+#define mln_trait_fun_lvalue(Fun) typename mln::trait::fun::get_lvalue< Fun >::ret
+#define mln_trait_fun_param(Fun) typename mln::trait::fun::get_param< Fun >::ret
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace fun
+ {
+
+ namespace internal
+ {
+
+ namespace introspect
+ {
+
+ template <typename T>
+ struct except_void_t
+ {
+ typedef void ret;
+ };
+
+ template <>
+ struct except_void_t<void>;
+
+ template <typename T, typename V>
+ struct has_lvalue_t
+ {
+ typedef metal::false_ ret;
+ typedef void type;
+ };
+
+ template <typename T>
+ struct has_lvalue_t<T, typename except_void_t<typename T::lvalue>::ret>
+ {
+ typedef metal::true_ ret;
+ typedef typename T::lvalue type;
+ };
+
+ template <typename T, typename V>
+ struct has_param_t
+ {
+ typedef metal::false_ ret;
+ typedef void type;
+ };
+
+ template <typename T>
+ struct has_param_t<T, typename except_void_t<typename T::param>::ret>
+ {
+ typedef metal::true_ ret;
+ typedef typename T::param type;
+ };
+
+ }
+
+ } // end of namespace mln::trait::fun::internal
+
+ template <typename F>
+ struct is_assignable
+ {
+ typedef typename internal::introspect::has_lvalue_t<F, void>::ret ret;
+ };
+
+ template <typename F>
+ struct is_parametrable
+ {
+ typedef typename internal::introspect::has_param_t<F, void>::ret ret;
+ };
+
+ template <typename F>
+ struct get_lvalue
+ {
+ typedef typename internal::introspect::has_lvalue_t<F, void>::type ret;
+ };
+
+ template <typename F>
+ struct get_param
+ {
+ typedef typename internal::introspect::has_param_t<F, void>::type ret;
+ };
+
+ } // end of namespace mln::trait::fun
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+#endif // ! ASSIGNABILITY_HH
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/composition.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/composition.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/composition.hh (revision 3519)
@@ -0,0 +1,210 @@
+#ifndef COMPOSITION_HH
+# define COMPOSITION_HH
+
+# include "unary.hh"
+# include "binary.hh"
+
+namespace mln
+{
+ // Composition
+ namespace fun
+ {
+
+ namespace internal
+ {
+
+ // Compositions may take this has initialization parameter
+ template <typename F, typename G>
+ struct composition_param
+ {
+ composition_param(const F& f, const G& g) : f_(f), g_(g) {}
+ composition_param() {}
+
+ F f_;
+ G g_;
+ };
+
+ // Composition types...
+ template <template <class> class CatF, typename F,
+ template <class> class CatG, typename G>
+ struct composition;
+
+ // Meta
+ template <typename F, typename G>
+ struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>
+ : mln::fun::unary_param< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G>, composition_param<F, G> >
+ {
+ typedef mln::fun::unary_param< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G>, composition_param<F, G> > super;
+
+ composition() {};
+ composition(const typename super::param& p) : super(p) {};
+
+ typedef composition exact_type;
+ };
+
+ template <typename F, typename G>
+ struct composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>
+ : mln::fun::binary_param< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G>, composition_param<F, G> >
+ {
+ typedef mln::fun::binary_param< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G>, composition_param<F, G> > super;
+
+ composition() {};
+ composition(const typename super::param& p) : super(p) {};
+
+ typedef composition exact_type;
+ };
+
+ // Concrete
+ template <typename F, typename G>
+ struct composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>
+ {
+ typedef mln::fun::spe::unary< composition<mln::Meta_Function_v2v, F,
mln::Function_vv2v, G>, typename G::argument> exact_type;
+ };
+
+ template <typename F, typename G>
+ struct composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>
+ {
+ typedef mln::fun::spe::binary< composition<mln::Meta_Function_v2v, F,
mln::Function_vv2v, G>,
+ typename G::argument1, typename G::argument2> exact_type;
+ };
+
+ // Unary compositions implementation inherit from composition_unary_impl...
+ template <bool has_lvalue, typename F, typename F_spe, typename G, typename
G_spe>
+ struct composition_unary_impl_helper;
+
+ template <typename F, typename F_spe, typename G, typename G_spe>
+ struct composition_unary_impl_helper<false, F, F_spe, G, G_spe>
+ {
+ typedef typename G_spe::argument argument;
+ typedef typename F_spe::result result;
+ typedef composition_param<F, G> param;
+
+ composition_unary_impl_helper() {}
+ composition_unary_impl_helper(const param& p) : f_(p.f_), g_(p.g_) {}
+
+ void init(const param& p)
+ {
+ f_ = p.f_;
+ g_ = p.g_;
+ }
+
+ result read(const argument& x) const
+ {
+ return this->f_(this->g_(x));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+ template <typename F, typename F_spe, typename G, typename G_spe>
+ struct composition_unary_impl_helper<true, F, F_spe, G, G_spe>
+ : composition_unary_impl_helper<false, F, F_spe, G, G_spe>
+ {
+ typedef composition_unary_impl_helper<false, F, F_spe, G, G_spe> super;
+ typedef typename G_spe::lvalue lvalue;
+
+ composition_unary_impl_helper() {}
+ composition_unary_impl_helper(const typename super::param& p) : super(p) {}
+
+ void write(lvalue l, const typename super::result& x) const
+ {
+ typename G_spe::result r(this->g_(l));
+
+ this->f_.set(r, x);
+ this->g_.set(l, r);
+ }
+ };
+
+ template <typename F, typename F_spe, typename G, typename G_spe>
+ struct composition_unary_impl
+ : composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F,
F_spe, G, G_spe>
+ {
+ typedef composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F,
F_spe, G, G_spe> super;
+
+ composition_unary_impl() {}
+ composition_unary_impl(const typename super::param& p) : super(p) {}
+ };
+
+ // Binary compositions implementation inherit from composition_binary_inherit...
+ template <typename F, typename F_spe, typename G, typename G_spe>
+ struct composition_binary_impl
+ {
+ typedef typename G_spe::argument1 argument1;
+ typedef typename G_spe::argument2 argument2;
+ typedef typename F_spe::result result;
+ typedef composition_param<F, G> param;
+
+ composition_binary_impl() {}
+ composition_binary_impl(const param& p) : f_(p.f_), g_(p.g_) {}
+
+ void init(const param& p)
+ {
+ f_ = p.f_;
+ g_ = p.g_;
+ }
+
+ result read(const argument1& a, const argument2& b) const
+ {
+ return this->f_(this->g_(a, b));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+ }
+
+ }
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <typename F, typename G, typename T>
+ struct
set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G>, T>
+ {
+ typedef typename G::template with<T>::ret G_fun;
+ typedef typename F::template with<typename G_fun::result>::ret F_fun;
+
+ typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G_fun> ret;
+ };
+
+ template <typename F, typename G, typename T1, typename T2>
+ struct
set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G>, T1, T2>
+ {
+ typedef typename G::template with<T1, T2>::ret G_fun;
+ typedef typename F::template with<typename G_fun::result>::ret F_fun;
+
+ typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G_fun> ret;
+ };
+
+ template <typename F, typename G>
+ struct
set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F,
mln::Function_v2v, G>,
+ typename G::argument>
+ {
+ typedef typename F::template with<typename G::result>::ret F_fun;
+
+ typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G> ret;
+ };
+
+ template <typename F, typename G>
+ struct
set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G>,
+ typename G::argument1, typename G::argument2>
+ {
+ typedef typename F::template with<typename G::result>::ret F_fun;
+
+ typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G> ret;
+ };
+
+ }
+
+ }
+
+}
+
+#endif /* ! COMPOSITION_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/abs.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/abs.hh (revision 3518)
+++ trunk/milena/sandbox/fred/fun/abs.hh (revision 3519)
@@ -22,7 +22,6 @@
typedef set_unary_ ret;
typedef T result;
typedef T argument;
- typedef T& lvalue;
static result read(const argument& x)
{
Index: trunk/milena/sandbox/fred/fun/compose.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/compose.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/compose.hh (revision 3519)
@@ -0,0 +1,71 @@
+#ifndef COMPOSE_HH
+# define COMPOSE_HH
+
+# include "composition.hh"
+
+namespace mln
+{
+ // Composition
+ namespace fun
+ {
+ struct compose : binary<compose> {};
+
+ namespace internal
+ {
+
+ template <template <class> class CatF, typename F, template <class>
class CatG, typename G>
+ struct compose_helper
+ {
+ typedef F argument1;
+ typedef G argument2;
+
+ typedef typename composition<CatF, F, CatG, G>::exact_type result;
+ typedef typename result::param param;
+
+ static result read(const F& f, const G& g)
+ {
+ return result(param(f, g));
+ }
+ };
+
+ }
+ }
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ // All kinds of supported compositions (meta : unary) with (meta or not : unary or
binary)
+ template <typename F, typename G>
+ struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G>
+ {
+ typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G> ret;
+ };
+
+ template <typename F, typename G>
+ struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G>
+ {
+ typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G> ret;
+ };
+
+ template <typename F, typename G>
+ struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F,
mln::Function_v2v, G>
+ {
+ typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F,
mln::Function_v2v, G> ret;
+ };
+
+ template <typename F, typename G>
+ struct set_binary_< mln::fun::compose, mln::Meta_Function_v2v, F,
mln::Function_vv2v, G>
+ {
+ typedef mln::fun::internal::compose_helper<mln::Meta_Function_v2v, F,
mln::Function_vv2v, G> ret;
+ };
+
+ }
+
+ }
+
+}
+
+#endif /* ! COMPOSE_HH */
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/nsolve.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/nsolve.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/nsolve.hh (revision 3519)
@@ -0,0 +1,152 @@
+// Copyright (C) 2006, 2008 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 MLN_TRAIT_NSOLVE_HH
+# define MLN_TRAIT_NSOLVE_HH
+
+/*!
+ * \file mln/trait/nsolve.hh
+ *
+ * \brief FIXME
+ *
+ *
+ */
+
+# include <mln/core/category.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include <mln/trait/solve.hh>
+
+
+// FIXME: Just for the record (use it...)
+
+# ifndef MLN_DEBUG_TRAITS
+# endif // ! MLN_DEBUG_TRAITS
+
+
+# define mln_trait_nunary(Name, T) typename mln::trait::next::solve_unary< Name, T
>::ret
+# define mln_trait_nunary_(Name, T) mln::trait::next::solve_unary< Name, T
>::ret
+
+# define mln_trait_nbinary(Name, T1, T2) typename mln::trait::next::solve_binary<
Name, T1, T2 >::ret
+# define mln_trait_nbinary_(Name, T1, T2) mln::trait::next::solve_binary<
Name, T1, T2 >::ret
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ // Unary case.
+
+
+ template < typename Name,
+ typename T >
+ struct set_precise_unary_
+ {
+ typedef undefined ret;
+ };
+
+
+ template < typename Name,
+ template <class> class Category_T, typename T >
+ struct set_unary_
+ {
+ typedef undefined ret;
+ };
+
+ template < typename Name,
+ typename T >
+ struct set_unary_< Name, Unknown, T > // Blocker; top of inheritance.
+ {
+ typedef not_found ret;
+ };
+
+
+
+
+ // Binary case.
+
+
+ template < typename Name,
+ typename L,
+ typename R >
+ struct set_precise_binary_
+ {
+ typedef undefined ret;
+ };
+
+
+ template < typename Name,
+ template <class> class Category_L, typename L,
+ template <class> class Category_R, typename R >
+ struct set_binary_
+ {
+ typedef undefined ret;
+ };
+
+ template < typename Name,
+ typename L,
+ template <class> class Category_R, typename R >
+ struct set_binary_< Name, Unknown, L, Category_R, R > // Left blocker.
+ {
+ typedef not_found ret;
+ };
+
+ template < typename Name,
+ template <class> class Category_L, typename L,
+ typename R >
+ struct set_binary_< Name, Category_L, L, Unknown, R > // Right blocker.
+ {
+ typedef not_found ret;
+ };
+
+ template < typename Name,
+ typename L,
+ typename R >
+ struct set_binary_< Name, Unknown, L, Unknown, R > // Blocker.
+ {
+ typedef not_found ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+# include "nsolve_unary.hh"
+# include "nsolve_binary.hh"
+
+
+#endif // ! MLN_TRAIT_NSOLVE_HH
Index: trunk/milena/sandbox/fred/fun/cos.cc
===================================================================
--- trunk/milena/sandbox/fred/fun/cos.cc (revision 0)
+++ trunk/milena/sandbox/fred/fun/cos.cc (revision 3519)
@@ -0,0 +1,34 @@
+// Meta functions test
+#include "cos.hh"
+#include "compose.hh"
+
+#include <iostream>
+
+#define dbg_print(val) std::cout << #val << "\n\t -> \t"
<< (val) << std::endl
+int main()
+{
+ mln::fun::cos cos;
+ mln::fun::compose compose;
+
+ double x;
+ dbg_print(cos(compose)(cos,cos)(x) = 0.857553);
+ dbg_print(x);
+ dbg_print(cos(compose)(cos,cos)(0.));
+
+ // COS
+ {
+ mln_invariant(cos(0.) == 1.);
+ dbg_print(cos(0.));
+ dbg_print(cos(mln::math::acos(0.5)));
+ }
+
+ // COS
+ {
+ double x;
+ dbg_print(cos(x) = 1.);
+ mln_invariant(cos(x) == 1.);
+ dbg_print(x);
+ }
+
+ std::cout << "Ok." << std::endl;
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/fun/nsolve_binary.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/nsolve_binary.hh (revision 0)
+++ trunk/milena/sandbox/fred/fun/nsolve_binary.hh (revision 3519)
@@ -0,0 +1,302 @@
+// Copyright (C) 2006, 2008, 2009 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 MLN_TRAIT_NSOLVE_BINARY_HH
+# define MLN_TRAIT_NSOLVE_BINARY_HH
+
+/// \file mln/trait/solve_binary.hh
+///
+/// FIXME
+
+# include <mln/core/category.hh>
+# include <mln/core/routine/exact.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/ret.hh>
+# include "nsolve.hh"
+
+
+// FIXME: Just for the record (use it...)
+
+# ifndef MLN_DEBUG_TRAITS
+# endif // ! MLN_DEBUG_TRAITS
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ namespace internal
+ {
+
+
+ template < typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct trait_set_binary_;
+
+ template < typename Name,
+ template <class> class Category_L, typename _l, typename L,
+ template <class> class Category_R, typename _r, typename R >
+ struct trait_set_binary_< Name,
+ Category_L<_l>, L,
+ Category_R<_r>, R >
+ {
+ typedef typename mln::trait::next::set_binary_<Name,
+ Category_L, L,
+ Category_R, R>::ret ret;
+ };
+
+
+ // triplet_ret_
+
+ template < unsigned i_L_, unsigned i_R_, typename ret_ >
+ struct triplet_
+ {
+ typedef ret_ ret;
+ };
+
+
+ // merge_triplets_
+
+ template < typename L_trp, typename R_trp >
+ struct merge_triplets_;
+
+ template < unsigned L_i_L, unsigned L_i_R, typename L_ret,
+ unsigned R_i_L, unsigned R_i_R, typename R_ret >
+ struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
+ triplet_<R_i_L, R_i_R, R_ret> >
+ {
+ typedef metal::bool_<(L_i_L <= R_i_L && L_i_R <= R_i_R)> take_L;
+ typedef metal::bool_<(R_i_L <= L_i_L && R_i_R <= L_i_R)> take_R;
+ typedef metal::or_<take_L, take_R> ok;
+ typedef typename metal::if_< metal::and_<ok, take_L>,
+ triplet_<L_i_L, L_i_R, L_ret>,
+ typename metal::if_< metal::and_<ok, take_R>,
+ triplet_<R_i_L, R_i_R, R_ret>,
+ triplet_<0,0, not_found> >::ret >::ret ret;
+ };
+
+ template < unsigned i_L, unsigned i_R, typename LR_ret >
+ struct merge_triplets_< triplet_<i_L, i_R, LR_ret>,
+ triplet_<i_L, i_R, LR_ret> >
+ {
+ typedef triplet_<i_L, i_R, LR_ret> ret;
+ };
+
+
+ template < unsigned L_i_L, unsigned L_i_R, unsigned L_i_max,
+ unsigned R_i_L, unsigned R_i_R, unsigned R_i_max >
+ // L_i_max and R_i_max differ
+ struct helper_merge_triplets_same_ret_
+ {
+ // The winning couple between L_* and R_* is the one which
+ // maximum index is the smallest; for instance, with:
+ // left branch giving L_i_L = 5 and L_i_R = 1 so L_i_max = 5
+ // right branch giving L_i_L = 3 and L_i_R = 4 so R_i_max = 4
+ // the right branch wins.
+ enum { i_L = (L_i_max < R_i_max ? L_i_L : R_i_L),
+ i_R = (L_i_max < R_i_max ? L_i_R : R_i_R) };
+ };
+
+ template < unsigned L_i_L, unsigned L_i_R, unsigned i_max,
+ unsigned R_i_L, unsigned R_i_R >
+ // L_i_max is equal to R_i_max
+ struct helper_merge_triplets_same_ret_< L_i_L, L_i_R, i_max,
+ R_i_L, R_i_R, i_max >
+ {
+ // The winning couple is the one with the minimum index.
+ enum { L_i_min = (L_i_L < L_i_R ? L_i_L : L_i_R),
+ R_i_min = (R_i_L < R_i_R ? R_i_L : R_i_R),
+ i_L = (L_i_min < R_i_min ? L_i_L : R_i_L),
+ i_R = (L_i_min < R_i_min ? L_i_R : R_i_R) };
+ };
+
+
+ template < unsigned L_i_L, unsigned L_i_R, typename LR_ret,
+ unsigned R_i_L, unsigned R_i_R >
+ struct merge_triplets_< triplet_<L_i_L, L_i_R, LR_ret>,
+ triplet_<R_i_L, R_i_R, LR_ret> >
+ {
+ typedef helper_merge_triplets_same_ret_< L_i_L, L_i_R, (L_i_L > L_i_R ? L_i_L :
L_i_R),
+ R_i_L, R_i_R, (R_i_L > R_i_R ? R_i_L : R_i_R) > helper;
+ typedef triplet_<helper::i_L, helper::i_R, LR_ret> ret;
+ };
+
+ template < unsigned L_i_L, unsigned L_i_R, typename L_ret >
+ struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
+ triplet_< 0, 0, not_found> >
+ {
+ typedef triplet_<L_i_L, L_i_R, L_ret> ret;
+ };
+
+ template < unsigned R_i_L, unsigned R_i_R, typename R_ret >
+ struct merge_triplets_< triplet_< 0, 0, not_found>,
+ triplet_<R_i_L, R_i_R, R_ret> >
+ {
+ typedef triplet_<R_i_L, R_i_R, R_ret> ret;
+ };
+
+ template <> // To disambiguate.
+ struct merge_triplets_< triplet_<0, 0, not_found>,
+ triplet_<0, 0, not_found> >
+ {
+ typedef triplet_<0u,0u, not_found> ret;
+ };
+
+
+
+ // Fwd decl.
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct get_binary_;
+
+
+ template < typename user_ret, /* != not_found and != undefined */
+ typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct helper_get_binary_
+ {
+ typedef triplet_< i_L, i_R, user_ret > ret; // The user has defined
'ret' so we return it.
+ };
+
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct helper_get_binary_< /* user_ret == */ not_found,
+ Name, i_L, Category_L, L, i_R, Category_R, R >
+ {
+ typedef triplet_< 0, 0, not_found > ret; // End of search due to a blocker;
'ret' is not found.
+ };
+
+
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct helper_get_binary_< /* user_ret == */ undefined,
+ Name, i_L,Category_L, L, i_R,Category_R, R >
+ {
+ // No user definition for 'ret' so treillis construction in a static recursive
way.
+
+ // FIXME: We *do* need to handle this search with a priority!
+ // FIXME: for a result can be found in both branches...
+
+ typedef typename mln::internal::super_category_< Category_L, L >::ret
Super_Category_L;
+ typedef typename mln::internal::super_category_< Category_R, R >::ret
Super_Category_R;
+
+ typedef get_binary_< Name,
+ i_L + 1, Super_Category_L, L,
+ i_R, Category_R, R > L_branch;
+ typedef mlc_ret(L_branch) L_trp;
+
+ typedef get_binary_< Name,
+ i_L, Category_L, L,
+ i_R + 1, Super_Category_R, R > R_branch;
+ typedef mlc_ret(R_branch) R_trp;
+
+ typedef typename merge_triplets_< L_trp, R_trp >::ret ret;
+ };
+
+
+ template < typename Name,
+ unsigned i_L, typename Category_L, typename L,
+ unsigned i_R, typename Category_R, typename R >
+ struct get_binary_
+ {
+ typedef typename trait_set_binary_<Name, Category_L,L,
+ Category_R,R>::ret user_ret; // First get 'user_ret'
+ typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L,
+ i_R,Category_R,R> helper; // Set the helper to make a decision.
+ typedef mlc_ret(helper) ret; // Return
a triplet.
+ };
+
+
+ template < typename precise_ret,
+ typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_choose_binary_wrt_ /* precise_ret != undefined */
+ {
+ typedef precise_ret ret; // -> A
precise ret has been defined so it is it.
+ };
+
+ template < typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_choose_binary_wrt_< /* precise_ret == */ undefined,
+ Name, Category_L, L, Category_R, R >
+ {
+ typedef typename get_binary_< Name,
+ 0, Category_L, L,
+ 0, Category_R, R >::ret triplet; // Browse upwards the category
inheritance
+ typedef mlc_ret(triplet) ret; // to fetch
ret from 'get_binary_'s.
+ };
+
+
+ template < typename Name,
+ typename Category_L, typename L,
+ typename Category_R, typename R >
+ struct helper_solve_binary_
+ {
+ typedef typename set_precise_binary_<Name, L, R>::ret precise_ret; /* undefined
or not (?) */
+ typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R>
helper;
+ typedef mlc_ret(helper) ret;
+ };
+
+ } // end of namespace mln::trait::internal
+
+
+ // FIXME: Postfix solve_binary with a '-'(?)
+ template < typename Name,
+ typename L_,
+ typename R_ >
+ struct solve_binary
+ {
+ typedef mln_exact(L_) L;
+ typedef mln_exact(R_) R;
+ typedef typename mln::category<L>::ret Category_L;
+ typedef typename mln::category<R>::ret Category_R;
+ typedef internal::helper_solve_binary_< Name, Category_L, L, Category_R, R >
meta_code;
+ typedef typename meta_code::ret ret;
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_NSOLVE_BINARY_HH
Index: trunk/milena/sandbox/fred/fun/fun.cc
===================================================================
--- trunk/milena/sandbox/fred/fun/fun.cc (revision 3518)
+++ trunk/milena/sandbox/fred/fun/fun.cc (revision 3519)
@@ -27,6 +27,10 @@
dbg_print(abs(-1));
dbg_print(abs(-3.1415926535));
+ int x = 1;
+ abs(x) = 2;
+ abs.set(x, 2);
+
// INC
mln_invariant(inc(-1) == 0);
dbg_print(inc(-1));
@@ -48,6 +52,7 @@
v[2] = 0;
dbg_print(v);
dbg_print(l1(v));
+// dbg_print(cos(l1)(v));
dbg_print(l2(v));
dbg_print(linfty(v));
Index: trunk/milena/sandbox/fred/fun/thru_morpher.hh
===================================================================
--- trunk/milena/sandbox/fred/fun/thru_morpher.hh (revision 3518)
+++ trunk/milena/sandbox/fred/fun/thru_morpher.hh (revision 3519)
@@ -135,6 +135,7 @@
public:
/// Type returned by the read-write pixel value operator.
+// typedef typename F::template lresult<typename F::argument>::ret lvalue;
typedef typename F::lresult lvalue;
using thru_image_read<I,F>::operator();