|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once |
|
|
|
#include <cstdint> |
|
#include <type_traits> |
|
#include <utility> |
|
|
|
namespace c10 { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename Fn> |
|
class function_ref; |
|
|
|
template <typename Ret, typename... Params> |
|
class function_ref<Ret(Params...)> { |
|
Ret (*callback)(intptr_t callable, Params... params) = nullptr; |
|
intptr_t callable; |
|
|
|
template <typename Callable> |
|
static Ret callback_fn(intptr_t callable, Params... params) { |
|
return (*reinterpret_cast<Callable*>(callable))(std::forward<Params>( |
|
params)...); |
|
} |
|
|
|
public: |
|
function_ref() = default; |
|
function_ref(std::nullptr_t) {} |
|
|
|
template <typename Callable> |
|
function_ref( |
|
Callable&& callable, |
|
typename std::enable_if<!std::is_same< |
|
typename std::remove_reference<Callable>::type, |
|
function_ref>::value>::type* = nullptr, |
|
typename std::enable_if<std::is_convertible< |
|
typename c10::invoke_result_t<Callable, Params...>, |
|
Ret>::value>::type* = nullptr) |
|
: callback(callback_fn<typename std::remove_reference<Callable>::type>), |
|
callable(reinterpret_cast<intptr_t>(&callable)) {} |
|
|
|
Ret operator()(Params... params) const { |
|
return callback(callable, std::forward<Params>(params)...); |
|
} |
|
|
|
operator bool() const { |
|
return callback; |
|
} |
|
}; |
|
|
|
} |
|
|