diff options
| author | Maxime Coste <mawww@kakoune.org> | 2019-01-24 21:09:07 +1100 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2019-01-24 23:24:50 +1100 |
| commit | b91367f8a3b6e712888988a15f1242b478a8fcdd (patch) | |
| tree | b92de116bd668e0c084ef3f8306b09396a3ae931 /src | |
| parent | 3e89148d74c3d4a9ba075b0d9218457e845982e6 (diff) | |
Replace std::mem_fn with custom lambda in ranges
Diffstat (limited to 'src')
| -rw-r--r-- | src/ranges.hh | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/ranges.hh b/src/ranges.hh index 1089c94d..88f6d2ef 100644 --- a/src/ranges.hh +++ b/src/ranges.hh @@ -5,7 +5,6 @@ #include <utility> #include <iterator> #include <numeric> -#include <functional> #include "constexpr_utils.hh" @@ -191,10 +190,31 @@ inline auto transform(Transform t) }); } +template<typename T, typename U, typename = void> +struct is_pointer_like : std::false_type {}; + +template<typename T, typename U> +struct is_pointer_like<T, U, std::enable_if_t<std::is_same_v<std::decay_t<decltype(*std::declval<U>())>, std::decay_t<T>>>> : std::true_type {}; + template<typename M, typename T> -inline auto transform(M T::*m) +inline auto transform(M T::*member) { - return transform(std::mem_fn(std::forward<decltype(m)>(m))); + return transform([member](auto&& arg) -> decltype(auto) { + using Arg = decltype(arg); + using Member = decltype(member); + + auto get_object = [&] () mutable -> decltype(auto) { + if constexpr (is_pointer_like<T, Arg>::value) + return *std::forward<Arg>(arg); + else + return std::forward<Arg>(arg); + }; + + if constexpr (std::is_member_function_pointer_v<Member>) + return (get_object().*member)(); + else + return get_object().*member; + }); } template<typename Range, bool escape, bool include_separator, |
