|
2 | 2 | #define METAL_LIST_MIN_ELEMENT_HPP
|
3 | 3 |
|
4 | 4 | #include "../config.hpp"
|
5 |
| -#include "../detail/sfinae.hpp" |
6 | 5 | #include "../lambda/apply.hpp"
|
| 6 | +#include "../lambda/invoke.hpp" |
7 | 7 | #include "../lambda/lambda.hpp"
|
8 | 8 | #include "../number/if.hpp"
|
| 9 | +#include "../number/number.hpp" |
9 | 10 | #include "../value/fold_left.hpp"
|
10 | 11 |
|
11 | 12 | namespace metal {
|
12 | 13 | namespace detail {
|
13 |
| - |
14 | 14 | template<class lbd>
|
15 |
| - struct _min_element {}; |
16 |
| - |
17 |
| - template<template<class...> class expr> |
18 |
| - struct _min_element<lambda<expr>> { |
| 15 | + struct _min_element { |
19 | 16 | template<class x, class y>
|
20 |
| - using combiner = if_<dcall<expr, y, x>, y, x>; |
| 17 | + using combiner = if_<invoke<lbd, y, x>, y, x>; |
| 18 | + // Combiner must use `invoke` in order to support SFINAE. It is |
| 19 | + // tempting to extract the `expr` from `lbd` and use `expr<y, x>`, |
| 20 | + // but that is not SFINAE-friendly. |
21 | 21 |
|
22 | 22 | template<class... vals>
|
23 | 23 | using type = fold_left<lambda<combiner>, vals...>;
|
24 | 24 | };
|
25 | 25 | }
|
26 | 26 |
|
27 | 27 | template<class seq, class lbd>
|
28 |
| - using min_element = |
29 |
| - apply<lambda<detail::_min_element<lbd>::template type>, seq>; |
| 28 | + using min_element = apply< |
| 29 | + lambda<detail::_min_element<if_<is_lambda<lbd>, lbd>>::template type>, |
| 30 | + seq>; |
30 | 31 | }
|
31 | 32 |
|
32 | 33 | #endif
|
0 commit comments