26 #ifndef MLN_TRAIT_NEXT_SOLVE_BINARY_HH
27 # define MLN_TRAIT_NEXT_SOLVE_BINARY_HH
33 # include <mln/core/category.hh>
34 # include <mln/core/routine/exact.hh>
35 # include <mln/metal/equal.hh>
36 # include <mln/metal/if.hh>
37 # include <mln/metal/ret.hh>
38 # include <mln/trait/next/solve.hh>
43 # ifndef MLN_DEBUG_TRAITS
44 # endif // ! MLN_DEBUG_TRAITS
61 template <
typename Name,
62 typename Category_L,
typename L,
63 typename Category_R,
typename R >
64 struct trait_set_binary_;
66 template <
typename Name,
67 template <
class>
class Category_L,
typename _l,
typename L,
68 template <
class>
class Category_R,
typename _r,
typename R >
69 struct trait_set_binary_< Name,
73 typedef typename mln::trait::next::set_binary_<Name,
81 template <
unsigned i_L_,
unsigned i_R_,
typename ret_ >
90 template <
typename L_trp,
typename R_trp >
91 struct merge_triplets_;
93 template <
unsigned L_i_L,
unsigned L_i_R,
typename L_ret,
94 unsigned R_i_L,
unsigned R_i_R,
typename R_ret >
95 struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
96 triplet_<R_i_L, R_i_R, R_ret> >
98 typedef metal::bool_<(L_i_L <= R_i_L && L_i_R <= R_i_R)> take_L;
99 typedef metal::bool_<(R_i_L <= L_i_L && R_i_R <= L_i_R)> take_R;
100 typedef metal::or_<take_L, take_R> ok;
101 typedef typename metal::if_< metal::and_<ok, take_L>,
102 triplet_<L_i_L, L_i_R, L_ret>,
103 typename metal::if_< metal::and_<ok, take_R>,
104 triplet_<R_i_L, R_i_R, R_ret>,
108 template <
unsigned i_L,
unsigned i_R,
typename LR_ret >
109 struct merge_triplets_< triplet_<i_L, i_R, LR_ret>,
110 triplet_<i_L, i_R, LR_ret> >
112 typedef triplet_<i_L, i_R, LR_ret>
ret;
116 template <
unsigned L_i_L,
unsigned L_i_R,
unsigned L_i_max,
117 unsigned R_i_L,
unsigned R_i_R,
unsigned R_i_max >
119 struct helper_merge_triplets_same_ret_
126 enum { i_L = (L_i_max < R_i_max ? L_i_L : R_i_L),
127 i_R = (L_i_max < R_i_max ? L_i_R : R_i_R) };
130 template <
unsigned L_i_L,
unsigned L_i_R,
unsigned i_max,
131 unsigned R_i_L,
unsigned R_i_R >
133 struct helper_merge_triplets_same_ret_< L_i_L, L_i_R, i_max,
134 R_i_L, R_i_R, i_max >
137 enum { L_i_min = (L_i_L < L_i_R ? L_i_L : L_i_R),
138 R_i_min = (R_i_L < R_i_R ? R_i_L : R_i_R),
139 i_L = (L_i_min < R_i_min ? L_i_L : R_i_L),
140 i_R = (L_i_min < R_i_min ? L_i_R : R_i_R) };
144 template <
unsigned L_i_L,
unsigned L_i_R,
typename LR_ret,
145 unsigned R_i_L,
unsigned R_i_R >
146 struct merge_triplets_< triplet_<L_i_L, L_i_R, LR_ret>,
147 triplet_<R_i_L, R_i_R, LR_ret> >
149 typedef helper_merge_triplets_same_ret_< L_i_L, L_i_R, (L_i_L > L_i_R ? L_i_L : L_i_R),
150 R_i_L, R_i_R, (R_i_L > R_i_R ? R_i_L : R_i_R) > helper;
151 typedef triplet_<helper::i_L, helper::i_R, LR_ret>
ret;
154 template <
unsigned L_i_L,
unsigned L_i_R,
typename L_ret >
155 struct merge_triplets_< triplet_<L_i_L, L_i_R, L_ret>,
156 triplet_< 0, 0, not_found> >
158 typedef triplet_<L_i_L, L_i_R, L_ret>
ret;
161 template <
unsigned R_i_L,
unsigned R_i_R,
typename R_ret >
162 struct merge_triplets_< triplet_< 0, 0, not_found>,
163 triplet_<R_i_L, R_i_R, R_ret> >
165 typedef triplet_<R_i_L, R_i_R, R_ret>
ret;
169 struct merge_triplets_< triplet_<0, 0, not_found>,
170 triplet_<0, 0, not_found> >
172 typedef triplet_<0u,0u, not_found>
ret;
178 template <
typename Name,
179 unsigned i_L,
typename Category_L,
typename L,
180 unsigned i_R,
typename Category_R,
typename R >
184 template <
typename user_ret,
186 unsigned i_L,
typename Category_L,
typename L,
187 unsigned i_R,
typename Category_R,
typename R >
188 struct helper_get_binary_
190 typedef triplet_< i_L, i_R, user_ret >
ret;
193 template <
typename Name,
194 unsigned i_L,
typename Category_L,
typename L,
195 unsigned i_R,
typename Category_R,
typename R >
196 struct helper_get_binary_< not_found,
197 Name, i_L, Category_L, L, i_R, Category_R, R >
199 typedef triplet_< 0, 0, not_found >
ret;
203 template <
typename Name,
204 unsigned i_L,
typename Category_L,
typename L,
205 unsigned i_R,
typename Category_R,
typename R >
206 struct helper_get_binary_< undefined,
207 Name, i_L,Category_L, L, i_R,Category_R, R >
217 typedef get_binary_< Name,
218 i_L + 1, Super_Category_L, L,
219 i_R, Category_R, R > L_branch;
220 typedef mlc_ret(L_branch) L_trp;
222 typedef get_binary_< Name,
224 i_R + 1, Super_Category_R, R > R_branch;
225 typedef mlc_ret(R_branch) R_trp;
227 typedef typename merge_triplets_< L_trp, R_trp >::
ret ret;
231 template < typename Name,
232 unsigned i_L, typename Category_L, typename L,
233 unsigned i_R, typename Category_R, typename R >
236 typedef typename trait_set_binary_<Name, Category_L,L,
237 Category_R,R>
::ret user_ret;
238 typedef helper_get_binary_<user_ret, Name, i_L,Category_L,L,
239 i_R,Category_R,R> helper;
240 typedef mlc_ret(helper) ret;
244 template < typename precise_ret,
246 typename Category_L, typename L,
247 typename Category_R, typename R >
248 struct helper_choose_binary_wrt_
250 typedef precise_ret ret;
253 template <
typename Name,
254 typename Category_L,
typename L,
255 typename Category_R,
typename R >
256 struct helper_choose_binary_wrt_< undefined,
257 Name, Category_L, L, Category_R, R >
259 typedef typename get_binary_< Name,
261 0, Category_R, R >
::ret triplet;
262 typedef mlc_ret(triplet) ret;
266 template < typename Name,
267 typename Category_L, typename L,
268 typename Category_R, typename R >
269 struct helper_solve_binary_
271 typedef typename set_precise_binary_<Name, L, R>::ret precise_ret;
272 typedef helper_choose_binary_wrt_<precise_ret, Name, Category_L,L, Category_R,R> helper;
273 typedef mlc_ret(helper) ret;
280 template < typename Name,
285 typedef mln_exact(L_) L;
286 typedef mln_exact(R_) R;
287 typedef typename mln::category<L>::ret Category_L;
288 typedef typename mln::category<R>::ret Category_R;
289 typedef internal::helper_solve_binary_< Name, Category_L, L, Category_R, R > meta_code;
290 typedef typename meta_code::ret ret;
300 #endif // ! MLN_TRAIT_NEXT_SOLVE_BINARY_HH