diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-17 00:21:48 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-17 22:29:50 +0100 |
commit | a141c401f78467bc15f62882fca5d55a007cacbb (patch) | |
tree | 908ac71a8640f78f45d22c6808c5fa6e373000fa /asl/base/functional.hpp | |
parent | cb77cbe9ce4cddad6a460aa190ff70f0c13e4703 (diff) |
Reorganize everything
Diffstat (limited to 'asl/base/functional.hpp')
-rw-r--r-- | asl/base/functional.hpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/asl/base/functional.hpp b/asl/base/functional.hpp new file mode 100644 index 0000000..d820bce --- /dev/null +++ b/asl/base/functional.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include "asl/base/meta.hpp" +#include "asl/base/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 |