Improve compile-time safety of coral::callable
continuous-integration/drone/push Build is failing Details

This commit is contained in:
kayomn 2023-02-22 22:59:33 +00:00
parent 02d4d56f35
commit f9ac5831cf
1 changed files with 11 additions and 9 deletions

View File

@ -426,12 +426,12 @@ export namespace coral {
* Type-erasing wrapper for functor types that have a call operator with a return value
* matching `return_value` and arguments matching `argument_values`.
*/
template<typename return_value, typename... argument_values> struct callable<return_value(argument_values...)> {
using function = return_value(*)(argument_values...);
template<typename returns, typename... arguments> struct callable<returns(arguments...)> {
using function = returns(*)(arguments...);
callable(function callable_function) {
this->dispatcher = [](u8 const * userdata, argument_values... arguments) -> return_value {
return (*reinterpret_cast<function const *>(userdata))(arguments...);
this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<function const *>(context))(dispatch_arguments...);
};
new (this->capture) function{callable_function};
@ -440,21 +440,23 @@ export namespace coral {
callable(callable const &) = delete;
template<typename functor> callable(functor const & callable_functor) {
this->dispatcher = [](u8 const * userdata, argument_values... arguments) -> return_value {
return (*reinterpret_cast<functor const*>(userdata))(arguments...);
static_assert(sizeof(functor) < capture_size);
this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...);
};
new (this->capture) functor{callable_functor};
}
return_value operator()(argument_values const &... arguments) const {
return this->dispatcher(this->capture, arguments...);
returns operator()(arguments const &... call_arguments) const {
return this->dispatcher(this->capture, call_arguments...);
}
private:
static constexpr usize capture_size = 24;
return_value(* dispatcher)(u8 const * userdata, argument_values... arguments);
returns(* dispatcher)(u8 const *, arguments...);
u8 capture[capture_size];
};