Fix function pointer semantics on coral::closure constructor

This commit is contained in:
kayomn 2023-02-25 18:14:46 +00:00
parent 868297dfb7
commit e379d1d9da

View File

@ -313,10 +313,10 @@ export namespace coral {
template<typename returns, typename... arguments> struct closure<returns(arguments...)> {
template<typename callable> closure(callable call) requires function_pointer<callable, arguments...> {
this->dispatch = [](void * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<callable *>(context))(dispatch_arguments...);
return (reinterpret_cast<callable>(context))(dispatch_arguments...);
};
this->context = reinterpret_cast<void *&>(call);
this->context = reinterpret_cast<void *>(call);
}
template<typename callable> closure(callable && call) requires functor<callable, arguments...> {
@ -347,67 +347,6 @@ export namespace coral {
return value;
}
/**
* Monadic container for a single-`element` value or nothing.
*/
template<typename element> struct [[nodiscard]] optional {
optional() : buffer{0} {}
optional(element const & value) : buffer{0} {
(*reinterpret_cast<element *>(this->buffer)) = value;
this->buffer[sizeof(element)] = 1;
}
optional(optional const & that) : buffer{0} {
if (that.has_value()) {
(*reinterpret_cast<element *>(this->buffer)) = *that;
this->buffer[sizeof(element)] = 1;
} else {
this->buffer[sizeof(element)] = 0;
}
}
/**
* Returns `true` if the optional contains a value, otherwise `false`.
*/
bool has_value() const {
return this->buffer[sizeof(element)] == 1;
}
/**
* Attempts to call `apply` on the contained value, returning a new [optional] of whatever type `apply` returns.
*
* If the optional is empty, an empty optional will always be returned.
*/
template<typename functor> std::invoke_result_t<functor, element> map(functor const & apply) const {
if (this->has_value()) return apply(**this);
return {};
}
/**
* Returns the contained value or `fallback` if the optional is empty.
*/
element const & value_or(element const & fallback) const {
return this->has_value() ? *reinterpret_cast<element const *>(this->buffer) : fallback;
}
element & operator *() {
if (!this->has_value()) unreachable();
return *reinterpret_cast<element *>(this->buffer);
}
element const & operator *() const {
if (!this->has_value()) unreachable();
return *reinterpret_cast<element const *>(this->buffer);
}
private:
u8 buffer[sizeof(element) + 1];
};
/**
* Monadic container for a descriminating union of either `value_element` or `error_element`.
*/
@ -487,6 +426,12 @@ export namespace coral {
return *reinterpret_cast<error_element const *>(this->buffer);
}
template<typename returns> expected<returns, error_element> map(closure<returns(value_element const &)> const & apply) const {
if (this->is_ok()) return apply(this->value());
return this->error();
}
private:
static constexpr usize buffer_size = max(sizeof(value_element), sizeof(error_element));