Skip to content

Commit

Permalink
refactor(hook): return hook pointer for lambdas
Browse files Browse the repository at this point in the history
  • Loading branch information
Curve committed Dec 25, 2023
1 parent b8abe1c commit 22e7bfa
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 23 deletions.
23 changes: 5 additions & 18 deletions include/lime/hooks/hook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
#include <cstdint>
#include <concepts>

#include <functional>
#include <tl/expected.hpp>
#include <boost/callable_traits.hpp>

namespace lime
{
Expand Down Expand Up @@ -47,39 +45,28 @@ namespace lime
concept Address = requires() { requires std::integral<T> || std::is_pointer_v<T>; };

template <typename Hook, typename Signature>
consteval auto lambda_target()
{
using args_t = boost::callable_traits::args_t<Signature>;
using rtn_t = boost::callable_traits::return_type_t<Signature>;

return std::apply(
[]<typename... T>(T &&...)
{
using func_t = std::function<rtn_t(Hook, T...)>;
return std::type_identity<func_t>{};
},
args_t{});
}
consteval auto lambda_target();

template <typename Hook, typename Signature>
using lambda_target_t = typename decltype(lambda_target<Hook, Signature>())::type;

template <typename Signature>
class hook : public hook_base
{
template <template <typename...> typename T>
using rtn_t = tl::expected<T<hook>, hook_error>;
using signature_t = std::conditional_t<std::is_pointer_v<Signature>, Signature, Signature *>;
using rtn_t = tl::expected<std::unique_ptr<hook>, hook_error>;

public:
signature_t original() const;

public:
template <Address Source, Address Target>
[[nodiscard]] static rtn_t create(Source source, Target target);
[[nodiscard]] static rtn_t<std::unique_ptr> create(Source source, Target target);

public:
template <Address Source>
static void create(Source source, lambda_target_t<hook *, Signature> &&target);
static rtn_t<std::add_pointer_t> create(Source source, lambda_target_t<hook *, Signature> &&target);
};
} // namespace lime

Expand Down
35 changes: 30 additions & 5 deletions include/lime/hooks/hook.inl
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@
#include "hook.hpp"

#include <cassert>
#include <functional>

#include <boost/callable_traits.hpp>

namespace lime
{
template <typename Hook, typename Signature>
consteval auto lambda_target()
{
using args_t = boost::callable_traits::args_t<Signature>;
using return_t = boost::callable_traits::return_type_t<Signature>;

return std::apply(
[]<typename... T>(T &&...)
{
using function_t = std::function<return_t(Hook, T...)>;
return std::type_identity<function_t>{};
},
args_t{});
}

template <typename Signature>
typename hook<Signature>::signature_t hook<Signature>::original() const
{
Expand All @@ -13,7 +31,7 @@ namespace lime

template <typename Signature>
template <Address Source, Address Target>
typename hook<Signature>::rtn_t hook<Signature>::create(Source source, Target target)
hook<Signature>::template rtn_t<std::unique_ptr> hook<Signature>::create(Source source, Target target)
{
auto source_address = reinterpret_cast<std::uintptr_t>(source);
auto target_address = reinterpret_cast<std::uintptr_t>(target);
Expand All @@ -31,7 +49,8 @@ namespace lime

template <typename Signature>
template <Address Source>
void hook<Signature>::create(Source source, lambda_target_t<hook *, Signature> &&target)
hook<Signature>::template rtn_t<std::add_pointer_t>
hook<Signature>::create(Source source, lambda_target_t<hook *, Signature> &&target)
{
using args_t = boost::callable_traits::args_t<Signature>;
using rtn_t = boost::callable_traits::return_type_t<Signature>;
Expand All @@ -49,9 +68,15 @@ namespace lime
},
args_t{});

auto _hook = create(source, +wrapper);
assert(_hook && "Failed to create hook");
auto result = create(source, static_cast<signature_t>(wrapper));

if (!result)
{
return tl::make_unexpected(result.error());
}

hook = result->release();

hook = _hook->release();
return hook;
}
} // namespace lime

0 comments on commit 22e7bfa

Please sign in to comment.