diff options
Diffstat (limited to 'libs/kstd/include')
| -rw-r--r-- | libs/kstd/include/kstd/bits/flat_map.hpp | 2 | ||||
| -rw-r--r-- | libs/kstd/include/kstd/bits/observer_ptr.hpp | 163 | ||||
| -rw-r--r-- | libs/kstd/include/kstd/bits/unique_ptr.hpp | 25 | ||||
| -rw-r--r-- | libs/kstd/include/kstd/memory | 9 | ||||
| -rw-r--r-- | libs/kstd/include/kstd/string | 13 |
5 files changed, 196 insertions, 16 deletions
diff --git a/libs/kstd/include/kstd/bits/flat_map.hpp b/libs/kstd/include/kstd/bits/flat_map.hpp index 9455549..fe46203 100644 --- a/libs/kstd/include/kstd/bits/flat_map.hpp +++ b/libs/kstd/include/kstd/bits/flat_map.hpp @@ -45,7 +45,7 @@ namespace kstd::bits template<std::size_t Index> requires(Index >= 0 && Index <= 1) - constexpr auto get() const noexcept -> decltype(auto) + [[nodiscard]] constexpr auto get() const noexcept -> decltype(auto) { if constexpr (Index == 0) { diff --git a/libs/kstd/include/kstd/bits/observer_ptr.hpp b/libs/kstd/include/kstd/bits/observer_ptr.hpp new file mode 100644 index 0000000..1c5da15 --- /dev/null +++ b/libs/kstd/include/kstd/bits/observer_ptr.hpp @@ -0,0 +1,163 @@ +#ifndef KSTD_OBSERVER_PTR_HPP +#define KSTD_OBSERVER_PTR_HPP + +// IWYU pragma: private, include <kstd/memory> + +#include "kstd/os/error.hpp" + +#include <compare> +#include <concepts> +#include <cstddef> +#include <type_traits> +#include <utility> + +namespace kstd +{ + + template<typename ElementType> + struct observer_ptr + { + //! The type of the element being pointed to. + using element_type = ElementType; + + //! Construct an empty observer pointer. + constexpr observer_ptr() noexcept = default; + + //! Construct an empty observer pointer from a null pointer. + constexpr observer_ptr(std::nullptr_t) noexcept {} + + //! Construct an observer pointer from a raw pointer. + constexpr explicit observer_ptr(element_type * pointer) + : m_ptr{pointer} + {} + + //! Construct an observer pointer from another observer pointer. + template<typename OtherElementType> + requires std::convertible_to<OtherElementType *, ElementType *> + constexpr observer_ptr(observer_ptr<OtherElementType> other) noexcept + : m_ptr{other.get()} + {} + + //! Copy construct an observer pointer. + constexpr observer_ptr(observer_ptr const & other) noexcept = default; + + //! Move construct an observer pointer. + constexpr observer_ptr(observer_ptr && other) noexcept = default; + + //! Copy assign an observer pointer. + constexpr auto operator=(observer_ptr const & other) noexcept -> observer_ptr & = default; + + //! Move assign an observer pointer. + constexpr auto operator=(observer_ptr && other) noexcept -> observer_ptr & = default; + + //! Stop watching the the watched object. + //! + //! @return The currently watched object, or nullptr if no object is being watched. + [[nodiscard]] constexpr auto release() noexcept -> element_type * + { + return std::exchange(m_ptr, nullptr); + } + + //! Reset the observer pointer. + //! + //! @param pointer The new object to watch. + constexpr auto reset(element_type * pointer = nullptr) noexcept -> void + { + m_ptr = pointer; + } + + //! Swap the observer pointer with another observer pointer. + //! + //! @param other The other observer pointer to swap with. + constexpr auto swap(observer_ptr & other) noexcept -> void + { + std::swap(m_ptr, other.m_ptr); + } + + //! Get the currently watched object. + //! + //! @return The currently watched object, or nullptr if no object is being watched. + [[nodiscard]] constexpr auto get() const noexcept -> element_type * + { + return m_ptr; + } + + //! Check if the observer pointer is watching an object. + //! + //! @return True if the observer pointer is watching an object, false otherwise. + [[nodiscard]] constexpr explicit operator bool() const noexcept + { + return m_ptr != nullptr; + } + + //! Get the currently watched object. + //! + //! @return A reference to the currently watched object. + [[nodiscard]] constexpr auto operator*() const -> std::add_lvalue_reference_t<element_type> + { + throw_on_null(); + return *m_ptr; + } + + //! Get the currently watched object. + //! + //! @return A pointer to the currently watched object. + [[nodiscard]] constexpr auto operator->() const -> element_type * + { + throw_on_null(); + return m_ptr; + } + + //! Convert the observer pointer to a raw pointer. + //! + //! @return A pointer to the currently watched object. + constexpr explicit operator element_type *() const noexcept + { + return m_ptr; + } + + //! Compare the observer pointer with another observer pointer. + //!> + //! @param other The other observer pointer to compare with. + //! @return The result of the comparison. + constexpr auto operator<=>(observer_ptr const & other) const noexcept -> std::strong_ordering = default; + + private: + //! Throw an exception if the observer pointer is null. + //! + //! @throws std::runtime_error if the observer pointer is null. + constexpr auto throw_on_null() const -> void + { + if (m_ptr == nullptr) + { + os::panic("[kstd:observer_ptr] Dereferencing a null observer pointer"); + } + } + + //! The raw pointer to the watched object. + ElementType * m_ptr{}; + }; + + //! Swap two observer pointers. + //! + //! @param lhs The first observer pointer to swap. + //! @param rhs The second observer pointer to swap. + template<typename ElementType> + constexpr auto swap(observer_ptr<ElementType> & lhs, observer_ptr<ElementType> & rhs) noexcept -> void + { + lhs.swap(rhs); + } + + //! Create an observer pointer from a raw pointer. + //! + //! @param pointer The raw pointer to create an observer pointer from. + //! @return An observer pointer to the given raw pointer. + template<typename ElementType> + constexpr auto make_observer(ElementType * pointer) noexcept -> observer_ptr<ElementType> + { + return observer_ptr<ElementType>{pointer}; + } + +} // 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 index e0870b1..3d803b4 100644 --- a/libs/kstd/include/kstd/bits/unique_ptr.hpp +++ b/libs/kstd/include/kstd/bits/unique_ptr.hpp @@ -16,6 +16,9 @@ namespace kstd template<typename T> struct unique_ptr { + template<typename U> + friend struct unique_ptr; + /** * @brief Constructor. * @@ -40,6 +43,12 @@ namespace kstd */ unique_ptr(unique_ptr const &) = delete; + template<typename U> + requires(std::is_convertible_v<U *, T *>) + unique_ptr(unique_ptr<U> && other) noexcept + : pointer{std::exchange(other.pointer, nullptr)} + {} + /** * @brief Deleted copy assignment operator to enforce unique ownership. */ @@ -51,10 +60,8 @@ namespace kstd * @param other Unique pointer to move from. */ unique_ptr(unique_ptr && other) noexcept - : pointer(other.pointer) - { - other.pointer = nullptr; - } + : pointer{std::exchange(other.pointer, nullptr)} + {} /** * @brief Move assignment operator. Transfers ownership from other to *this as if by calling reset(r.release()). @@ -67,8 +74,7 @@ namespace kstd if (this != &other) { delete pointer; - pointer = other.pointer; - other.pointer = nullptr; + pointer = std::exchange(other.pointer, nullptr); } return *this; } @@ -123,9 +129,7 @@ namespace kstd */ auto release() -> T * { - T * temp = pointer; - pointer = nullptr; - return temp; + return std::exchange(pointer, nullptr); } /** @@ -139,8 +143,7 @@ namespace kstd */ auto reset(T * ptr = nullptr) -> void { - delete pointer; - pointer = ptr; + delete std::exchange(pointer, ptr); } /** diff --git a/libs/kstd/include/kstd/memory b/libs/kstd/include/kstd/memory index cab2fba..493f49a 100644 --- a/libs/kstd/include/kstd/memory +++ b/libs/kstd/include/kstd/memory @@ -1,7 +1,8 @@ -#ifndef KSTD_SHARED_POINTER_HPP -#define KSTD_SHARED_POINTER_HPP +#ifndef KSTD_MEMORY_HPP +#define KSTD_MEMORY_HPP -#include "kstd/bits/shared_ptr.hpp" // IWYU pragma: export -#include "kstd/bits/unique_ptr.hpp" // IWYU pragma: export +#include "kstd/bits/observer_ptr.hpp" // IWYU pragma: export +#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/string b/libs/kstd/include/kstd/string index 075422e..4ce19ce 100644 --- a/libs/kstd/include/kstd/string +++ b/libs/kstd/include/kstd/string @@ -1,6 +1,10 @@ #ifndef KSTD_STRING_HPP #define KSTD_STRING_HPP +#include "kstd/bits/format/context.hpp" +#include "kstd/bits/format/formatter.hpp" +#include "kstd/bits/format/formatter/string_view.hpp" + #include <kstd/cstring> #include <kstd/os/error.hpp> #include <kstd/vector> @@ -343,6 +347,15 @@ namespace kstd return !(lhs == rhs); } + template<> + struct formatter<string> : formatter<std::string_view> + { + auto format(string const & str, format_context & context) const -> void + { + formatter<std::string_view>::format(str.view(), context); + } + }; + } // namespace kstd #endif
\ No newline at end of file |
