From c59d460f12e1393e0ddbaaa1c6f5522eb12f8ff9 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Fri, 29 Nov 2024 16:23:52 +0100 Subject: more utility classes for Audio system --- src/crepe/util/CMakeLists.txt | 3 +++ src/crepe/util/Private.cpp | 29 +++++++++++++++++++++++++++++ src/crepe/util/Private.h | 34 ++++++++++++++++++++++++++++++++++ src/crepe/util/Private.hpp | 31 +++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 src/crepe/util/Private.cpp create mode 100644 src/crepe/util/Private.h create mode 100644 src/crepe/util/Private.hpp (limited to 'src/crepe/util') diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt index 94ed906..f49d851 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(crepe PUBLIC LogColor.cpp Log.cpp + Private.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -11,5 +12,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES Proxy.hpp OptionalRef.h OptionalRef.hpp + Private.h + Private.hpp ) diff --git a/src/crepe/util/Private.cpp b/src/crepe/util/Private.cpp new file mode 100644 index 0000000..c5b5b30 --- /dev/null +++ b/src/crepe/util/Private.cpp @@ -0,0 +1,29 @@ +#include "Private.h" + +using namespace crepe; + +bool Private::empty() const noexcept { + return this->instance == nullptr; +} + +Private::~Private() { + if (this->instance == nullptr) return; + this->destructor(this->instance); +} + +Private::Private(Private && other) { + *this = std::move(other); +} + +Private & Private::operator=(Private && other) { + // TODO: ideally this function checks for self-assignment + this->instance = other.instance; + this->destructor = other.destructor; + this->type = other.type; + + other.instance = nullptr; + other.destructor = [](void*){}; + + return *this; +} + diff --git a/src/crepe/util/Private.h b/src/crepe/util/Private.h new file mode 100644 index 0000000..fc3728f --- /dev/null +++ b/src/crepe/util/Private.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +namespace crepe { + +class Private { +public: + Private() = default; + ~Private(); + Private(Private &&); + Private & operator=(Private &&); + Private(const Private &) = delete; + Private & operator=(const Private &) = delete; + + template + T & get(); + + template + void set(Args &&... args); + + bool empty() const noexcept; + +private: + std::function destructor; + std::type_index type = typeid(void); + void * instance = nullptr; +}; + +} + +#include "Private.hpp" + diff --git a/src/crepe/util/Private.hpp b/src/crepe/util/Private.hpp new file mode 100644 index 0000000..30c8146 --- /dev/null +++ b/src/crepe/util/Private.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include "Private.h" + +namespace crepe { + +template +void Private::set(Args &&... args) { + T * instance = new T(std::forward(args)...); + this->instance = static_cast(instance); + this->destructor = [](void * instance) { + delete static_cast(instance); + }; + this->type = typeid(T); +} + +template +T & Private::get() { + using namespace std; + if (this->empty()) + throw out_of_range("Private: get() called on empty object"); + type_index requested_type = typeid(T); + if (this->type != requested_type) + throw logic_error(format("Private: get() called with [T = {}] (actual is [T = {}])", requested_type.name(), this->type.name())); + return *static_cast(this->instance); +} + +} -- cgit v1.2.3