summaryrefslogtreecommitdiff
path: root/src/ranges.hh
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2019-01-24 21:09:07 +1100
committerMaxime Coste <mawww@kakoune.org>2019-01-24 23:24:50 +1100
commitb91367f8a3b6e712888988a15f1242b478a8fcdd (patch)
treeb92de116bd668e0c084ef3f8306b09396a3ae931 /src/ranges.hh
parent3e89148d74c3d4a9ba075b0d9218457e845982e6 (diff)
Replace std::mem_fn with custom lambda in ranges
Diffstat (limited to 'src/ranges.hh')
-rw-r--r--src/ranges.hh26
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,