Files
asl/asl/functional.hpp

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