Implement a generic forwarding function that replaces the manually written ones.

This commit is contained in:
King_DuckZ 2020-04-26 10:49:57 +02:00
parent 3142e4c4ce
commit 30975c1405

View file

@ -53,27 +53,21 @@ namespace wren {
define_method_info(resolve_module_fn, resolve_module, const char*, const char*, const char*); define_method_info(resolve_module_fn, resolve_module, const char*, const char*, const char*);
define_method_info(load_module_fn, load_module, char*, VM*, const char*); define_method_info(load_module_fn, load_module, char*, VM*, const char*);
namespace fwd { template <typename T, typename F> struct AnyFunctionWrap;
template <typename T> template <typename T, typename R, typename... Args>
inline void write_fn (Configuration& obj, VM* vm, const char* text) { struct AnyFunctionWrap<T, R(T::*)(Args...)> {
reinterpret_cast<T&>(obj).write_fn(vm, text); template <R(T::*M)(Args...)>
inline static R call(Configuration& obj, Args... args) {
return (reinterpret_cast<T&>(obj).*M)(args...);
} }
};
template <typename T> template <typename T, typename R, typename... Args>
inline void error_fn (Configuration& obj, VM* vm, ErrorType et, const char* module, int line, const char* message) { struct AnyFunctionWrap<T, R(*)(Args...)> {
reinterpret_cast<T&>(obj).error_fn(vm, et, module, line, message); template <R(*M)(Args...)>
inline static R call(Configuration&, Args... args) {
return (*M)(args...);
} }
};
template <typename T>
inline const char* resolve_module_fn (Configuration& obj, VM* vm, void* memory, std::size_t new_size) {
return reinterpret_cast<T&>(obj).resolve_module_fn(vm, memory, new_size);
}
template <typename T>
inline char* load_module_fn (Configuration& obj, VM* vm, const char* name) {
return reinterpret_cast<T&>(obj).load_module_fn(vm, name);
}
} //namespace fwd
} //namespace detail } //namespace detail
template <typename T> template <typename T>
@ -89,12 +83,12 @@ namespace wren {
ret.vm = this; ret.vm = this;
if constexpr (method_write::exists<T>::value) if constexpr (method_write::exists<T>::value)
ret.write_fn = &detail::fwd::write_fn<T>; ret.write_fn = &detail::AnyFunctionWrap<T, decltype(&T::write_fn)>::template call<&T::write_fn>;
else else
ret.write_fn = nullptr; ret.write_fn = nullptr;
if constexpr (method_error::exists<T>::value) if constexpr (method_error::exists<T>::value)
ret.error_fn = &detail::fwd::error_fn<T>; ret.error_fn = &detail::AnyFunctionWrap<T, decltype(&T::error_fn)>::template call<&T::error_fn>;
else else
ret.error_fn = nullptr; ret.error_fn = nullptr;
@ -105,12 +99,12 @@ namespace wren {
static_assert(not method_reallocate::exists<T>::value or method_reallocate::is_static<T>::value, "Realloc function must be a static function"); static_assert(not method_reallocate::exists<T>::value or method_reallocate::is_static<T>::value, "Realloc function must be a static function");
if constexpr (method_resolve_module::exists<T>::value) if constexpr (method_resolve_module::exists<T>::value)
ret.resolve_module_fn = &detail::fwd::resolve_module_fn<T>; ret.resolve_module_fn = &detail::AnyFunctionWrap<T, decltype(&T::resolve_module_fn)>::template call<&T::resolve_module_fn>;
else else
ret.resolve_module_fn = nullptr; ret.resolve_module_fn = nullptr;
if constexpr (method_load_module::exists<T>::value) if constexpr (method_load_module::exists<T>::value)
ret.load_module_fn = &detail::fwd::load_module_fn<T>; ret.load_module_fn = &detail::AnyFunctionWrap<T, decltype(&T::load_module_fn)>::template call<&T::load_module_fn>;
else else
ret.load_module_fn = nullptr; ret.load_module_fn = nullptr;