Fix function pointer semantics on coral::closure constructor
This commit is contained in:
parent
868297dfb7
commit
e379d1d9da
@ -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));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user