aboutsummaryrefslogtreecommitdiff
path: root/libs/kstd/include
diff options
context:
space:
mode:
Diffstat (limited to 'libs/kstd/include')
-rw-r--r--libs/kstd/include/kstd/bits/flat_map.hpp2
-rw-r--r--libs/kstd/include/kstd/bits/observer_ptr.hpp163
-rw-r--r--libs/kstd/include/kstd/bits/unique_ptr.hpp25
-rw-r--r--libs/kstd/include/kstd/memory9
-rw-r--r--libs/kstd/include/kstd/string13
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