66 lines
1.5 KiB
C++
66 lines
1.5 KiB
C++
#pragma once
|
|
|
|
#include "asl/meta.hpp"
|
|
#include "asl/utility.hpp"
|
|
|
|
namespace asl {
|
|
|
|
template<typename... Args, typename C>
|
|
constexpr auto invoke(is_func auto C::* f, auto&& self, Args&&... args)
|
|
requires requires {
|
|
(self.*f)(ASL_FWD(args)...);
|
|
}
|
|
{
|
|
return (ASL_FWD(self).*f)(ASL_FWD(args)...);
|
|
}
|
|
|
|
template<typename... Args, typename C>
|
|
constexpr auto invoke(is_func auto C::* f, auto* self, Args&&... args)
|
|
requires requires {
|
|
(self->*f)(ASL_FWD(args)...);
|
|
}
|
|
{
|
|
return (self->*f)(ASL_FWD(args)...);
|
|
}
|
|
|
|
template<typename... Args, typename C>
|
|
constexpr auto invoke(is_object auto C::* m, auto&& self, Args&&...)
|
|
requires (
|
|
sizeof...(Args) == 0 &&
|
|
requires { self.*m; }
|
|
)
|
|
{
|
|
return ASL_FWD(self).*m;
|
|
}
|
|
|
|
template<typename... Args, typename C>
|
|
constexpr auto invoke(is_object auto C::* m, auto* self, Args&&...)
|
|
requires (
|
|
sizeof...(Args) == 0 &&
|
|
requires { self->*m; }
|
|
)
|
|
{
|
|
return self->*m;
|
|
}
|
|
|
|
template<typename... Args>
|
|
constexpr auto invoke(auto&& f, Args&&... args)
|
|
requires requires {
|
|
f(ASL_FWD(args)...);
|
|
}
|
|
{
|
|
return ASL_FWD(f)(ASL_FWD(args)...);
|
|
}
|
|
|
|
template<typename F> struct _result_of_helper;
|
|
|
|
template<typename R, typename... Args>
|
|
struct _result_of_helper<R(Args...)>
|
|
{
|
|
using type = decltype(invoke(declval<R>(), declval<Args>()...));
|
|
};
|
|
|
|
template<typename F> using result_of_t = _result_of_helper<F>::type;
|
|
|
|
} // namespace asl
|