Skip to content

Commit

Permalink
brute-force attempt to fix min_element example on GCC 4.7
Browse files Browse the repository at this point in the history
  • Loading branch information
ecrypa committed Oct 28, 2019
1 parent 9d833d8 commit 39a5465
Showing 1 changed file with 33 additions and 13 deletions.
46 changes: 33 additions & 13 deletions include/metal/list/min_element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "../config.hpp"
#include "../detail/sfinae.hpp"
#include "../lambda/lambda.hpp"
#include "../number/if.hpp"
#include "../number/less.hpp"

namespace metal {
Expand Down Expand Up @@ -53,32 +52,53 @@ namespace metal {
/// \see min, sort
#if !defined(METAL_WORKAROUND)
template<class seq, class lbd = metal::lambda<metal::less>>
using min_element = detail::call<
detail::_min_element<if_<is_lambda<lbd>, lbd>>::template type, seq>;
using min_element =
detail::call<detail::_min_element<lbd>::template type, seq>;
#else
// MSVC 14 has shabby SFINAE support in case of default alias template args
template<class seq, class... lbd>
using min_element = detail::call<
detail::_min_element<if_<is_lambda<lbd>, lbd>...>::template type, seq>;
using min_element =
detail::call<detail::_min_element<lbd...>::template type, seq>;
#endif
}

#include "../lambda/apply.hpp"
#include "../lambda/invoke.hpp"
#include "../lambda/partial.hpp"
#include "../list/list.hpp"
#include "../number/if.hpp"
#include "../value/fold_left.hpp"

namespace metal {
/// \cond
namespace detail {
template<class lbd>
struct _min_element {
template<class x, class y>
struct _min_element_min_impl {
template<template<class...> class expr>
using type = if_<expr<y, x>, y, x>;
};

template<template<class...> class expr>
struct _min_element_min {
template<class x, class y>
using custom_min = if_<invoke<lbd, y, x>, y, x>;
using type =
forward<_min_element_min_impl<x, y>::template type, expr>;
};

template<class seq>
struct _min_element_impl {};

template<class... vals>
struct _min_element_impl<list<vals...>> {
template<template<class...> class expr>
using type = fold_left<
lambda<_min_element_min<expr>::template type>, vals...>;
};

template<class lbd>
struct _min_element {};

template<template<class...> class expr>
struct _min_element<lambda<expr>> {
template<class seq>
using type =
apply<partial<lambda<fold_left>, lambda<custom_min>>, seq>;
using type = forward<_min_element_impl<seq>::template type, expr>;
};
}
/// \endcond
Expand Down

0 comments on commit 39a5465

Please sign in to comment.