URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-04-06 Frederic Bour <bour(a)lrde.epita.fr>
Clean new fun implementation.
* sandbox/fred/mln/fun/binary.hh,
* sandbox/fred/mln/fun/compose.hh,
* sandbox/fred/mln/fun/composition.hh,
* sandbox/fred/mln/fun/spe/binary.hh,
* sandbox/fred/mln/fun/spe/unary.hh,
* sandbox/fred/mln/fun/unary.hh: Clean and update to make use of
param.hh.
* sandbox/fred/mln/fun/param.hh: New.
* sandbox/fred/mln/trait/fun.hh: Add support for parameter storage.
---
fun/binary.hh | 45 ++++-------
fun/compose.hh | 19 ++++
fun/composition.hh | 68 ++++++-----------
fun/param.hh | 88 ++++++++++++++++++++++
fun/spe/binary.hh | 60 +++++++++++----
fun/spe/unary.hh | 210 ++++++++++++++++++++++++++++-------------------------
fun/unary.hh | 198 ++++++++++---------------------------------------
trait/fun.hh | 87 +++++++++++++++++++++
8 files changed, 437 insertions(+), 338 deletions(-)
Index: trunk/milena/sandbox/fred/mln/trait/fun.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/trait/fun.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/trait/fun.hh (revision 3623)
@@ -30,6 +30,8 @@
# include <mln/metal/bexpr.hh>
# include <mln/metal/if.hh>
+# include <mln/fun/param.hh>
+# include <mln/trait/next/solve.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
@@ -41,6 +43,7 @@
#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
+# define mln_trait_fun_storage(Fun) typename mln::trait::fun::get_storage< Fun
>::ret
namespace mln
{
@@ -66,6 +69,8 @@
template <>
struct except_void_t<void>;
+ // Lvalue solver
+
template <typename T, typename V>
struct has_lvalue_t
{
@@ -80,6 +85,44 @@
typedef typename T::lvalue type;
};
+ // Parameter solver
+ template <typename T, typename V>
+ struct param_solver;
+
+ template <typename T, typename V>
+ struct param_flag_solver
+ {
+ typedef typename mln::fun::parameter<T> ret;
+ };
+
+ template <typename T>
+ struct param_flag_solver<T, typename except_void_t<typename
T::flag>::ret>
+ {
+ typedef typename param_solver<typename T::flag, void>::ret ret;
+ };
+
+ template <typename T, typename V>
+ struct param_def_solver : param_flag_solver<T, V>
+ {
+ };
+
+ template <typename T>
+ struct param_def_solver<T, typename except_void_t<typename T::def>::ret>
+ {
+ typedef typename param_solver<typename T::def, void>::ret ret;
+ };
+
+ template <typename T, typename V>
+ struct param_solver : param_def_solver<T, V>
+ {
+ };
+
+ template <typename T>
+ struct param_solver<T, typename except_void_t<typename T::param>::ret>
+ {
+ typedef T ret;
+ };
+
template <typename T, typename V>
struct has_param_t
{
@@ -88,10 +131,44 @@
};
template <typename T>
- struct has_param_t<T, typename except_void_t<typename T::param>::ret>
+ struct has_param_t<T, typename except_void_t<typename
param_solver<T,void>::ret::param>::ret>
{
typedef metal::true_ ret;
- typedef typename T::param type;
+ typedef typename param_solver<T,void>::ret::param type;
+ };
+
+ template <typename T, typename V>
+ struct has_storage_t
+ {
+ typedef has_param_t<T, V> has_param;
+
+ typedef metal::false_ ret;
+ typedef typename has_param::type type;
+
+ template <typename U>
+ static inline
+ const U& compute(const U& t)
+ {
+ return t;
+ }
+
+ };
+
+ template <typename T>
+ struct has_storage_t<T, typename except_void_t<typename
param_solver<T,void>::ret::storage>::ret>
+ {
+ typedef metal::true_ ret;
+ typedef typename param_solver<T,void>::ret def;
+
+ typedef typename def::storage type;
+
+ template <typename U>
+ static inline
+ type compute(const U& p)
+ {
+ return def::compute(p);
+ };
+
};
} // end of namespace mln::trait::fun::internal::introspect
@@ -122,6 +199,12 @@
typedef typename internal::introspect::has_param_t<F, void>::type ret;
};
+ template <typename F>
+ struct get_storage
+ {
+ typedef typename internal::introspect::has_storage_t<F, void>::type ret;
+ };
+
} // end of namespace mln::trait::fun
} // end of namespace mln::trait
Index: trunk/milena/sandbox/fred/mln/fun/composition.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/composition.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/fun/composition.hh (revision 3623)
@@ -30,6 +30,7 @@
# include <mln/fun/unary.hh>
# include <mln/fun/binary.hh>
+# include <mln/fun/param.hh>
namespace mln
{
@@ -56,27 +57,39 @@
template <class> class CatG, typename G>
struct composition;
+ } // end of namespace mln::fun::internal
+
+ template <template <class> class CatF, typename F,
+ template <class> class CatG, typename G>
+ struct parameter< internal::composition<CatF, F, CatG, G> >
+ {
+ typedef internal::composition_param<F, G> param;
+ };
+
+ namespace internal
+ {
+
// 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> >
+ : mln::fun::unary< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G> >
{
- typedef mln::fun::unary_param< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G>, composition_param<F, G> > super;
+ typedef mln::fun::unary< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_v2v, G> > super;
composition() {};
- composition(const typename super::param& p) : super(p) {};
+ composition(const composition_param<F, G>& 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> >
+ : mln::fun::binary< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G> >
{
- typedef mln::fun::binary_param< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G>, composition_param<F, G> > super;
+ typedef mln::fun::binary< composition<mln::Meta_Function_v2v, F,
mln::Meta_Function_vv2v, G> > super;
composition() {};
- composition(const typename super::param& p) : super(p) {};
+ composition(const composition_param<F, G>& p) : super(p) {};
typedef composition exact_type;
};
@@ -106,23 +119,10 @@
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)
+ static result read(const param& p, const argument& x)
{
- f_ = p.f_;
- g_ = p.g_;
+ return p.f_(p.g_(x));
}
-
- 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>
@@ -135,12 +135,12 @@
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
+ static void write(const typename super::param& p, lvalue l, const typename
super::result& x)
{
- typename G_spe::result r(this->g_(l));
+ typename G_spe::result r(p.g_(l));
- this->f_.set(r, x);
- this->g_.set(l, r);
+ p.f_.set(r, x);
+ p.g_.set(l, r);
}
};
@@ -154,7 +154,6 @@
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
{
@@ -163,23 +162,10 @@
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)
+ static result read(const param& p, const argument1& a, const argument2& b)
{
- f_ = p.f_;
- g_ = p.g_;
+ return p.f_(p.g_(a, b));
}
-
- result read(const argument1& a, const argument2& b) const
- {
- return this->f_(this->g_(a, b));
- }
-
- protected:
- F f_;
- G g_;
};
} // end of namespace mln::fun::internal
Index: trunk/milena/sandbox/fred/mln/fun/binary.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/binary.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/fun/binary.hh (revision 3623)
@@ -42,6 +42,8 @@
template <typename F>
struct binary : mln::Meta_Function_vv2v< binary<F> >
{
+ typedef F flag;
+ typedef mln_trait_fun_storage(flag) storage;
template <typename T1, typename T2>
struct with
@@ -52,48 +54,37 @@
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);
+ return typename with<T1, T2>::ret(storage_)(a, b);
}
- };
-
- template <typename F, typename P>
- struct binary_param: binary<F>
+ template <typename U>
+ void init(const U& value)
{
- typedef P param;
-
- binary_param() {};
- binary_param(const param& p) : p_(p) {};
+ storage_ = mln::trait::fun::internal::introspect::has_storage_t<flag,
void>::compute(value);
+ };
- void init(const param& p)
+ binary()
{
- p_ = p;
}
- param& parameter()
+ template <typename U>
+ binary(const U& param)
{
- return p_;
+ this->init(param);
}
- protected:
- param p_;
- };
-
- template <typename F>
- struct binary_param<F, F>: binary<F>
- {
- typedef F param;
-
- void init(const param& p)
+ stored<storage>& storage_get()
{
- exact(*this) = p;
+ return storage_;
}
- param& parameter()
+ const stored<storage>& storage_get() const
{
- return exact(*this);
+ return storage_;
}
+
+ protected:
+ stored<storage> storage_;
};
} // end of namespace mln::fun
Index: trunk/milena/sandbox/fred/mln/fun/compose.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/compose.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/fun/compose.hh (revision 3623)
@@ -30,6 +30,7 @@
# include <mln/fun/binary.hh>
# include <mln/fun/composition.hh>
+# include <mln/fun/param.hh>
namespace mln
{
@@ -42,13 +43,29 @@
{
template <template <class> class CatF, typename F, template <class>
class CatG, typename G>
+ struct compose_helper;
+
+ }
+
+ template <template <class> class CatF, typename F,
+ template <class> class CatG, typename G>
+ struct parameter< internal::compose_helper<CatF, F, CatG, G> >
+ {
+ typedef typename internal::composition<CatF, F, CatG, G>::exact_type result;
+ typedef typename result::param param;
+ };
+
+ 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;
+ typedef mln_trait_fun_param(result) param;
static result read(const F& f, const G& g)
{
Index: trunk/milena/sandbox/fred/mln/fun/spe/binary.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/spe/binary.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/fun/spe/binary.hh (revision 3623)
@@ -50,50 +50,78 @@
namespace impl
{
+ template <bool has_param, typename Fun, typename T1, typename T2>
+ struct binary_impl;
+
template <typename Fun, typename T1, typename T2>
- struct binary_impl : mln::Function_v2v< binary<Fun, T1, T2> >
+ struct binary_impl<false, Fun, T1, T2>
+ : mln::Function_v2v< binary<Fun, T1, T2> >
{
- typedef mln_trait_nbinary(Fun, T1, T2) impl;
+ typedef Fun flag;
+ typedef mln_trait_nbinary(flag, T1, T2) def;
- typedef typename impl::argument1 argument1;
- typedef typename impl::argument2 argument2;
- typedef typename impl::result result;
+ typedef typename def::argument1 argument1;
+ typedef typename def::argument2 argument2;
+ typedef typename def::result result;
- binary_impl()
- : impl_()
+ result operator () (const argument1& a, const argument2& b) const
{
+ return def::read(a, b);
}
- binary_impl(const impl& f)
- : impl_(f)
+
+ template <typename U>
+ void init(const U& value)
{
}
+ };
+
+ template <typename Fun, typename T1, typename T2>
+ struct binary_impl<true, Fun, T1, T2>
+ : mln::Function_v2v< binary<Fun, T1, T2> >
+ {
+ typedef Fun flag;
+ typedef mln_trait_nbinary(flag, T1, T2) def;
+
+ typedef typename def::argument1 argument1;
+ typedef typename def::argument2 argument2;
+ typedef typename def::result result;
+
+ typedef mln_trait_fun_param(def) param;
+ typedef mln_trait_fun_storage(def) storage;
+
result operator () (const argument1& a, const argument2& b) const
{
- return this->impl_.read(a, b);
+ return def::read(storage_, a, b);
+ }
+
+ template <typename U>
+ void init(const U& value)
+ {
+ storage_ = mln::trait::fun::internal::introspect::has_storage_t<def,
void>::compute(value);
}
protected:
- impl impl_;
+ mln::fun::stored<storage> storage_;
};
} // end of namespace mln::fun::spe::impl
template <typename Fun, typename T1, typename T2>
struct binary
- : impl::binary_impl<Fun, T1, T2>
+ : impl::binary_impl<mln_trait_fun_is_parametrable_(Fun)::value, Fun, T1, T2>
{
- typedef impl::binary_impl<Fun, T1, T2> super;
+ typedef impl::binary_impl<mln_trait_fun_is_parametrable_(Fun)::value, Fun, T1, T2>
super;
binary()
- : super()
{
}
- binary(const typename super::impl& f)
- : super(f)
+ template <typename U>
+ binary(const U& param)
{
+ this->super::init(param);
}
using super::operator();
Index: trunk/milena/sandbox/fred/mln/fun/spe/unary.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/spe/unary.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/fun/spe/unary.hh (revision 3623)
@@ -41,26 +41,23 @@
namespace spe
{
- namespace internal
- {
-
// Wrapper for bijective functions
- template <typename Impl, typename T>
- struct unary_modifier
+ template <typename Fun, typename T>
+ struct lwrapper
{
- typedef typename Impl::result result;
- typedef typename Impl::argument argument;
- typedef typename Impl::lvalue lvalue;
- typedef unary_modifier lresult;
+ typedef typename Fun::result result;
+ typedef typename Fun::argument argument;
+ typedef typename Fun::lvalue lvalue;
+ typedef lwrapper lresult;
- unary_modifier(const Impl& impl, T& x)
- : x_(&x), impl_(&impl)
+ lwrapper(const Fun& f, T& x)
+ : x_(&x), f_(&f)
{
}
result to_result() const
{
- return impl_->read(*x_);
+ return (*f_)(*const_cast<const T*>(x_));
};
operator result() const
@@ -71,7 +68,7 @@
const result& operator = (const result& r) const
{
argument x(*x_);
- impl_->write(x, r);
+ f_->set(x, r);
*x_ = x;
return r;
@@ -79,25 +76,25 @@
private:
T *x_;
- const Impl *impl_;
+ const Fun *f_;
};
- template <typename Impl>
- struct unary_modifier<Impl, typename Impl::argument>
+ template <typename Fun>
+ struct lwrapper<Fun, typename Fun::argument>
{
- typedef typename Impl::result result;
- typedef typename Impl::argument argument;
- typedef typename Impl::lvalue lvalue;
- typedef unary_modifier lresult;
+ typedef typename Fun::result result;
+ typedef typename Fun::argument argument;
+ typedef typename Fun::lvalue lvalue;
+ typedef lwrapper lresult;
- unary_modifier(const Impl& impl, argument& x)
- : x_(&x), impl_(&impl)
+ lwrapper(const Fun& f, argument& x)
+ : x_(&x), f_(&f)
{
}
result to_result() const
{
- return impl_->read(*x_);
+ return (*f_)(*const_cast<const argument*>(x_));
};
operator result() const
@@ -107,33 +104,32 @@
const result& operator = (const result& r) const
{
- impl_->write(*x_, r);
+ f_->set(*x_, r);
return r;
}
private:
argument *x_;
- const Impl *impl_;
+ const Fun *f_;
};
- template <typename Impl, typename Impl2, typename T>
- struct unary_modifier<Impl, unary_modifier<Impl2, T> >
+ template <typename Fun, typename Any, typename T>
+ struct lwrapper<Fun, lwrapper<Any, T> >
{
- typedef typename Impl::result result;
- typedef typename Impl::argument argument;
- typedef typename Impl::lvalue lvalue;
- typedef unary_modifier lresult;
+ typedef typename Fun::result result;
+ typedef typename Fun::argument argument;
+ typedef typename Fun::lvalue lvalue;
+ typedef lwrapper lresult;
- // FIXME: "argument& x" or "lvalue x" directly? ~~~
- unary_modifier(const Impl& impl, const unary_modifier<Impl2, T>& m)
- : m_(m), impl_(&impl)
+ lwrapper(const Fun& f, const lwrapper<Any, T>& m)
+ : m_(m), f_(&f)
{
}
result to_result() const
{
- return impl_->read(m_.to_result());
+ return (*f_)(m_.to_result());
};
operator result() const
@@ -144,113 +140,125 @@
const result& operator = (const result& r) const
{
argument m(m_);
- impl_->write(m, r);
+ f_->set(m, r);
m_ = m;
return r;
}
private:
- const unary_modifier<Impl2, T> m_;
- const Impl *impl_;
+ const lwrapper<Any, T> m_;
+ const Fun *f_;
};
- } // end of namespace mln::fun::internal
-
- // Forward declaration (defined in mln/fun/unary.hh)
template <typename Fun, typename T>
struct unary;
namespace impl
{
- template <bool set, typename Fun, typename T>
- struct unary_impl_set;
+ template <bool param, bool set, typename Fun, typename T>
+ struct unary_impl;
template <typename Fun, typename T>
- struct unary_impl_set<false, Fun, T> : mln::Function_v2v< unary<Fun, T>
>
+ struct unary_impl<false, false, Fun, T> : 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() {}
+ typedef Fun flag;
+ typedef mln_trait_nunary(Fun, T) def;
- unary_impl_set(const init_param& p) : impl_(p) {}
+ typedef typename def::argument argument;
+ typedef typename def::result result;
result operator () (const argument& value) const
{
- return this->impl_.read(value);
+ return def::read(value);
}
- protected:
- impl impl_;
+ template <typename U>
+ void init(const U& value)
+ {
+ };
+
};
template <typename Fun, typename T>
- struct unary_impl_set<true, Fun, T> : unary_impl_set<false, Fun, T>
+ struct unary_impl<false, true, Fun, T> : unary_impl<false, 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 unary_impl<false, false, Fun, T> super;
+ typedef typename super::def::lvalue lvalue;
template <typename U>
struct lresult_with
{
- typedef mln::fun::spe::internal::unary_modifier<impl, U> ret;
+ typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret;
};
- typedef typename lresult_with<argument>::ret lresult;
+ typedef typename lresult_with<typename super::argument>::ret lresult;
+
+ void set(lvalue l, const typename super::result& r) const
+ {
+ super::def::write(l, r);
+ }
- unary_impl_set() {}
- unary_impl_set(const typename super::init_param& p) : super(p) {}
+ using super::operator ();
- void set(lvalue l, const result& r) const
+ lresult operator () (typename super::argument& value) const
{
- this->impl_.write(l, r);
+ return lresult(this, value);
}
+ };
+
+ template <typename Fun, typename T>
+ struct unary_impl<true, false, Fun, T> : Function_v2v< unary<Fun, T>
>
+ {
+ typedef Fun flag;
+ typedef mln_trait_nunary(Fun, T) def;
+
+ typedef typename def::argument argument;
+ typedef typename def::result result;
+
+ typedef mln_trait_fun_param(def) param;
+ typedef mln_trait_fun_storage(def) storage;
- lresult operator () (argument& value) const
+ result operator () (const argument& value) const
{
- return lresult(this->impl_, value);
+ return def::read(this->storage_, value);
}
- using super::operator();
+ template <typename U>
+ void init(const U& value)
+ {
+ storage_ = mln::trait::fun::internal::introspect::has_storage_t<def,
void>::compute(value);
};
- template <bool set, typename Fun, typename T>
- struct unary_impl_param;
+ protected:
+ storage storage_;
+ };
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>
+ struct unary_impl<true, true, Fun, T> : unary_impl<true, false, Fun, T>
{
- typedef impl::unary_impl_set<mln_trait_fun_is_assignable_(mln_trait_nunary(Fun,
T))::value, Fun, T> super;
+ typedef unary_impl<true, false, Fun, T> super;
+ typedef typename super::def::lvalue lvalue;
- unary_impl_param() {}
- unary_impl_param(const typename super::init_param& p) : super(p) {}
+ template <typename U>
+ struct lresult_with
+ {
+ typedef mln::fun::spe::lwrapper< unary<Fun, T>, U> ret;
};
- 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;
+ typedef typename lresult_with<typename super::argument>::ret lresult;
- unary_impl_param() {}
- unary_impl_param(const typename super::init_param& p) : super(p) {}
+ void set(lvalue l, const typename super::result& r) const
+ {
+ super::def::write(this->storage_, l, r);
+ }
- typedef typename super::param_ param;
+ using super::operator ();
- void init(const param& p)
+ lresult operator () (typename super::argument& value) const
{
- this->impl_.init(p);
+ return lresult(exact(*this), value);
}
};
@@ -258,13 +266,23 @@
template <typename Fun, typename T>
struct unary
- : impl::unary_impl_param<mln_trait_fun_is_parametrable_(mln_trait_nunary(Fun,
T))::value, Fun, T>
+ : impl::unary_impl<mln_trait_fun_is_parametrable_(mln_trait_nunary(Fun,
T))::value,
+ mln_trait_fun_is_assignable_(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>
+ typedef mln_trait_nunary(Fun, T) def;
+ typedef impl::unary_impl<mln_trait_fun_is_parametrable_(def)::value,
+ mln_trait_fun_is_assignable_(def)::value,
+ Fun,
+ T>
super;
unary() {}
- unary(const typename super::init_param& p) : super(p) {}
+
+ template <typename U>
+ unary(const U& param)
+ {
+ this->init(param);
+ }
using super::operator();
};
@@ -273,12 +291,12 @@
} // end of namespace mln::fun
- template <typename Impl, typename T>
- std::ostream& operator << (std::ostream& o, const
mln::fun::spe::internal::unary_modifier<Impl, T>& m)
+} // end of namespace mln
+
+template <typename F, typename T>
+std::ostream& operator << (std::ostream& o, const
mln::fun::spe::lwrapper<F, T>& m)
{
return o << m.to_result();
}
-} // end of namespace mln
-
#endif /* ! UNARY_HH */
Index: trunk/milena/sandbox/fred/mln/fun/unary.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/unary.hh (revision 3622)
+++ trunk/milena/sandbox/fred/mln/fun/unary.hh (revision 3623)
@@ -41,199 +41,73 @@
// Forward declarations, for composition with unary::operator()(Fun)
struct compose;
- template <typename F>
- struct unary;
-
namespace internal
{
- template <typename T>
+ template <typename U>
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 mln::fun::spe::unary<M, T> function;
-
- static function inst(const M& m)
- {
- return function(m.parameter());
- };
-
- };
-
- template <bool has_lvalue, typename M, typename T>
- struct unary_with_lvalue_helper;
-
- template <typename M, typename T>
- struct unary_with_lvalue_helper<false, M, T>
- : 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);
- }
- };
-
- template <typename M, typename T>
- struct unary_with_lvalue_helper<true, M, T>
- : unary_with_lvalue_helper<false, M, T>
- {
- typedef unary_with_lvalue_helper<false, M, T> super;
- typedef typename super::function function;
-
- static typename function::template lresult_with<T>::ret lcall(const M& m,
T& x)
- {
- function f(super::inst(m));
- return f(x);
- }
-
- static void set(const M& m, typename function::lvalue v, const T& x)
- {
- function f(super::inst(m));
- f.set(v, x);
- }
- };
-
- template <typename MF, typename MG, typename T>
- struct unary_with_lvalue_helper<true, MF,
mln::fun::spe::internal::unary_modifier<MG, T> >
- : unary_with_lvalue_helper<false, MF,
mln::fun::spe::internal::unary_modifier<MG, T> >
- {
- typedef unary_with_lvalue_helper<false, MF, typename MG::result > super;
- typedef typename super::function function;
-
- static typename function::template lresult_with<typename MG::result>::ret
lcall(const MF& m, T& x)
- {
- function f(super::inst(m));
- return f(x);
- }
-
- static typename function::template lresult_with<
mln::fun::spe::internal::unary_modifier<MG, T> >::ret
- lcall(const MF& m, const mln::fun::spe::internal::unary_modifier<MG, T>&
x)
- {
- function f(super::inst(m));
- return f(x);
}
- static void set(const MF& m, typename function::lvalue v, const T& x)
- {
- function f(super::inst(m));
- f.set(v, x);
- }
- };
-
- template <typename M, typename T>
- struct unary_with_helper
- :
unary_with_lvalue_helper<mln_trait_fun_is_assignable__1comma_(mln::fun::spe::unary<M,
T>)::value, M, T>
- {
- };
-
- } // end of namespace mln::fun::internal
-
template <typename F>
struct unary: mln::Meta_Function_v2v< F >
{
+ typedef F flag;
+ typedef mln_trait_fun_param(flag) param;
+ typedef mln_trait_fun_storage(flag) storage;
template <typename T>
struct with {
- typedef mln_trait_nunary(internal::unary_with<F>, T) impl;
- typedef typename impl::function ret;
+ typedef mln_trait_nunary(internal::unary_with<F>, T) def;
+ typedef typename def::ret ret;
};
template <typename T>
typename with<T>::ret::result operator()(const T& v) const
{
- return with<T>::impl::call(exact(*this), v);
+ return with<T>::def::call(exact(*this), v);
}
template <typename T>
typename with<T>::ret::template lresult_with<T>::ret operator()(T&
v) const
{
- return with<T>::impl::lcall(exact(*this), v);
- }
-
- template <typename G, typename U>
- typename with< mln::fun::spe::internal::unary_modifier<G, U>
>::ret::lresult
- operator()(const mln::fun::spe::internal::unary_modifier<G, U>& v) const
- {
- return with< mln::fun::spe::internal::unary_modifier<G, U>
>::impl::lcall(exact(*this), v);
+ return typename with<T>::ret(storage_get())(v);
}
template <typename T, typename R>
void set(T& v, const R& r) const
{
- 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;
+ typename with<T>::ret(storage_).set(v, r);
}
- param& parameter()
+ template <typename U>
+ void init(const U& value)
{
- return p_;
- }
-
- const param& parameter() const
- {
- return p_;
- }
-
- protected:
- param p_;
-
+ storage_ = mln::trait::fun::internal::introspect::has_storage_t<flag,
void>::compute(value);
};
- template <typename F>
- struct unary_param<F, F>: unary<F>
+ unary()
{
- typedef F param;
+ }
- void init(const param& p)
+ template <typename U>
+ unary(const U& param)
{
- exact(*this) = p;
+ this->init(param);
}
- param& parameter()
+ stored<storage>& storage_get()
{
- return exact(*this);
+ return storage_;
}
- const param& parameter() const
+ const stored<storage>& storage_get() const
{
- return exact(*this);
+ return storage_;
}
+ protected:
+ stored<storage> storage_;
};
} // end of namespace mln::fun
@@ -248,7 +122,17 @@
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;
+ struct ret_t
+ {
+ typedef mln::fun::spe::unary<F, T> ret;
+
+ static typename ret::result call(const F& f, const T& v)
+ {
+ return ret(f.storage_get())(v);
+ }
+ };
+
+ typedef ret_t ret;
};
// Meta Function
@@ -262,14 +146,18 @@
typedef T ret;
};
- typedef set_unary_ ret;
- typedef typename identity<mln::fun::compose>::ret::template with<F, G>::ret
function;
+ struct ret_t
+ {
+ typedef typename identity<mln::fun::compose>::ret::template with<F,
G>::ret ret;
- static typename function::result call(const F& f, const G& g)
+ static typename ret::result call(const F& f, const G& g)
{
- function tmp;
- return tmp(f, g);
+ return ret()(f, g);
}
+
+ };
+
+ typedef ret_t ret;
};
} // end of namespace mln::trait::next
Index: trunk/milena/sandbox/fred/mln/fun/param.hh
===================================================================
--- trunk/milena/sandbox/fred/mln/fun/param.hh (revision 0)
+++ trunk/milena/sandbox/fred/mln/fun/param.hh (revision 3623)
@@ -0,0 +1,88 @@
+// 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_FUN_PARAM_HH
+# define MLN_FUN_PARAM_HH
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ template <typename T>
+ struct stored
+ {
+ typedef T value;
+
+ const T& to_value() const
+ {
+ return t_;
+ }
+
+ T& to_value()
+ {
+ return t_;
+ }
+
+ operator const T& () const
+ {
+ return to_value();
+ }
+
+ operator T& ()
+ {
+ return to_value();
+ }
+
+ stored& operator = (const T& t)
+ {
+ t_ = t;
+ return *this;
+ }
+
+ protected:
+ T t_;
+ };
+
+ template <>
+ struct stored<void>
+ {
+ };
+
+ template <typename F>
+ struct parameter
+ {
+ typedef void param;
+ typedef void storage;
+ };
+
+ } // end of namespace mln::fun
+
+} // end of namespace mln
+
+#endif /* ! MLN_FUN_PARAM_HH */