Fix constructor ambiguity in coral::closure

This commit is contained in:
kayomn 2023-02-24 22:21:06 +00:00
parent 7a6731df8e
commit ea75a4f96e

View File

@ -3,6 +3,7 @@ module;
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
#include <type_traits> #include <type_traits>
#include <concepts>
export module coral; export module coral;
@ -285,6 +286,15 @@ export void operator delete[](void * pointer, coral::allocator & allocator) {
// Wrapper types. // Wrapper types.
export namespace coral { export namespace coral {
template<typename type, typename... arguments> concept function_pointer = requires (type value, arguments... value_arguments) {
{*value};
{value(value_arguments...)};
};
template<typename type, typename... arguments> concept functor = requires (type value, arguments... value_arguments) {
{value.operator()(value_arguments...)};
};
template<typename> struct closure; template<typename> struct closure;
/** /**
@ -295,42 +305,32 @@ export namespace coral {
* the caller to manage the lifetime of any functor assigned to it. * the caller to manage the lifetime of any functor assigned to it.
*/ */
template<typename returns, typename... arguments> struct closure<returns(arguments...)> { template<typename returns, typename... arguments> struct closure<returns(arguments...)> {
using function = returns(*)(arguments...); template<typename callable> closure(callable const & call) requires function_pointer<callable, arguments...> {
this->dispatch = [](void * context, arguments... dispatch_arguments) -> returns {
closure(function callable_function) { return (*reinterpret_cast<callable *>(context))(dispatch_arguments...);
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
return (reinterpret_cast<function const *>(context))(dispatch_arguments...);
}; };
this->context = callable_function; this->context = reinterpret_cast<void *&>(call);
} }
template<typename functor> closure(functor * callable_functor) { template<typename callable> closure(callable && call) requires functor<callable, arguments...> {
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns { this->dispatch = [](void * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...); return (*reinterpret_cast<callable *>(context))(dispatch_arguments...);
}; };
this->context = callable_functor; this->context = &call;
} }
closure(closure const &) = delete; closure(closure const &) = delete;
template<typename functor> closure(functor && callable_functor) {
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...);
};
this->context = &callable_functor;
}
returns operator()(arguments const &... call_arguments) const { returns operator()(arguments const &... call_arguments) const {
return this->dispatch(this->context, call_arguments...); return this->dispatch(this->context, call_arguments...);
} }
private: private:
void const * context; void * context;
returns(* dispatch)(void const *, arguments...); returns(* dispatch)(void *, arguments...);
}; };
/** /**