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 returns, typename... arguments> struct closure<returns(arguments...)> {
|
||||||
template<typename callable> closure(callable call) requires function_pointer<callable, arguments...> {
|
template<typename callable> closure(callable call) requires function_pointer<callable, arguments...> {
|
||||||
this->dispatch = [](void * context, arguments... dispatch_arguments) -> returns {
|
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...> {
|
template<typename callable> closure(callable && call) requires functor<callable, arguments...> {
|
||||||
@ -347,67 +347,6 @@ export namespace coral {
|
|||||||
return value;
|
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`.
|
* 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);
|
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:
|
private:
|
||||||
static constexpr usize buffer_size = max(sizeof(value_element), sizeof(error_element));
|
static constexpr usize buffer_size = max(sizeof(value_element), sizeof(error_element));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user