27 #ifndef MLN_FUN_X2X_COMPOSED_HH
28 # define MLN_FUN_X2X_COMPOSED_HH
34 # include <mln/core/concept/function.hh>
35 # include <mln/fun/internal/x2x_linear_impl.hh>
36 # include <mln/algebra/vec.hh>
37 # include <mln/metal/is.hh>
38 # include <mln/metal/bexpr.hh>
39 # include <mln/algebra/h_mat.hh>
52 template <
typename T2,
typename T1>
57 template <
typename T2,
typename T1,
typename E,
bool is_bij>
58 struct helper_composed_;
62 template <
typename T2,
typename T1,
typename E>
63 struct helper_composed_<T2,T1,E,true>
64 :
public fun::internal::x2x_linear_impl_<mln_result(T2), typename T2::data_t, E >,
65 public Function_v2v<E>
67 typedef fun::internal::x2x_linear_impl_<typename T2::result, typename T2::data_t, E > super_;
70 typedef typename T2::data_t data_t;
77 helper_composed_(
const T2& f,
const T1& g);
79 using super_::operator();
82 const T2& second()
const;
84 const T1& first()
const;
87 void set_second(
const T2& f);
89 void set_first(
const T1& g);
92 typedef composed<mln_invert(T1),mln_invert(T2)> invert;
103 template <
typename T2,
typename T1,
typename E>
104 struct helper_composed_<T2,T1,E,false>
105 :
public fun::internal::x2x_linear_impl_<mln_result(T2), typename T2::data_t, E >,
106 public Function_v2v<E>
108 typedef fun::internal::x2x_linear_impl_<typename T2::result, typename T2::data_t, E > super_;
112 typedef typename T2::data_t data_t;
119 helper_composed_(
const T2& f,
const T1& g);
121 using super_::operator();
124 void set_second(
const T2& f);
126 void set_first(
const T1& g);
129 const T2& second()
const;
131 const T1& first()
const;
143 template <
typename T2,
typename T1>
145 :
public internal::helper_composed_< T2, T1, composed<T2,T1>,
146 (mlc_is(T2, Function_v2v<T2>)::value &&
147 mlc_is(T1, Function_v2v<T1>)::value) >,
148 private metal::and_< metal::bool_<(T2::dim == T1::dim)>,
149 metal::is<mln_argument(T2), mln_result(T1)>
157 : internal::helper_composed_< T2, T1,
composed<T2,T1>,
174 template <
typename T2,
typename T1>
175 fun::x2x::composed<T2,T1>
compose(T2 f, T1 g);
177 # ifndef MLN_INCLUDE_ONLY
190 template <
typename T2,
typename T1,
typename E>
192 helper_composed_<T2,T1,E,true>::helper_composed_()
196 template <
typename T2,
typename T1,
typename E>
198 helper_composed_<T2,T1,E,true>::helper_composed_(
const T2& f,
const T1& g)
202 this->m_ = f_.mat() * g_.mat();
205 template <
typename T2,
typename T1,
typename E>
207 typename helper_composed_<T2,T1,E,true>::invert
208 helper_composed_<T2,T1,E,true>::inv()
const
210 return compose(g_.inv(), f_.inv());
213 template <
typename T2,
typename T1,
typename E>
216 helper_composed_<T2,T1,E,true>::set_second(
const T2& f)
219 this->m_ = this->f_.mat() * this->g_.mat();
222 template <
typename T2,
typename T1,
typename E>
225 helper_composed_<T2,T1,E,true>::set_first(
const T1& g)
228 this->m_ = this->f_.mat() * this->g_.mat();
231 template <
typename T2,
typename T1,
typename E>
234 helper_composed_<T2,T1,E,true>::second()
const
239 template <
typename T2,
typename T1,
typename E>
242 helper_composed_<T2,T1,E,true>::first()
const
248 template <
typename T2,
typename T1,
typename E>
250 helper_composed_<T2,T1,E,false>::helper_composed_()
254 template <
typename T2,
typename T1,
typename E>
256 helper_composed_<T2,T1,E,false>::helper_composed_(
const T2& f,
const T1& g)
260 this->m_ = f_.mat() * g_.mat();
263 template <
typename T2,
typename T1,
typename E>
266 helper_composed_<T2,T1,E,false>::set_second(
const T2& f)
269 this->m_ = this->f_.mat() * this->g_.mat();
272 template <
typename T2,
typename T1,
typename E>
275 helper_composed_<T2,T1,E,false>::set_first(
const T1& g)
278 this->m_ = this->f_.mat() * this->g_.mat();
281 template <
typename T2,
typename T1,
typename E>
284 helper_composed_<T2,T1,E,false>::second()
const
289 template <
typename T2,
typename T1,
typename E>
292 helper_composed_<T2,T1,E,false>::first()
const
304 template <
typename T2,
typename T1>
308 trace::entering(
"fun::x2x::compose");
310 trace::exiting(
"fun::x2x::compose");
314 # endif // ! MLN_INCLUDE_ONLY
319 #endif // ! MLN_FUN_X2X_COMPOSED_HH