aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2025-03-09 16:52:17 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2025-03-09 16:52:17 +0000
commit1a6d41362447531a2ea5ee344c15b9aaa6c2090a (patch)
treeedeeb090b4948cdb7646071f19416cfd4ab411ea /arch/x86_64/include
parent06d5e5872838bd1528493b62b4dc28d44b54aa47 (diff)
downloadteachos-1a6d41362447531a2ea5ee344c15b9aaa6c2090a.tar.xz
teachos-1a6d41362447531a2ea5ee344c15b9aaa6c2090a.zip
Adjust comments and implement remaining interface for STL classes.
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/arch/stl/shared_pointer.hpp142
-rw-r--r--arch/x86_64/include/arch/stl/unique_pointer.hpp96
-rw-r--r--arch/x86_64/include/arch/stl/vector.hpp18
3 files changed, 162 insertions, 94 deletions
diff --git a/arch/x86_64/include/arch/stl/shared_pointer.hpp b/arch/x86_64/include/arch/stl/shared_pointer.hpp
index 80ca7fe..1ddc182 100644
--- a/arch/x86_64/include/arch/stl/shared_pointer.hpp
+++ b/arch/x86_64/include/arch/stl/shared_pointer.hpp
@@ -6,10 +6,14 @@
namespace teachos::arch::stl
{
/**
- * @brief A simple implementation of a shared pointer.
- *
- * This class provides reference counting and automatic resource management
- * for dynamically allocated objects.
+ * @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.
*/
@@ -17,14 +21,15 @@ namespace teachos::arch::stl
struct shared_pointer
{
/**
- * @brief Constructs a shared pointer.
+ * @brief Constructor.
*
- * @param pointer Raw pointer to manage (default is nullptr).
+ * @param pointer A pointer to an object to manage (default is nullptr).
*/
explicit shared_pointer(T * pointer = nullptr)
: pointer(pointer)
- , ref_count(new std::atomic<int>(pointer != nullptr ? 1 : 0))
+ , ref_count(new std::atomic<std::size_t>(pointer != nullptr ? 1 : 0))
{
+ // Nothing to do.
}
/**
@@ -56,10 +61,12 @@ namespace teachos::arch::stl
}
/**
- * @brief Copy assignment operator.
+ * @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<T>(r).swap(*this).
*
- * @param other The shared_pointer to copy from.
- * @return Reference to this shared_pointer.
+ * @param other Another smart pointer to share the ownership with.
+ * @return Reference to this shared pointer.
*/
shared_pointer & operator=(const shared_pointer & other)
{
@@ -79,10 +86,11 @@ namespace teachos::arch::stl
}
/**
- * @brief Move assignment operator.
+ * @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<T>(std::move(r)).swap(*this).
*
- * @param other The shared_pointer to move from.
- * @return Reference to this shared_pointer.
+ * @param other Another smart pointer to acquire the ownership from.
+ * @return Reference to this shared pointer.
*/
shared_pointer & operator=(shared_pointer && other) noexcept
{
@@ -104,31 +112,20 @@ namespace teachos::arch::stl
~shared_pointer() { cleanup(); }
/**
- * @brief Releases ownership and deletes the object if necessary.
- */
- void cleanup()
- {
- if (pointer != nullptr && ref_count != nullptr && --(*ref_count) == 0)
- {
- delete pointer;
- delete ref_count;
- }
- }
-
- /**
- * @brief Resets the shared pointer with a new raw pointer.
+ * @brief Replaces the managed object.
*
- * @param p New raw pointer (default is nullptr).
+ * @param ptr Pointer to a new object to manage (default = nullptr).
*/
- void reset(T * p = nullptr)
+ void reset(T * ptr = nullptr)
{
cleanup();
- pointer = p;
- ref_count = new std::atomic<int>(p != nullptr ? 1 : 0);
+ pointer = ptr;
+ ref_count = new std::atomic<std::size_t>(ptr != nullptr ? 1 : 0);
}
/**
- * @brief Swaps the contents of this shared pointer with another.
+ * @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.
*/
@@ -139,32 +136,38 @@ namespace teachos::arch::stl
}
/**
- * @brief Dereference operator.
+ * @brief Dereference operator. If get() is a null pointer, the behavior is undefined.
*
- * @return Reference to the managed object.
+ * @return Returns the object owned by *this, equivalent to *get().
*/
- T & operator*() const { return *pointer; }
+ auto operator*() const -> T & { return *pointer; }
/**
* @brief Member access operator.
*
- * @return Pointer to the managed object.
+ * @return Returns a pointer to the object owned by *this, i.e. get().
*/
- T * operator->() const { return pointer; }
+ auto operator->() const -> T * { return pointer; }
/**
- * @brief Returns the raw pointer.
+ * @brief Returns a pointer to the managed object or nullptr if no object is owned.
*
- * @return Pointer to the managed object.
+ * @return Pointer to the managed object or nullptr if no object is owned.
*/
- T * get() const { return pointer; }
+ auto get() const -> T * { return pointer; }
/**
- * @brief Returns the reference count.
+ * @brief Returns the number of different shared_pointer instances (*this included) managing the current object. If
+ * there is no managed object, ​0​ is returned.
*
- * @return Number of shared_pointer instances managing the same object.
+ * @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.
*/
- int use_count() const
+ auto use_count() const -> std::size_t
{
if (pointer != nullptr)
{
@@ -175,34 +178,59 @@ namespace teachos::arch::stl
}
/**
- * @brief Checks if this is the only shared pointer managing the object.
+ * @brief Checks whether *this owns an object, i.e. whether get() != nullptr.
*
- * @return True if the use count is 1, otherwise false.
+ * @return true if *this owns an object, false otherwise.
*/
- bool unique() const { return use_count() == 1; }
+ explicit operator bool() const { return pointer != nullptr; }
/**
- * @brief Checks if the shared pointer is not empty.
- *
- * @return True if the pointer is not null, otherwise false.
+ * @brief Defaulted three-way comparator operator.
*/
- explicit operator bool() const { return pointer != nullptr; }
+ auto operator<=>(const shared_pointer & other) const = default;
private:
- T * pointer; ///< The managed object.
- std::atomic<int> * ref_count; ///< Reference count.
+ /**
+ * @brief Releases ownership and deletes the object if this was the last ereference to the owned managed object.
+ */
+ auto cleanup() -> void
+ {
+ if (pointer != nullptr && ref_count != nullptr && --(*ref_count) == 0)
+ {
+ delete pointer;
+ delete ref_count;
+ }
+ }
+
+ T * pointer; ///< The managed object.
+ std::atomic<std::size_t> * ref_count; ///< Reference count.
};
/**
- * @brief Creates a shared pointer instance.
+ * @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<typename T>
+ auto swap(shared_pointer<T> & lhs, shared_pointer<T> & 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<T>(new T(std::forward<Args>(args)...)).
*
- * @tparam T The type of object to allocate.
- * @tparam Args Argument types for the constructor of T.
- * @param args Arguments for the constructor of T.
- * @return A shared_pointer instance managing a newly created object.
+ * @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<typename T, typename... Args>
- shared_pointer<T> make_shared(Args &&... args)
+ auto make_shared(Args &&... args) -> shared_pointer<T>
{
return shared_pointer<T>(new T(std::forward<Args>(args)...));
}
diff --git a/arch/x86_64/include/arch/stl/unique_pointer.hpp b/arch/x86_64/include/arch/stl/unique_pointer.hpp
index 08c862d..899a35b 100644
--- a/arch/x86_64/include/arch/stl/unique_pointer.hpp
+++ b/arch/x86_64/include/arch/stl/unique_pointer.hpp
@@ -4,7 +4,8 @@
namespace teachos::arch::stl
{
/**
- * @brief A simple unique pointer implementation.
+ * @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.
*/
@@ -12,13 +13,14 @@ namespace teachos::arch::stl
struct unique_pointer
{
/**
- * @brief Constructs a unique pointer.
+ * @brief Constructor.
*
- * @param ptr Pointer to manage, default is nullptr.
+ * @param ptr A pointer to an object to manage (default is nullptr).
*/
explicit unique_pointer(T * ptr = nullptr)
: pointer(ptr)
{
+ // Nothing to do.
}
/**
@@ -34,7 +36,7 @@ namespace teachos::arch::stl
/**
* @brief Deleted copy assignment operator to enforce unique ownership.
*/
- unique_pointer & operator=(const unique_pointer &) = delete;
+ auto operator=(const unique_pointer &) -> unique_pointer & = delete;
/**
* @brief Move constructor.
@@ -48,12 +50,12 @@ namespace teachos::arch::stl
}
/**
- * @brief Move assignment operator.
+ * @brief Move assignment operator. Transfers ownership from other to *this as if by calling reset(r.release()).
*
- * @param other Unique pointer to move from.
+ * @param other Smart pointer from which ownership will be transferred.
* @return Reference to this unique pointer.
*/
- unique_pointer & operator=(unique_pointer && other) noexcept
+ auto operator=(unique_pointer && other) noexcept -> unique_pointer &
{
if (this != &other)
{
@@ -65,32 +67,42 @@ namespace teachos::arch::stl
}
/**
- * @brief Dereference operator.
+ * @brief Dereference operator. If get() is a null pointer, the behavior is undefined.
*
- * @return Reference to the managed object.
+ * @return Returns the object owned by *this, equivalent to *get().
*/
- T & operator*() const { return *pointer; }
+ auto operator*() const -> T & { return *pointer; }
/**
* @brief Member access operator.
*
- * @return Pointer to the managed object.
+ * @return Returns a pointer to the object owned by *this, i.e. get().
+ */
+ 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.
*/
- T * operator->() const { return pointer; }
+ auto get() const -> T * { return pointer; }
/**
- * @brief Gets the raw pointer.
+ * @brief Checks whether *this owns an object, i.e. whether get() != nullptr.
*
- * @return The managed pointer.
+ * @return true if *this owns an object, false otherwise.
*/
- T * get() const { return pointer; }
+ explicit operator bool() const noexcept { return pointer != nullptr; }
/**
- * @brief Releases ownership of the managed object.
+ * @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 The raw pointer and sets internal pointer to nullptr.
+ * @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.
*/
- T * release()
+ auto release() -> T *
{
T * temp = pointer;
pointer = nullptr;
@@ -98,37 +110,65 @@ namespace teachos::arch::stl
}
/**
- * @brief Resets the managed object.
+ * @brief Replaces the managed object.
*
- * @param ptr New pointer to manage (default is nullptr).
+ * @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).
*/
- void reset(T * ptr = nullptr)
+ auto reset(T * ptr = nullptr) -> void
{
delete pointer;
pointer = ptr;
}
/**
- * @brief Swaps the managed object with another unique pointer.
+ * @brief Swaps the managed objects and associated deleters of *this and another unique_ptr object other.
*
- * @param other Unique pointer to swap with.
+ * @param other Another unique_ptr object to swap the managed object and the deleter with.
*/
- void swap(unique_pointer & other) { std::swap(pointer, other.pointer); }
+ auto swap(unique_pointer & other) -> void
+ {
+ using std::swap;
+ swap(pointer, other.pointer);
+ }
+
+ /**
+ * @brief Defaulted three-way comparator operator.
+ */
+ auto operator<=>(const unique_pointer & other) const = default;
private:
T * pointer; ///< The managed pointer.
};
/**
- * @brief Creates a unique pointer instance.
+ * @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<typename T>
+ auto swap(unique_pointer<T> & lhs, unique_pointer<T> & 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<T>(new T(std::forward<Args>(args)...)).
*
* @tparam T Type of the managed object.
* @tparam Args Argument types for T's constructor.
- * @param args Arguments for T's constructor.
- * @return A unique pointer managing a newly created T object.
+ * @param args List of arguments with which an instance of T will be constructed.
+ * @returns Unique_pointer of an instance of type T.
*/
template<typename T, typename... Args>
- unique_pointer<T> make_unique(Args &&... args)
+ auto make_unique(Args &&... args) -> unique_pointer<T>
{
return unique_pointer<T>(new T(std::forward<Args>(args)...));
}
diff --git a/arch/x86_64/include/arch/stl/vector.hpp b/arch/x86_64/include/arch/stl/vector.hpp
index 5bebf62..b8bedf3 100644
--- a/arch/x86_64/include/arch/stl/vector.hpp
+++ b/arch/x86_64/include/arch/stl/vector.hpp
@@ -29,7 +29,7 @@ namespace teachos::arch::stl
* @param capacity Amount of elements we want to create and set the given value for.
* @param initial Inital value of all elements in the underlying data array.
*/
- explicit vector(size_t capacity, T initial = T{})
+ explicit vector(std::size_t capacity, T initial = T{})
: _size(capacity)
, _capacity(capacity)
, _data(new T[_capacity]{})
@@ -113,7 +113,7 @@ namespace teachos::arch::stl
*
* @return Current amount of elements.
*/
- size_t size() const { return _size; }
+ std::size_t size() const { return _size; }
/**
* @brief Amount of space the vector currently has, can be different than the size, because we allocate more than we
@@ -121,7 +121,7 @@ namespace teachos::arch::stl
*
* @return Current amount of space the vector has for elements.
*/
- size_t capacity() const { return _capacity; }
+ std::size_t capacity() const { return _capacity; }
/**
* @brief Array indexing operator. Allowing to access element at the given index.
@@ -131,7 +131,7 @@ namespace teachos::arch::stl
* @param index Index we want to access elements at.
* @return Reference to the underlying element.
*/
- T & operator[](size_t index) { return _data[index]; }
+ T & operator[](std::size_t index) { return _data[index]; }
/**
* @brief Array indexing operator. Allowing to access element at the given index.
@@ -141,7 +141,7 @@ namespace teachos::arch::stl
* @param index Index we want to access elements at.
* @return Reference to the underlying element.
*/
- T & at(size_t index)
+ T & at(std::size_t index)
{
if (index >= _size)
{
@@ -357,7 +357,7 @@ namespace teachos::arch::stl
*
* @param new_capacity New capacity of the vector, in number of elements
*/
- void reserve(size_t new_capacity)
+ void reserve(std::size_t new_capacity)
{
if (new_capacity <= _capacity)
{
@@ -392,9 +392,9 @@ namespace teachos::arch::stl
}
private:
- size_t _size = {}; ///< Amount of elements in the underlying data container
- size_t _capacity = {}; ///< Amount of space for elements in the underlying data container
- T * _data = {}; ///< Pointer to the first element in the underlying data container
+ std::size_t _size = {}; ///< Amount of elements in the underlying data container
+ std::size_t _capacity = {}; ///< Amount of space for elements in the underlying data container
+ T * _data = {}; ///< Pointer to the first element in the underlying data container
};
} // namespace teachos::arch::stl