|
4 | 4 | #include "../config.hpp"
|
5 | 5 | #include "../detail/sfinae.hpp"
|
6 | 6 | #include "../lambda/lambda.hpp"
|
7 |
| -#include "../number/if.hpp" |
8 | 7 | #include "../number/less.hpp"
|
9 | 8 |
|
10 | 9 | namespace metal {
|
@@ -53,32 +52,53 @@ namespace metal {
|
53 | 52 | /// \see min, sort
|
54 | 53 | #if !defined(METAL_WORKAROUND)
|
55 | 54 | template<class seq, class lbd = metal::lambda<metal::less>>
|
56 |
| - using min_element = detail::call< |
57 |
| - detail::_min_element<if_<is_lambda<lbd>, lbd>>::template type, seq>; |
| 55 | + using min_element = |
| 56 | + detail::call<detail::_min_element<lbd>::template type, seq>; |
58 | 57 | #else
|
59 | 58 | // MSVC 14 has shabby SFINAE support in case of default alias template args
|
60 | 59 | template<class seq, class... lbd>
|
61 |
| - using min_element = detail::call< |
62 |
| - detail::_min_element<if_<is_lambda<lbd>, lbd>...>::template type, seq>; |
| 60 | + using min_element = |
| 61 | + detail::call<detail::_min_element<lbd...>::template type, seq>; |
63 | 62 | #endif
|
64 | 63 | }
|
65 | 64 |
|
66 |
| -#include "../lambda/apply.hpp" |
67 |
| -#include "../lambda/invoke.hpp" |
68 |
| -#include "../lambda/partial.hpp" |
| 65 | +#include "../list/list.hpp" |
| 66 | +#include "../number/if.hpp" |
69 | 67 | #include "../value/fold_left.hpp"
|
70 | 68 |
|
71 | 69 | namespace metal {
|
72 | 70 | /// \cond
|
73 | 71 | namespace detail {
|
74 |
| - template<class lbd> |
75 |
| - struct _min_element { |
| 72 | + template<class x, class y> |
| 73 | + struct _min_element_min_impl { |
| 74 | + template<template<class...> class expr> |
| 75 | + using type = if_<expr<y, x>, y, x>; |
| 76 | + }; |
| 77 | + |
| 78 | + template<template<class...> class expr> |
| 79 | + struct _min_element_min { |
76 | 80 | template<class x, class y>
|
77 |
| - using custom_min = if_<invoke<lbd, y, x>, y, x>; |
| 81 | + using type = |
| 82 | + forward<_min_element_min_impl<x, y>::template type, expr>; |
| 83 | + }; |
78 | 84 |
|
| 85 | + template<class seq> |
| 86 | + struct _min_element_impl {}; |
| 87 | + |
| 88 | + template<class... vals> |
| 89 | + struct _min_element_impl<list<vals...>> { |
| 90 | + template<template<class...> class expr> |
| 91 | + using type = fold_left< |
| 92 | + lambda<_min_element_min<expr>::template type>, vals...>; |
| 93 | + }; |
| 94 | + |
| 95 | + template<class lbd> |
| 96 | + struct _min_element {}; |
| 97 | + |
| 98 | + template<template<class...> class expr> |
| 99 | + struct _min_element<lambda<expr>> { |
79 | 100 | template<class seq>
|
80 |
| - using type = |
81 |
| - apply<partial<lambda<fold_left>, lambda<custom_min>>, seq>; |
| 101 | + using type = forward<_min_element_impl<seq>::template type, expr>; |
82 | 102 | };
|
83 | 103 | }
|
84 | 104 | /// \endcond
|
|
0 commit comments