2019-06-02 21:19:10 +00:00
|
|
|
#ifndef LLARP_UTIL_MEMFN
|
|
|
|
#define LLARP_UTIL_MEMFN
|
|
|
|
|
2020-02-22 03:11:20 +00:00
|
|
|
#include <type_traits>
|
2019-06-02 21:19:10 +00:00
|
|
|
#include <utility>
|
2020-02-22 03:11:20 +00:00
|
|
|
#include <memory>
|
2019-06-02 21:19:10 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace util
|
|
|
|
{
|
2020-02-22 03:11:20 +00:00
|
|
|
// Wraps a member function and instance into a callable object that invokes
|
|
|
|
// the method (non-const overload).
|
|
|
|
template <
|
2020-04-07 18:38:56 +00:00
|
|
|
typename Return,
|
|
|
|
typename Class,
|
|
|
|
typename Derived,
|
|
|
|
typename... Arg,
|
|
|
|
typename = std::enable_if_t<std::is_base_of<Class, Derived>::value>>
|
2020-02-22 03:11:20 +00:00
|
|
|
auto
|
|
|
|
memFn(Return (Class::*f)(Arg...), Derived* self)
|
2019-06-02 21:19:10 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
return [f, self](Arg... args) -> Return { return (self->*f)(std::forward<Arg>(args)...); };
|
2020-02-22 03:11:20 +00:00
|
|
|
}
|
2019-06-02 21:19:10 +00:00
|
|
|
|
2020-02-22 03:11:20 +00:00
|
|
|
// Wraps a member function and instance into a lambda that invokes the
|
|
|
|
// method (const overload).
|
|
|
|
template <
|
2020-04-07 18:38:56 +00:00
|
|
|
typename Return,
|
|
|
|
typename Class,
|
|
|
|
typename Derived,
|
|
|
|
typename... Arg,
|
|
|
|
typename = std::enable_if_t<std::is_base_of<Class, Derived>::value>>
|
2020-02-22 03:11:20 +00:00
|
|
|
auto
|
|
|
|
memFn(Return (Class::*f)(Arg...) const, const Derived* self)
|
2019-06-02 21:19:10 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
return [f, self](Arg... args) -> Return { return (self->*f)(std::forward<Arg>(args)...); };
|
2020-02-22 03:11:20 +00:00
|
|
|
}
|
2019-06-02 21:19:10 +00:00
|
|
|
|
2020-02-22 03:11:20 +00:00
|
|
|
// Wraps a member function and shared pointer to an instance into a lambda
|
|
|
|
// that invokes the method.
|
|
|
|
template <
|
2020-04-07 18:38:56 +00:00
|
|
|
typename Return,
|
|
|
|
typename Class,
|
|
|
|
typename Derived,
|
|
|
|
typename... Arg,
|
|
|
|
typename = std::enable_if_t<std::is_base_of<Class, Derived>::value>>
|
2020-02-22 03:11:20 +00:00
|
|
|
auto
|
2020-04-07 18:38:56 +00:00
|
|
|
memFn(Return (Class::*f)(Arg...), std::shared_ptr<Derived> self)
|
2020-02-22 03:11:20 +00:00
|
|
|
{
|
2020-02-22 16:17:53 +00:00
|
|
|
return [f, self = std::move(self)](Arg... args) -> Return {
|
2020-04-07 18:38:56 +00:00
|
|
|
return (self.get()->*f)(std::forward<Arg>(args)...);
|
2020-02-22 03:11:20 +00:00
|
|
|
};
|
|
|
|
}
|
2019-06-02 21:19:10 +00:00
|
|
|
|
2020-02-22 03:11:20 +00:00
|
|
|
// Wraps a member function and shared pointer to an instance into a lambda
|
|
|
|
// that invokes the method (const method overload).
|
|
|
|
template <
|
2020-04-07 18:38:56 +00:00
|
|
|
typename Return,
|
|
|
|
typename Class,
|
|
|
|
typename Derived,
|
|
|
|
typename... Arg,
|
|
|
|
typename = std::enable_if_t<std::is_base_of<Class, Derived>::value>>
|
2020-02-22 03:11:20 +00:00
|
|
|
auto
|
2020-04-07 18:38:56 +00:00
|
|
|
memFn(Return (Class::*f)(Arg...) const, std::shared_ptr<Derived> self)
|
2019-06-02 21:19:10 +00:00
|
|
|
{
|
2020-02-22 16:17:53 +00:00
|
|
|
return [f, self = std::move(self)](Arg... args) -> Return {
|
2020-04-07 18:38:56 +00:00
|
|
|
return (self.get()->*f)(std::forward<Arg>(args)...);
|
2020-02-22 03:11:20 +00:00
|
|
|
};
|
2019-06-02 21:19:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace util
|
|
|
|
} // namespace llarp
|
|
|
|
|
|
|
|
#endif
|