
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2009-04-06 Frederic Bour <bour@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 */