aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/util')
-rw-r--r--src/crepe/util/Private.h60
-rw-r--r--src/crepe/util/Private.hpp2
2 files changed, 59 insertions, 3 deletions
diff --git a/src/crepe/util/Private.h b/src/crepe/util/Private.h
index 62a2e1a..d725a5e 100644
--- a/src/crepe/util/Private.h
+++ b/src/crepe/util/Private.h
@@ -5,26 +5,82 @@
namespace crepe {
+/**
+ * \brief Utility for storing type hidden from user
+ *
+ * This class can be used to store types which cannot be used in the API directly due to header
+ * distribution limitations. This class is similar to `std::any`, but provides a method for
+ * retrieving a mutable reference to the stored object.
+ */
class Private {
public:
Private() = default;
~Private();
+ /**
+ * \name Copy
+ *
+ * \note These functions do not do anything, resulting in `*this` being an empty (default)
+ * instance.
+ *
+ * \{
+ */
Private(const Private &);
- Private(Private &&);
Private & operator=(const Private &);
+ //! \}
+ /**
+ * \name Move
+ *
+ * These functions actually move the stored type if present.
+ *
+ * \{
+ */
+ Private(Private &&);
Private & operator=(Private &&);
+ //! \}
+ /**
+ * \brief Get the stored object
+ *
+ * \tparam T Type of stored object
+ *
+ * \returns Mutable reference to stored object
+ *
+ * \throws std::out_of_range if this instance does not contain any object
+ * \throws std::logic_error if the stored type and requested type differ
+ */
template <typename T>
- T & get();
+ T & get() const;
+ /**
+ * \brief Create and store an arbitrary object
+ *
+ * \tparam T Type of object
+ * \tparam Args Perfect forwarding arguments
+ * \param args Perfect forwarding arguments
+ *
+ * All arguments to this function are forwarded using `std::forward` to the constructor of T.
+ *
+ * \returns Mutable reference to stored object
+ *
+ * \note If this instance already contained an object, this function implicitly destroys the
+ * previous object.
+ */
template <typename T, typename... Args>
T & set(Args &&... args);
+ /**
+ * \brief Check if this instance contains an object
+ *
+ * \returns `true` if this instance is empty, `false` if it contains an object
+ */
bool empty() const noexcept;
private:
+ //! Wrapper for destructor call of stored object type
std::function<void(void *)> destructor;
+ //! Stored object's type
std::type_index type = typeid(void);
+ //! Stored object
void * instance = nullptr;
};
diff --git a/src/crepe/util/Private.hpp b/src/crepe/util/Private.hpp
index 3a87a9f..b2174c0 100644
--- a/src/crepe/util/Private.hpp
+++ b/src/crepe/util/Private.hpp
@@ -18,7 +18,7 @@ T & Private::set(Args &&... args) {
}
template <typename T>
-T & Private::get() {
+T & Private::get() const {
using namespace std;
if (this->empty()) throw out_of_range("Private: get() called on empty object");
type_index requested_type = typeid(T);