diff options
Diffstat (limited to 'src/crepe/util')
-rw-r--r-- | src/crepe/util/Private.h | 60 | ||||
-rw-r--r-- | src/crepe/util/Private.hpp | 2 |
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); |