From f9ac5831cf660398fee52e75c1e6de10c687ad7a Mon Sep 17 00:00:00 2001 From: kayomn Date: Wed, 22 Feb 2023 22:59:33 +0000 Subject: [PATCH] Improve compile-time safety of coral::callable --- source/coral.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/source/coral.cpp b/source/coral.cpp index 9705c49..1fcf1ea 100644 --- a/source/coral.cpp +++ b/source/coral.cpp @@ -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 struct callable { - using function = return_value(*)(argument_values...); + template struct callable { + using function = returns(*)(arguments...); callable(function callable_function) { - this->dispatcher = [](u8 const * userdata, argument_values... arguments) -> return_value { - return (*reinterpret_cast(userdata))(arguments...); + this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns { + return (*reinterpret_cast(context))(dispatch_arguments...); }; new (this->capture) function{callable_function}; @@ -440,21 +440,23 @@ export namespace coral { callable(callable const &) = delete; template callable(functor const & callable_functor) { - this->dispatcher = [](u8 const * userdata, argument_values... arguments) -> return_value { - return (*reinterpret_cast(userdata))(arguments...); + static_assert(sizeof(functor) < capture_size); + + this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns { + return (*reinterpret_cast(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]; };