From 4e99a7586748f9acd7027abc4c86a8df5f0c2e6f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 14 Jul 2025 20:26:05 +0000 Subject: kstd: improve resemblence of STL --- libs/kstd/include/kstd/bits/shared_ptr.hpp | 269 +++++++++++++++++++++++++++++ libs/kstd/include/kstd/bits/unique_ptr.hpp | 206 ++++++++++++++++++++++ libs/kstd/include/kstd/memory.hpp | 7 + libs/kstd/include/kstd/shared_pointer.hpp | 269 ----------------------------- libs/kstd/include/kstd/unique_pointer.hpp | 206 ---------------------- 5 files changed, 482 insertions(+), 475 deletions(-) create mode 100644 libs/kstd/include/kstd/bits/shared_ptr.hpp create mode 100644 libs/kstd/include/kstd/bits/unique_ptr.hpp create mode 100644 libs/kstd/include/kstd/memory.hpp delete mode 100644 libs/kstd/include/kstd/shared_pointer.hpp delete mode 100644 libs/kstd/include/kstd/unique_pointer.hpp (limited to 'libs') diff --git a/libs/kstd/include/kstd/bits/shared_ptr.hpp b/libs/kstd/include/kstd/bits/shared_ptr.hpp new file mode 100644 index 0000000..d41b165 --- /dev/null +++ b/libs/kstd/include/kstd/bits/shared_ptr.hpp @@ -0,0 +1,269 @@ +#ifndef KSTD_BITS_SHARED_PTR_HPP +#define KSTD_BITS_SHARED_PTR_HPP + +#include + +namespace kstd +{ + /** + * @brief Shared_pointer is a smart pointer that retains shared ownership of an object through a pointer. Several + * shared_ptr objects may own the same object. The object is destroyed and its memory deallocated when either of + * the following happens: the last remaining shared_ptr owning the object is destroyed; the last remaining + * shared_ptr owning the object is assigned another pointer via operator= or reset(). A + * shared_ptr can share ownership of an object while storing a pointer to another object. This feature can be used + * to point to member objects while owning the object they belong to. The stored pointer is the one accessed by get(), + * the dereference and the comparison operators. The managed pointer is the one passed to the deleter when use count + * reaches zero. + * + * @tparam T The type of the managed object. + */ + template + struct shared_ptr + { + /** + * @brief Constructor. + * + * @param pointer A pointer to an object to manage (default is nullptr). + */ + [[gnu::section(".stl_text")]] + explicit shared_ptr(T * pointer = nullptr) + : pointer(pointer) + , ref_count(new std::atomic(pointer != nullptr ? 1 : 0)) + { + // Nothing to do. + } + + /** + * @brief Copy constructor. + * + * @param other The shared_ptr to copy from. + */ + [[gnu::section(".stl_text")]] + shared_ptr(const shared_ptr & other) + : pointer(other.pointer) + , ref_count(other.ref_count) + { + if (pointer != nullptr) + { + ++(*ref_count); + } + } + + /** + * @brief Move constructor. + * + * @param other The shared_ptr to move from. + */ + [[gnu::section(".stl_text")]] + shared_ptr(shared_ptr && other) noexcept + : pointer(other.pointer) + , ref_count(other.ref_count) + { + other.pointer = nullptr; + other.ref_count = nullptr; + } + + /** + * @brief Copy assignment operator. Replaces the managed object with the one managed by r. Shares ownership of the + * object managed by r. If r manages no object, *this manages no object too. Equivalent to + * shared_ptr(r).swap(*this). + * + * @param other Another smart pointer to share the ownership with. + * @return Reference to this shared pointer. + */ + [[gnu::section(".stl_text")]] + shared_ptr & operator=(const shared_ptr & other) + { + if (this != &other) + { + cleanup(); + pointer = other.pointer; + ref_count = other.ref_count; + + if (pointer != nullptr) + { + ++(*ref_count); + } + } + + return *this; + } + + /** + * @brief Move assignment operator. Move-assigns a shared_ptr from r. After the assignment, *this contains a copy of + * the previous state of r, and r is empty. Equivalent to shared_ptr(std::move(r)).swap(*this). + * + * @param other Another smart pointer to acquire the ownership from. + * @return Reference to this shared pointer. + */ + [[gnu::section(".stl_text")]] + shared_ptr & operator=(shared_ptr && other) noexcept + { + if (this != &other) + { + cleanup(); + pointer = other.pointer; + ref_count = other.ref_count; + other.pointer = nullptr; + other.ref_count = nullptr; + } + + return *this; + } + + /** + * @brief Destructor. Cleans up resources if necessary. + */ + [[gnu::section(".stl_text")]] + ~shared_ptr() + { + cleanup(); + } + + /** + * @brief Replaces the managed object. + * + * @param ptr Pointer to a new object to manage (default = nullptr). + */ + [[gnu::section(".stl_text")]] + void reset(T * ptr = nullptr) + { + cleanup(); + pointer = ptr; + ref_count = new std::atomic(ptr != nullptr ? 1 : 0); + } + + /** + * @brief Exchanges the stored pointer values and the ownerships of *this and r. Reference counts, if any, are not + * adjusted. + * + * @param other The shared_ptr to swap with. + */ + [[gnu::section(".stl_text")]] + void swap(shared_ptr & other) + { + std::swap(pointer, other.pointer); + std::swap(ref_count, other.ref_count); + } + + /** + * @brief Dereference operator. If get() is a null pointer, the behavior is undefined. + * + * @return Returns the object owned by *this, equivalent to *get(). + */ + [[gnu::section(".stl_text")]] + auto operator*() const -> T & + { + return *pointer; + } + + /** + * @brief Member access operator. + * + * @return Returns a pointer to the object owned by *this, i.e. get(). + */ + [[gnu::section(".stl_text")]] + auto operator->() const -> T * + { + return pointer; + } + + /** + * @brief Returns a pointer to the managed object or nullptr if no object is owned. + * + * @return Pointer to the managed object or nullptr if no object is owned. + */ + [[gnu::section(".stl_text")]] + auto get() const -> T * + { + return pointer; + } + + /** + * @brief Returns the number of different shared_ptr instances (*this included) managing the current object. If + * there is no managed object, ​0​ is returned. + * + * @note Common use cases include comparison with ​0​. If use_count returns zero, the shared pointer is empty + * and manages no objects (whether or not its stored pointer is nullptr). Comparison with 1. If use_count returns 1, + * there are no other owners. + * + * @return The number of Shared_pointer instances managing the current object or ​0​ if there is no managed + * object. + */ + [[gnu::section(".stl_text")]] + auto use_count() const -> std::size_t + { + if (pointer != nullptr) + { + return *ref_count; + } + + return 0; + } + + /** + * @brief Checks whether *this owns an object, i.e. whether get() != nullptr. + * + * @return true if *this owns an object, false otherwise. + */ + [[gnu::section(".stl_text")]] + explicit operator bool() const + { + return pointer != nullptr; + } + + /** + * @brief Defaulted three-way comparator operator. + */ + [[gnu::section(".stl_text")]] + auto operator<=>(const shared_ptr & other) const = default; + + private: + /** + * @brief Releases ownership and deletes the object if this was the last ereference to the owned managed object. + */ + [[gnu::section(".stl_text")]] + auto cleanup() -> void + { + if (pointer != nullptr && ref_count != nullptr && --(*ref_count) == 0) + { + delete pointer; + delete ref_count; + } + } + + T * pointer; ///< The managed object. + std::atomic * ref_count; ///< Reference count. + }; + + /** + * @brief Specializes the std::swap algorithm for stl::unique_ptr. Swaps the contents of lhs and rhs. Calls + * lhs.swap(rhs). + * + * @tparam T Type of the managed object. + * @param lhs, rhs Smart pointers whose contents to swap. + */ + template + auto swap(shared_ptr & lhs, shared_ptr & rhs) -> void + { + lhs.swap(rhs); + } + + /** + * @brief Constructs an object of type T and wraps it in a shared_ptr. Constructs a non-array type T. The + * arguments args are passed to the constructor of T. This overload participates in overload resolution only if T is + * not an array type. The function is equivalent to: shared_ptr(new T(std::forward(args)...)). + * + * @tparam T Type of the managed object. + * @tparam Args Argument types for T's constructor. + * @param args List of arguments with which an instance of T will be constructed. + * @returns Shared_pointer of an instance of type T. + */ + template + auto make_shared(Args &&... args) -> shared_ptr + { + return shared_ptr(new T(std::forward(args)...)); + } +} // namespace kstd + +#endif \ No newline at end of file diff --git a/libs/kstd/include/kstd/bits/unique_ptr.hpp b/libs/kstd/include/kstd/bits/unique_ptr.hpp new file mode 100644 index 0000000..1932913 --- /dev/null +++ b/libs/kstd/include/kstd/bits/unique_ptr.hpp @@ -0,0 +1,206 @@ +#ifndef KSTD_BITS_UNIQUE_POINTER_HPP +#define KSTD_BITS_UNIQUE_POINTER_HPP + +#include + +namespace kstd +{ + /** + * @brief Unique_pointer is a smart pointer that owns (is responsible for) and manages another object via a pointer + * and subsequently disposes of that object when the unique_ptr goes out of scope. + * + * @tparam T Type of the managed object. + */ + template + struct unique_ptr + { + /** + * @brief Constructor. + * + * @param ptr A pointer to an object to manage (default is nullptr). + */ + [[gnu::section(".stl_text")]] + explicit unique_ptr(T * ptr = nullptr) + : pointer(ptr) + { + // Nothing to do. + } + + /** + * @brief Destructor that deletes the managed object. + */ + [[gnu::section(".stl_text")]] + ~unique_ptr() + { + delete pointer; + } + + /** + * @brief Deleted copy constructor to enforce unique ownership. + */ + unique_ptr(const unique_ptr &) = delete; + + /** + * @brief Deleted copy assignment operator to enforce unique ownership. + */ + auto operator=(const unique_ptr &) -> unique_ptr & = delete; + + /** + * @brief Move constructor. + * + * @param other Unique pointer to move from. + */ + [[gnu::section(".stl_text")]] + unique_ptr(unique_ptr && other) noexcept + : pointer(other.pointer) + { + other.pointer = nullptr; + } + + /** + * @brief Move assignment operator. Transfers ownership from other to *this as if by calling reset(r.release()). + * + * @param other Smart pointer from which ownership will be transferred. + * @return Reference to this unique pointer. + */ + [[gnu::section(".stl_text")]] + auto operator=(unique_ptr && other) noexcept -> unique_ptr & + { + if (this != &other) + { + delete pointer; + pointer = other.pointer; + other.pointer = nullptr; + } + return *this; + } + + /** + * @brief Dereference operator. If get() is a null pointer, the behavior is undefined. + * + * @return Returns the object owned by *this, equivalent to *get(). + */ + [[gnu::section(".stl_text")]] + auto operator*() const -> T & + { + return *pointer; + } + + /** + * @brief Member access operator. + * + * @return Returns a pointer to the object owned by *this, i.e. get(). + */ + [[gnu::section(".stl_text")]] + auto operator->() const -> T * + { + return pointer; + } + + /** + * @brief Returns a pointer to the managed object or nullptr if no object is owned. + * + * @return Pointer to the managed object or nullptr if no object is owned. + */ + [[gnu::section(".stl_text")]] + auto get() const -> T * + { + return pointer; + } + + /** + * @brief Checks whether *this owns an object, i.e. whether get() != nullptr. + * + * @return true if *this owns an object, false otherwise. + */ + [[gnu::section(".stl_text")]] + explicit operator bool() const noexcept + { + return pointer != nullptr; + } + + /** + * @brief Releases the ownership of the managed object, if any. + * get() returns nullptr after the call. + * The caller is responsible for cleaning up the object (e.g. by use of get_deleter()). + * + * @return Pointer to the managed object or nullptr if there was no managed object, i.e. the value which would be + * returned by get() before the call. + */ + [[gnu::section(".stl_text")]] + auto release() -> T * + { + T * temp = pointer; + pointer = nullptr; + return temp; + } + + /** + * @brief Replaces the managed object. + * + * @note A test for self-reset, i.e. whether ptr points to an object already managed by *this, is not performed, + * except where provided as a compiler extension or as a debugging assert. Note that code such as + * p.reset(p.release()) does not involve self-reset, only code like p.reset(p.get()) does. + * + * @param ptr Pointer to a new object to manage (default = nullptr). + */ + [[gnu::section(".stl_text")]] + auto reset(T * ptr = nullptr) -> void + { + delete pointer; + pointer = ptr; + } + + /** + * @brief Swaps the managed objects and associated deleters of *this and another unique_ptr object other. + * + * @param other Another unique_ptr object to swap the managed object and the deleter with. + */ + [[gnu::section(".stl_text")]] + auto swap(unique_ptr & other) -> void + { + using std::swap; + swap(pointer, other.pointer); + } + + /** + * @brief Defaulted three-way comparator operator. + */ + [[gnu::section(".stl_text")]] + auto operator<=>(const unique_ptr & other) const = default; + + private: + T * pointer; ///< The managed pointer. + }; + + /** + * @brief Specializes the std::swap algorithm for stl::unique_ptr. Swaps the contents of lhs and rhs. Calls + * lhs.swap(rhs). + * + * @tparam T Type of the managed object. + * @param lhs, rhs Smart pointers whose contents to swap. + */ + template + auto swap(unique_ptr & lhs, unique_ptr & rhs) -> void + { + lhs.swap(rhs); + } + + /** + * @brief Constructs an object of type T and wraps it in a unique_ptr. Constructs a non-array type T. The + * arguments args are passed to the constructor of T. This overload participates in overload resolution only if T is + * not an array type. The function is equivalent to: unique_ptr(new T(std::forward(args)...)). + * + * @tparam T Type of the managed object. + * @tparam Args Argument types for T's constructor. + * @param args List of arguments with which an instance of T will be constructed. + * @returns Unique_pointer of an instance of type T. + */ + template + auto make_unique(Args &&... args) -> unique_ptr + { + return unique_ptr(new T(std::forward(args)...)); + } +} // namespace kstd + +#endif \ No newline at end of file diff --git a/libs/kstd/include/kstd/memory.hpp b/libs/kstd/include/kstd/memory.hpp new file mode 100644 index 0000000..cab2fba --- /dev/null +++ b/libs/kstd/include/kstd/memory.hpp @@ -0,0 +1,7 @@ +#ifndef KSTD_SHARED_POINTER_HPP +#define KSTD_SHARED_POINTER_HPP + +#include "kstd/bits/shared_ptr.hpp" // IWYU pragma: export +#include "kstd/bits/unique_ptr.hpp" // IWYU pragma: export + +#endif \ No newline at end of file diff --git a/libs/kstd/include/kstd/shared_pointer.hpp b/libs/kstd/include/kstd/shared_pointer.hpp deleted file mode 100644 index 4717117..0000000 --- a/libs/kstd/include/kstd/shared_pointer.hpp +++ /dev/null @@ -1,269 +0,0 @@ -#ifndef KSTD_SHARED_POINTER_HPP -#define KSTD_SHARED_POINTER_HPP - -#include - -namespace kstd -{ - /** - * @brief Shared_pointer is a smart pointer that retains shared ownership of an object through a pointer. Several - * shared_pointer objects may own the same object. The object is destroyed and its memory deallocated when either of - * the following happens: the last remaining shared_pointer owning the object is destroyed; the last remaining - * shared_pointer owning the object is assigned another pointer via operator= or reset(). A - * shared_pointer can share ownership of an object while storing a pointer to another object. This feature can be used - * to point to member objects while owning the object they belong to. The stored pointer is the one accessed by get(), - * the dereference and the comparison operators. The managed pointer is the one passed to the deleter when use count - * reaches zero. - * - * @tparam T The type of the managed object. - */ - template - struct shared_pointer - { - /** - * @brief Constructor. - * - * @param pointer A pointer to an object to manage (default is nullptr). - */ - [[gnu::section(".stl_text")]] - explicit shared_pointer(T * pointer = nullptr) - : pointer(pointer) - , ref_count(new std::atomic(pointer != nullptr ? 1 : 0)) - { - // Nothing to do. - } - - /** - * @brief Copy constructor. - * - * @param other The shared_pointer to copy from. - */ - [[gnu::section(".stl_text")]] - shared_pointer(const shared_pointer & other) - : pointer(other.pointer) - , ref_count(other.ref_count) - { - if (pointer != nullptr) - { - ++(*ref_count); - } - } - - /** - * @brief Move constructor. - * - * @param other The shared_pointer to move from. - */ - [[gnu::section(".stl_text")]] - shared_pointer(shared_pointer && other) noexcept - : pointer(other.pointer) - , ref_count(other.ref_count) - { - other.pointer = nullptr; - other.ref_count = nullptr; - } - - /** - * @brief Copy assignment operator. Replaces the managed object with the one managed by r. Shares ownership of the - * object managed by r. If r manages no object, *this manages no object too. Equivalent to - * shared_ptr(r).swap(*this). - * - * @param other Another smart pointer to share the ownership with. - * @return Reference to this shared pointer. - */ - [[gnu::section(".stl_text")]] - shared_pointer & operator=(const shared_pointer & other) - { - if (this != &other) - { - cleanup(); - pointer = other.pointer; - ref_count = other.ref_count; - - if (pointer != nullptr) - { - ++(*ref_count); - } - } - - return *this; - } - - /** - * @brief Move assignment operator. Move-assigns a shared_ptr from r. After the assignment, *this contains a copy of - * the previous state of r, and r is empty. Equivalent to shared_ptr(std::move(r)).swap(*this). - * - * @param other Another smart pointer to acquire the ownership from. - * @return Reference to this shared pointer. - */ - [[gnu::section(".stl_text")]] - shared_pointer & operator=(shared_pointer && other) noexcept - { - if (this != &other) - { - cleanup(); - pointer = other.pointer; - ref_count = other.ref_count; - other.pointer = nullptr; - other.ref_count = nullptr; - } - - return *this; - } - - /** - * @brief Destructor. Cleans up resources if necessary. - */ - [[gnu::section(".stl_text")]] - ~shared_pointer() - { - cleanup(); - } - - /** - * @brief Replaces the managed object. - * - * @param ptr Pointer to a new object to manage (default = nullptr). - */ - [[gnu::section(".stl_text")]] - void reset(T * ptr = nullptr) - { - cleanup(); - pointer = ptr; - ref_count = new std::atomic(ptr != nullptr ? 1 : 0); - } - - /** - * @brief Exchanges the stored pointer values and the ownerships of *this and r. Reference counts, if any, are not - * adjusted. - * - * @param other The shared_pointer to swap with. - */ - [[gnu::section(".stl_text")]] - void swap(shared_pointer & other) - { - std::swap(pointer, other.pointer); - std::swap(ref_count, other.ref_count); - } - - /** - * @brief Dereference operator. If get() is a null pointer, the behavior is undefined. - * - * @return Returns the object owned by *this, equivalent to *get(). - */ - [[gnu::section(".stl_text")]] - auto operator*() const -> T & - { - return *pointer; - } - - /** - * @brief Member access operator. - * - * @return Returns a pointer to the object owned by *this, i.e. get(). - */ - [[gnu::section(".stl_text")]] - auto operator->() const -> T * - { - return pointer; - } - - /** - * @brief Returns a pointer to the managed object or nullptr if no object is owned. - * - * @return Pointer to the managed object or nullptr if no object is owned. - */ - [[gnu::section(".stl_text")]] - auto get() const -> T * - { - return pointer; - } - - /** - * @brief Returns the number of different shared_pointer instances (*this included) managing the current object. If - * there is no managed object, ​0​ is returned. - * - * @note Common use cases include comparison with ​0​. If use_count returns zero, the shared pointer is empty - * and manages no objects (whether or not its stored pointer is nullptr). Comparison with 1. If use_count returns 1, - * there are no other owners. - * - * @return The number of Shared_pointer instances managing the current object or ​0​ if there is no managed - * object. - */ - [[gnu::section(".stl_text")]] - auto use_count() const -> std::size_t - { - if (pointer != nullptr) - { - return *ref_count; - } - - return 0; - } - - /** - * @brief Checks whether *this owns an object, i.e. whether get() != nullptr. - * - * @return true if *this owns an object, false otherwise. - */ - [[gnu::section(".stl_text")]] - explicit operator bool() const - { - return pointer != nullptr; - } - - /** - * @brief Defaulted three-way comparator operator. - */ - [[gnu::section(".stl_text")]] - auto operator<=>(const shared_pointer & other) const = default; - - private: - /** - * @brief Releases ownership and deletes the object if this was the last ereference to the owned managed object. - */ - [[gnu::section(".stl_text")]] - auto cleanup() -> void - { - if (pointer != nullptr && ref_count != nullptr && --(*ref_count) == 0) - { - delete pointer; - delete ref_count; - } - } - - T * pointer; ///< The managed object. - std::atomic * ref_count; ///< Reference count. - }; - - /** - * @brief Specializes the std::swap algorithm for stl::unique_ptr. Swaps the contents of lhs and rhs. Calls - * lhs.swap(rhs). - * - * @tparam T Type of the managed object. - * @param lhs, rhs Smart pointers whose contents to swap. - */ - template - auto swap(shared_pointer & lhs, shared_pointer & rhs) -> void - { - lhs.swap(rhs); - } - - /** - * @brief Constructs an object of type T and wraps it in a shared_pointer. Constructs a non-array type T. The - * arguments args are passed to the constructor of T. This overload participates in overload resolution only if T is - * not an array type. The function is equivalent to: shared_pointer(new T(std::forward(args)...)). - * - * @tparam T Type of the managed object. - * @tparam Args Argument types for T's constructor. - * @param args List of arguments with which an instance of T will be constructed. - * @returns Shared_pointer of an instance of type T. - */ - template - auto make_shared(Args &&... args) -> shared_pointer - { - return shared_pointer(new T(std::forward(args)...)); - } -} // namespace kstd - -#endif \ No newline at end of file diff --git a/libs/kstd/include/kstd/unique_pointer.hpp b/libs/kstd/include/kstd/unique_pointer.hpp deleted file mode 100644 index 2861646..0000000 --- a/libs/kstd/include/kstd/unique_pointer.hpp +++ /dev/null @@ -1,206 +0,0 @@ -#ifndef KSTD_UNIQUE_POINTER_HPP -#define KSTD_UNIQUE_POINTER_HPP - -#include - -namespace kstd -{ - /** - * @brief Unique_pointer is a smart pointer that owns (is responsible for) and manages another object via a pointer - * and subsequently disposes of that object when the unique_pointer goes out of scope. - * - * @tparam T Type of the managed object. - */ - template - struct unique_pointer - { - /** - * @brief Constructor. - * - * @param ptr A pointer to an object to manage (default is nullptr). - */ - [[gnu::section(".stl_text")]] - explicit unique_pointer(T * ptr = nullptr) - : pointer(ptr) - { - // Nothing to do. - } - - /** - * @brief Destructor that deletes the managed object. - */ - [[gnu::section(".stl_text")]] - ~unique_pointer() - { - delete pointer; - } - - /** - * @brief Deleted copy constructor to enforce unique ownership. - */ - unique_pointer(const unique_pointer &) = delete; - - /** - * @brief Deleted copy assignment operator to enforce unique ownership. - */ - auto operator=(const unique_pointer &) -> unique_pointer & = delete; - - /** - * @brief Move constructor. - * - * @param other Unique pointer to move from. - */ - [[gnu::section(".stl_text")]] - unique_pointer(unique_pointer && other) noexcept - : pointer(other.pointer) - { - other.pointer = nullptr; - } - - /** - * @brief Move assignment operator. Transfers ownership from other to *this as if by calling reset(r.release()). - * - * @param other Smart pointer from which ownership will be transferred. - * @return Reference to this unique pointer. - */ - [[gnu::section(".stl_text")]] - auto operator=(unique_pointer && other) noexcept -> unique_pointer & - { - if (this != &other) - { - delete pointer; - pointer = other.pointer; - other.pointer = nullptr; - } - return *this; - } - - /** - * @brief Dereference operator. If get() is a null pointer, the behavior is undefined. - * - * @return Returns the object owned by *this, equivalent to *get(). - */ - [[gnu::section(".stl_text")]] - auto operator*() const -> T & - { - return *pointer; - } - - /** - * @brief Member access operator. - * - * @return Returns a pointer to the object owned by *this, i.e. get(). - */ - [[gnu::section(".stl_text")]] - auto operator->() const -> T * - { - return pointer; - } - - /** - * @brief Returns a pointer to the managed object or nullptr if no object is owned. - * - * @return Pointer to the managed object or nullptr if no object is owned. - */ - [[gnu::section(".stl_text")]] - auto get() const -> T * - { - return pointer; - } - - /** - * @brief Checks whether *this owns an object, i.e. whether get() != nullptr. - * - * @return true if *this owns an object, false otherwise. - */ - [[gnu::section(".stl_text")]] - explicit operator bool() const noexcept - { - return pointer != nullptr; - } - - /** - * @brief Releases the ownership of the managed object, if any. - * get() returns nullptr after the call. - * The caller is responsible for cleaning up the object (e.g. by use of get_deleter()). - * - * @return Pointer to the managed object or nullptr if there was no managed object, i.e. the value which would be - * returned by get() before the call. - */ - [[gnu::section(".stl_text")]] - auto release() -> T * - { - T * temp = pointer; - pointer = nullptr; - return temp; - } - - /** - * @brief Replaces the managed object. - * - * @note A test for self-reset, i.e. whether ptr points to an object already managed by *this, is not performed, - * except where provided as a compiler extension or as a debugging assert. Note that code such as - * p.reset(p.release()) does not involve self-reset, only code like p.reset(p.get()) does. - * - * @param ptr Pointer to a new object to manage (default = nullptr). - */ - [[gnu::section(".stl_text")]] - auto reset(T * ptr = nullptr) -> void - { - delete pointer; - pointer = ptr; - } - - /** - * @brief Swaps the managed objects and associated deleters of *this and another unique_ptr object other. - * - * @param other Another unique_ptr object to swap the managed object and the deleter with. - */ - [[gnu::section(".stl_text")]] - auto swap(unique_pointer & other) -> void - { - using std::swap; - swap(pointer, other.pointer); - } - - /** - * @brief Defaulted three-way comparator operator. - */ - [[gnu::section(".stl_text")]] - auto operator<=>(const unique_pointer & other) const = default; - - private: - T * pointer; ///< The managed pointer. - }; - - /** - * @brief Specializes the std::swap algorithm for stl::unique_ptr. Swaps the contents of lhs and rhs. Calls - * lhs.swap(rhs). - * - * @tparam T Type of the managed object. - * @param lhs, rhs Smart pointers whose contents to swap. - */ - template - auto swap(unique_pointer & lhs, unique_pointer & rhs) -> void - { - lhs.swap(rhs); - } - - /** - * @brief Constructs an object of type T and wraps it in a unique_pointer. Constructs a non-array type T. The - * arguments args are passed to the constructor of T. This overload participates in overload resolution only if T is - * not an array type. The function is equivalent to: unique_pointer(new T(std::forward(args)...)). - * - * @tparam T Type of the managed object. - * @tparam Args Argument types for T's constructor. - * @param args List of arguments with which an instance of T will be constructed. - * @returns Unique_pointer of an instance of type T. - */ - template - auto make_unique(Args &&... args) -> unique_pointer - { - return unique_pointer(new T(std::forward(args)...)); - } -} // namespace kstd - -#endif \ No newline at end of file -- cgit v1.2.3