diff --git a/src/Memory/Memory.hpp b/src/Memory/Memory.hpp index 1c3c100..b3d6f0b 100644 --- a/src/Memory/Memory.hpp +++ b/src/Memory/Memory.hpp @@ -4,6 +4,7 @@ #include "__BorrowedPtr.hpp" #include "__OptionalBorrowedPtr.hpp" #include "__OptionalUniquePtr.hpp" +#include "__OptionalUniquePtrList.hpp" #include "__UniquePtr.hpp" #include "__UniquePtrList.hpp" diff --git a/src/Memory/__OptionalUniquePtrList.hpp b/src/Memory/__OptionalUniquePtrList.hpp new file mode 100644 index 0000000..01f196e --- /dev/null +++ b/src/Memory/__OptionalUniquePtrList.hpp @@ -0,0 +1,147 @@ +#ifndef ARBUTILS___OPTIONALUNIQUEPTRLIST_HPP +#define ARBUTILS___OPTIONALUNIQUEPTRLIST_HPP + +#include "__OptionalBorrowedPtr.hpp" + +namespace ArbUt { + /// @brief Collection of pointers that is owned by the list. When the list exits scope, the destructor on all + /// pointers will be called. + template class UniquePtrList { + private: + std::vector _vector; + using iterator = typename std::vector::iterator; + using const_iterator = typename std::vector::const_iterator; + + public: + inline UniquePtrList() noexcept : _vector() {} + /// @brief Initialises a UniquePtrList from a std::vector of raw pointers. + /// @param vec A std::vector of raw pointers. + inline UniquePtrList(const std::vector& vec) noexcept : _vector(vec) {} + /// @brief Initialises a UniquePtrList with a certain capacity reserved for use. This does not set immediate + /// size. + /// @param capacity The desired capacity. + explicit inline UniquePtrList(size_t capacity) : _vector() { _vector.reserve(capacity); } + /// @brief Initialises a UniquePtrList from a initialiser_list. + /// @param l A initialiser_list + inline UniquePtrList(const std::initializer_list& l) noexcept : _vector(l) {} + /// @brief Initialises a UniquePtrList from a raw pointer range. + /// @param begin The raw pointer to the start of the list. + /// @param end The raw pointer to the end of the list. + inline UniquePtrList(ValueT* const* begin, ValueT* const* end) noexcept : _vector(begin, end) {} + + UniquePtrList(const UniquePtrList&) = delete; + UniquePtrList& operator=(const UniquePtrList&) = delete; + ~UniquePtrList() noexcept { Clear(); } + + /// @brief Clears the UniquePtrList, and run the destructor on all containing pointers. + inline void Clear() noexcept { + for (auto& i : _vector) { + delete i; + } + } + + /// @brief Borrow a pointer at a certain index. + /// @param index The index to retrieve. + /// @return A borrowed pointer reference to the containing raw pointer. + inline OptionalBorrowedPtr At(size_t index) const { +#ifndef NO_ASSERT + if (index >= _vector.size()) { + std::stringstream ss; + ss << "Index " << index << " is out of bounds."; + throw ArbUt::Exception(ss.str()); + } +#endif + return _vector[index]; + } + /// @brief Returns a raw pointer at an index, and releases ownership. Proper handling of the memory is assumed + /// to be done by the taker. + /// @param index The index to get the pointer from. + /// @return A raw pointer. + ValueT* TakeOwnership(size_t index) { + auto p = _vector[index]; + _vector[index] = nullptr; + return p; + } + /// @brief Swaps two pointers at indices with each other. + /// @param indexA The first index to swap from. + /// @param indexB The second index to swap from + void Swap(size_t indexA, size_t indexB) { + auto temp = _vector[indexA]; + _vector[indexA] = _vector[indexB]; + _vector[indexB] = temp; + } + /// @brief Sets a pointer to a certain index. If an item already existed at that index, it's destructor will be + /// called. + /// @param index The index to set the pointer to. + /// @param ptr The pointer to store. + void Set(size_t index, ValueT* ptr) { + delete _vector[index]; + _vector[index] = ptr; + } + + /// @brief Removes a pointer at a certain index. It's destructor will be called. + /// @param index The index to remove. + inline void Remove(size_t index) { +#ifndef NO_ASSERT + if (index >= _vector.size()) { + std::stringstream ss; + ss << "Index " << index << " is out of bounds."; + throw ArbUt::Exception(ss.str()); + } +#endif + delete _vector[index]; + _vector.erase(_vector.begin() + index); + } + + /// @brief Check whether a pointer is contained in the list. + /// @param value The value to check for. + /// @return True if the list contains the pointer, false otherwise. + inline bool Contains(const BorrowedPtr& value) const noexcept { + return std::find(_vector.begin(), _vector.end(), value) != _vector.end(); + } + + /// @brief Find the index of the first occurrence of a value in the list, return -1 if none is found. + /// @param value The value we want the index for. + /// @return The index of the first occurrence of the value in the list, or -1 if none is found. + inline size_t IndexOf(const BorrowedPtr& value) const noexcept { + const auto& it = std::find(_vector.begin(), _vector.end(), value); + if (it == _vector.end()) + return -1; + return std::distance(_vector.begin(), it); + } + + /// @brief Append a pointer to the list. + /// @param value The pointer to push to the list. + inline void Append(ValueT* value) { _vector.push_back(value); } + /// @brief Borrow a pointer at a certain index. + /// @param index The index to retrieve. + /// @return A borrowed pointer reference to the containing raw pointer. + inline OptionalBorrowedPtr operator[](size_t index) const { return At(index); } + + /// @brief Returns the number of pointers contained. + /// @return The number of pointers contained. + [[nodiscard]] inline size_t Count() const noexcept { return _vector.size(); } + + /// @brief returns an iterator to the beginning of the specified bucket + iterator begin() noexcept { return _vector.begin(); } + /// @brief returns an iterator to the beginning of the specified bucket + iterator end() noexcept { return _vector.end(); } + /// @brief returns an iterator to the end of the specified bucket + const_iterator begin() const noexcept { return _vector.begin(); } + /// @brief returns an iterator to the end of the specified bucket + const_iterator end() const noexcept { return _vector.end(); } + + /// @brief Return a raw pointer to the beginning of the list. + /// @return A raw array pointer to the beginning of the list. + ValueT* const* RawData() const noexcept { return _vector.data(); } + + /// @brief Returns a std::vector representation of the current list. + /// @return A std::vector representation of the current list. + const std::vector& GetStdList() const noexcept { return _vector; } + /// @brief Returns a std::vector representation of the current list. + /// @return A std::vector representation of the current list. + std::vector& GetStdList() noexcept { return _vector; } + }; +} + +#endif // ARBUTILS___OPTIONALUNIQUEPTRLIST_HPP diff --git a/src/Memory/__UniquePtrList.hpp b/src/Memory/__UniquePtrList.hpp index 19056da..19a46fb 100644 --- a/src/Memory/__UniquePtrList.hpp +++ b/src/Memory/__UniquePtrList.hpp @@ -2,6 +2,7 @@ #define ARBUTILS___UNIQUEPTRLIST_HPP #include "__BorrowedPtr.hpp" +#include "../Assert.hpp" namespace ArbUt { /// @brief Collection of pointers that is owned by the list. When the list exits scope, the destructor on all @@ -16,18 +17,24 @@ namespace ArbUt { inline UniquePtrList() noexcept : _vector() {} /// @brief Initialises a UniquePtrList from a std::vector of raw pointers. /// @param vec A std::vector of raw pointers. - inline UniquePtrList(const std::vector& vec) noexcept : _vector(vec) {} + inline UniquePtrList(const std::vector& vec) noexcept : _vector(vec) { + AssertAllNotNull(vec); + } /// @brief Initialises a UniquePtrList with a certain capacity reserved for use. This does not set immediate /// size. /// @param capacity The desired capacity. explicit inline UniquePtrList(size_t capacity) : _vector() { _vector.reserve(capacity); } /// @brief Initialises a UniquePtrList from a initialiser_list. /// @param l A initialiser_list - inline UniquePtrList(const std::initializer_list& l) noexcept : _vector(l) {} + inline UniquePtrList(const std::initializer_list& l) noexcept : _vector(l) { + AssertAllNotNull(_vector); + } /// @brief Initialises a UniquePtrList from a raw pointer range. /// @param begin The raw pointer to the start of the list. /// @param end The raw pointer to the end of the list. - inline UniquePtrList(ValueT* const* begin, ValueT* const* end) noexcept : _vector(begin, end) {} + inline UniquePtrList(ValueT* const* begin, ValueT* const* end) noexcept : _vector(begin, end) { + AssertAllNotNull(_vector); + } UniquePtrList(const UniquePtrList&) = delete; UniquePtrList& operator=(const UniquePtrList&) = delete; @@ -75,6 +82,7 @@ namespace ArbUt { /// @param index The index to set the pointer to. /// @param ptr The pointer to store. void Set(size_t index, ValueT* ptr) { + AssertNotNull(ptr); delete _vector[index]; _vector[index] = ptr; } @@ -112,7 +120,10 @@ namespace ArbUt { /// @brief Append a pointer to the list. /// @param value The pointer to push to the list. - inline void Append(ValueT* value) { _vector.push_back(value); } + inline void Append(ValueT* value) { + AssertNotNull(value); + _vector.push_back(value); + } /// @brief Borrow a pointer at a certain index. /// @param index The index to retrieve. /// @return A borrowed pointer reference to the containing raw pointer.