Add monadic test function to coral::expected
This commit is contained in:
parent
53ec658439
commit
2a0f821e64
107
source/coral.cpp
107
source/coral.cpp
|
@ -285,6 +285,54 @@ export void operator delete[](void * pointer, coral::allocator & allocator) {
|
||||||
|
|
||||||
// Wrapper types.
|
// Wrapper types.
|
||||||
export namespace coral {
|
export namespace coral {
|
||||||
|
template<typename> struct closure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type-erasing view wrapper for both function and functor types that have a call operator with
|
||||||
|
* a return value matching `return_value` and arguments matching `argument_values`.
|
||||||
|
*
|
||||||
|
* **Note**: closures take no ownership of allocated memory, making it the responsibility of
|
||||||
|
* the caller to manage the lifetime of any functor assigned to it.
|
||||||
|
*/
|
||||||
|
template<typename returns, typename... arguments> struct closure<returns(arguments...)> {
|
||||||
|
using function = returns(*)(arguments...);
|
||||||
|
|
||||||
|
closure(function callable_function) {
|
||||||
|
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
|
||||||
|
return (reinterpret_cast<function const *>(context))(dispatch_arguments...);
|
||||||
|
};
|
||||||
|
|
||||||
|
this->context = callable_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
return this->dispatch(this->context, call_arguments...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void const * context;
|
||||||
|
|
||||||
|
returns(* dispatch)(void const *, arguments...);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monadic container for a single-`element` value or nothing.
|
* Monadic container for a single-`element` value or nothing.
|
||||||
*/
|
*/
|
||||||
|
@ -359,6 +407,17 @@ export namespace coral {
|
||||||
(*reinterpret_cast<error_element *>(this->buffer)) = error;
|
(*reinterpret_cast<error_element *>(this->buffer)) = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monadic function for calling `predicate` conditionally based on whether the expected is
|
||||||
|
* ok. If ok, the result of `predicate` is returned, otherwise `false` is always returned.
|
||||||
|
*
|
||||||
|
* This function may be used to chain conditional checks that depend on the expected being
|
||||||
|
* ok without creating a new local variable.
|
||||||
|
*/
|
||||||
|
bool and_test(closure<bool(value_element const &)> const & predicate) const {
|
||||||
|
return this->is_ok() && predicate(this->value());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the optional contains a value, otherwise `false` if it holds an error.
|
* Returns `true` if the optional contains a value, otherwise `false` if it holds an error.
|
||||||
*/
|
*/
|
||||||
|
@ -420,54 +479,6 @@ export namespace coral {
|
||||||
u8 buffer[buffer_size + 1];
|
u8 buffer[buffer_size + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename> struct closure;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type-erasing view wrapper for both function and functor types that have a call operator with
|
|
||||||
* a return value matching `return_value` and arguments matching `argument_values`.
|
|
||||||
*
|
|
||||||
* **Note**: closures take no ownership of allocated memory, making it the responsibility of
|
|
||||||
* the caller to manage the lifetime of any functor assigned to it.
|
|
||||||
*/
|
|
||||||
template<typename returns, typename... arguments> struct closure<returns(arguments...)> {
|
|
||||||
using function = returns(*)(arguments...);
|
|
||||||
|
|
||||||
closure(function callable_function) {
|
|
||||||
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
|
|
||||||
return (reinterpret_cast<function const *>(context))(dispatch_arguments...);
|
|
||||||
};
|
|
||||||
|
|
||||||
this->context = callable_function;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
return this->dispatch(this->context, call_arguments...);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void const * context;
|
|
||||||
|
|
||||||
returns(* dispatch)(void const *, arguments...);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Errors that may occur while executing an opaque I/O operation via the `readable` and
|
* Errors that may occur while executing an opaque I/O operation via the `readable` and
|
||||||
* `writable` type aliases.
|
* `writable` type aliases.
|
||||||
|
|
Loading…
Reference in New Issue