26 #ifndef MLN_FUN_COMPOSITION_HH
27 # define MLN_FUN_COMPOSITION_HH
29 # include <mln/fun/unary.hh>
30 # include <mln/fun/binary.hh>
31 # include <mln/fun/param.hh>
43 template <
typename F,
typename G>
44 struct composition_param
46 composition_param(
const F& f,
const G& g) : f_(f), g_(g) {}
47 composition_param() {}
54 template <
template <
class>
class CatF,
typename F,
55 template <
class>
class CatG,
typename G>
60 template <
template <
class>
class CatF,
typename F,
61 template <
class>
class CatG,
typename G>
62 struct parameter< internal::composition<CatF, F, CatG, G> >
64 typedef internal::composition_param<F, G> param;
71 template <
typename F,
typename G>
73 : mln::fun::unary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> >
75 typedef mln::fun::unary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G> > super;
78 composition(
const composition_param<F, G>& p) : super(p) {};
80 typedef composition exact_type;
83 template <
typename F,
typename G>
85 : mln::fun::binary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> >
87 typedef mln::fun::binary< composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G> > super;
90 composition(
const composition_param<F, G>& p) : super(p) {};
92 typedef composition exact_type;
96 template <
typename F,
typename G>
99 typedef mln::fun::spe::unary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>,
typename G::argument> exact_type;
102 template <
typename F,
typename G>
105 typedef mln::fun::spe::binary< composition<mln::Meta_Function_v2v, F, mln::Function_vv2v, G>,
106 typename G::argument1,
typename G::argument2> exact_type;
110 template <
bool has_lvalue,
typename F,
typename F_spe,
typename G,
typename G_spe>
111 struct composition_unary_impl_helper;
113 template <
typename F,
typename F_spe,
typename G,
typename G_spe>
114 struct composition_unary_impl_helper<false, F, F_spe, G, G_spe>
116 typedef typename G_spe::argument argument;
117 typedef typename F_spe::result result;
118 typedef composition_param<F, G> param;
120 static result read(
const param& p,
const argument& x)
122 return p.f_(p.g_(x));
126 template <
typename F,
typename F_spe,
typename G,
typename G_spe>
127 struct composition_unary_impl_helper<true, F, F_spe, G, G_spe>
128 : composition_unary_impl_helper<false, F, F_spe, G, G_spe>
130 typedef composition_unary_impl_helper<false, F, F_spe, G, G_spe> super;
131 typedef typename G_spe::lvalue lvalue;
133 composition_unary_impl_helper() {}
134 composition_unary_impl_helper(
const typename super::param& p) : super(p) {}
136 static void write(
const typename super::param& p, lvalue l,
const typename super::result& x)
138 typename G_spe::result r(p.g_(l));
145 template <
typename F,
typename F_spe,
typename G,
typename G_spe>
146 struct composition_unary_impl
147 : composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe>
149 typedef composition_unary_impl_helper<mln_trait_fun_is_assignable_(G_spe)::value, F, F_spe, G, G_spe> super;
151 composition_unary_impl() {}
152 composition_unary_impl(
const typename super::param& p) : super(p) {}
155 template <
typename F,
typename F_spe,
typename G,
typename G_spe>
156 struct composition_binary_impl
158 typedef typename G_spe::argument1 argument1;
159 typedef typename G_spe::argument2 argument2;
160 typedef typename F_spe::result result;
161 typedef composition_param<F, G> param;
163 static result read(
const param& p,
const argument1& a,
const argument2& b)
165 return p.f_(p.g_(a, b));
179 template <
typename F,
typename G,
typename T>
180 struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_v2v, G>, T>
182 typedef typename G::template with<T>::ret G_fun;
183 typedef typename F::template with<typename G_fun::result>::ret F_fun;
185 typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G_fun> ret;
188 template <
typename F,
typename G,
typename T1,
typename T2>
189 struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>, T1, T2>
191 typedef typename G::template with<T1, T2>::ret G_fun;
192 typedef typename F::template with<typename G_fun::result>::ret F_fun;
194 typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G_fun> ret;
197 template <
typename F,
typename G>
198 struct set_precise_unary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Function_v2v, G>,
199 typename G::argument>
201 typedef typename F::template with<typename G::result>::ret F_fun;
203 typedef mln::fun::internal::composition_unary_impl<F, F_fun, G, G> ret;
206 template <
typename F,
typename G>
207 struct set_precise_binary_<mln::fun::internal::composition<mln::Meta_Function_v2v, F, mln::Meta_Function_vv2v, G>,
208 typename G::argument1, typename G::argument2>
210 typedef typename F::template with<typename G::result>::ret F_fun;
212 typedef mln::fun::internal::composition_binary_impl<F, F_fun, G, G> ret;
221 #endif // ! MLN_FUN_COMPOSITION_HH