Merge pull request 'Replace `coral::callable` with `coral::closure`' (#9) from replace-callable into main
continuous-integration/drone/push Build is passing Details

Reviewed-on: #9
This commit is contained in:
kayomn 2023-02-23 16:12:29 +01:00
commit 388a98e654
4 changed files with 34 additions and 27 deletions

View File

@ -154,7 +154,7 @@ struct sandboxed_fs : public coral::fs {
return this->access_rules;
}
void read_file(coral::path const & file_path, coral::callable<void(coral::file_reader &)> const & then) override {
void read_file(coral::path const & file_path, coral::closure<void(coral::file_reader &)> const & then) override {
if (!this->access_rules.can_read) return;
native_path sandbox_file_path;
@ -183,7 +183,7 @@ struct sandboxed_fs : public coral::fs {
return;
}
void write_file(coral::path const & file_path, coral::callable<void(coral::file_writer &)> const & then) override {
void write_file(coral::path const & file_path, coral::closure<void(coral::file_writer &)> const & then) override {
if (!this->access_rules.can_write) return;
native_path sandbox_file_path;
@ -260,7 +260,7 @@ export namespace app {
return this->resources_archive;
}
static int run(coral::path const & title, coral::callable<int(client &)> const & start) {
static int run(coral::path const & title, coral::closure<int(client &)> const & start) {
constexpr int windowpos {SDL_WINDOWPOS_UNDEFINED};
constexpr coral::u32 windowflags {SDL_WINDOW_HIDDEN};
constexpr int window_width {640};

View File

@ -420,45 +420,52 @@ export namespace coral {
u8 buffer[buffer_size + 1];
};
template<typename> struct callable;
template<typename> struct closure;
/**
* Type-erasing wrapper for functor types that have a call operator with a return value
* matching `return_value` and arguments matching `argument_values`.
* 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 callable<returns(arguments...)> {
template<typename returns, typename... arguments> struct closure<returns(arguments...)> {
using function = returns(*)(arguments...);
callable(function callable_function) {
this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<function const *>(context))(dispatch_arguments...);
closure(function callable_function) {
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
return (reinterpret_cast<function const *>(context))(dispatch_arguments...);
};
new (this->capture) function{callable_function};
this->context = callable_function;
}
callable(callable const &) = delete;
template<typename functor> callable(functor const & callable_functor) {
static_assert(sizeof(functor) < capture_size);
this->dispatcher = [](u8 const * context, arguments... dispatch_arguments) -> returns {
template<typename functor> closure(functor * callable_functor) {
this->dispatch = [](void const * context, arguments... dispatch_arguments) -> returns {
return (*reinterpret_cast<functor const*>(context))(dispatch_arguments...);
};
new (this->capture) functor{callable_functor};
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->dispatcher(this->capture, call_arguments...);
return this->dispatch(this->context, call_arguments...);
}
private:
static constexpr usize capture_size = 24;
void const * context;
returns(* dispatcher)(u8 const *, arguments...);
u8 capture[capture_size];
returns(* dispatch)(void const *, arguments...);
};
/**

View File

@ -144,7 +144,7 @@ export namespace coral {
*
* Once `then` returns, access to the file is closed automatically.
*/
virtual void read_file(path const & file_path, callable<void(file_reader &)> const & then) = 0;
virtual void read_file(path const & file_path, closure<void(file_reader &)> const & then) = 0;
/**
* Attempts to write the file in the file system located at `file_path` relative, calling
@ -152,6 +152,6 @@ export namespace coral {
*
* Once `then` returns, access to the file is closed automatically.
*/
virtual void write_file(path const & file_path, callable<void(file_writer &)> const & then) = 0;
virtual void write_file(path const & file_path, closure<void(file_writer &)> const & then) = 0;
};
}

View File

@ -179,7 +179,7 @@ export namespace oar {
}
void read_file(coral::path const & file_path,
coral::callable<void(coral::file_reader &)> const & then) override {
coral::closure<void(coral::file_reader &)> const & then) override {
if ((this->backing_fs == nullptr) || (this->archive_path.byte_size() == 0)) return;
@ -195,7 +195,7 @@ export namespace oar {
}
void write_file(coral::path const & file_path,
coral::callable<void(coral::file_writer &)> const & then) override {
coral::closure<void(coral::file_writer &)> const & then) override {
// Read-only file system.
}