#ifndef ELFSPY_LAMBDA_H #define ELFSPY_LAMBDA_H #include #include namespace spy { extern std::vector hook_list; /** * @namespace spy * @class Lambda * This replaces an existing function with a lambda, so that all calls to * the program are made to the lambda. * The constructor installs the lambda in place of the function, the destructor * uninstalls it */ template class Lambda : public IHook { public: Lambda(H& hook, L& lambda); ~Lambda(); private: static ReturnType function(ArgTypes... argtypes); H& hook_; L lambda_; static Lambda* instance_; ReturnType (*func_)(ArgTypes...); }; template Lambda* Lambda::instance_ = nullptr; template inline Lambda::Lambda(H& hook, L& lambda) :hook_(hook) ,lambda_(lambda) { instance_ = this; func_ = hook.patch(&Lambda::function); } template inline Lambda::~Lambda() { hook_.patch(func_); instance_ = nullptr; } template ReturnType Lambda::function(ArgTypes... argtypes) { return instance_->lambda_(std::forward(argtypes)...); } template inline auto new_fake(H& hook, L& lambda) -> typename H::template Export::Type* { using Install = typename H::template Export::Type; auto instance = new Install(hook, lambda); hook_list.push_back (instance); return instance; } } // namespace elfspy #endif