diff --git a/.gitignore b/.gitignore index 27e4eed..baf251a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /cmake-build-debug/ /cmake-build-release/ +/build-release-windows/ /.idea/ \ No newline at end of file diff --git a/src/Memory/UniquePtrList.hpp b/src/Memory/UniquePtrList.hpp new file mode 100644 index 0000000..8ec5dab --- /dev/null +++ b/src/Memory/UniquePtrList.hpp @@ -0,0 +1,73 @@ +#ifndef ARBUTILS_UNIQUEPTRLIST_HPP +#define ARBUTILS_UNIQUEPTRLIST_HPP + +#include +#include +#include +#include +#include "BorrowedPtr.hpp" + +namespace ArbUt { + template class UniquePtrList { + private: + std::vector _vector; + using iterator = typename std::vector::iterator; + + public: + inline UniquePtrList() : _vector() {} + explicit inline UniquePtrList(size_t capacity) : _vector() { _vector.reserve(capacity); } + inline UniquePtrList(const std::initializer_list& l) : _vector(l) {} + inline UniquePtrList(ValueT* const* begin, ValueT* const* end) : _vector(begin, end) {} + + UniquePtrList(const UniquePtrList&) = delete; + UniquePtrList& operator=(const UniquePtrList&) = delete; + ~UniquePtrList() { Clear(); } + + inline void Clear() { + for (auto& i : _vector) { + delete i; + } + } + + inline BorrowedPtr At(size_t index) { +#ifndef NO_ASSERT + if (index >= _vector.size() || index < 0) { + std::stringstream ss; + ss << "Index " << index << " is out of bounds."; + throw std::logic_error(ss.str()); + } +#endif + return _vector[index]; + } + + inline bool Contains(const BorrowedPtr& value) const { + return std::find(_vector.begin(), _vector.end(), value) != _vector.end(); + } + + /// 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 { + const auto& it = std::find(_vector.begin(), _vector.end(), value); + if (it == _vector.end()) + return -1; + return std::distance(_vector.begin(), it); + } + + inline void Append(ValueT* value) { _vector.push_back(value); } + inline BorrowedPtr operator[](size_t index) { return At(index); } + + inline size_t Count() const { return _vector.size(); } + + iterator begin() { return _vector.begin(); } + iterator end() { return _vector.end(); } + + ValueT* const* RawData() const { return _vector.data(); } + + const std::vector& GetStdList() const { return _vector; } + std::vector& GetStdList() { return _vector; } + + }; +} + +#endif // ARBUTILS_UNIQUEPTRLIST_HPP diff --git a/tests/UniquePtrListTests.cpp b/tests/UniquePtrListTests.cpp new file mode 100644 index 0000000..9137d4f --- /dev/null +++ b/tests/UniquePtrListTests.cpp @@ -0,0 +1,42 @@ +#ifdef TESTS_BUILD +#include "../extern/catch.hpp" +#include "../src/Memory/UniquePtrList.hpp" +using namespace ArbUt; + +TEST_CASE("Create Unique Ptr list, append"){ + auto ls = UniquePtrList(); + auto v1 = new uint32_t (100); + auto v2 = new uint32_t (5000); + ls.Append(v1); + ls.Append(v2); +} + +TEST_CASE("Create Unique Ptr list, append, retrieve"){ + auto ls = UniquePtrList(); + auto v1 = new uint32_t (100); + auto v2 = new uint32_t (5000); + ls.Append(v1); + ls.Append(v2); + REQUIRE(ls.Count() == 2); + CHECK(ls.At(0) == v1); + CHECK(ls.At(1) == v2); + CHECK(ls[0] == v1); + CHECK(ls[1] == v2); +} + +TEST_CASE("Create Unique Ptr list, append, iterate"){ + auto ls = UniquePtrList(); + auto v1 = new uint32_t (100); + auto v2 = new uint32_t (5000); + ls.Append(v1); + ls.Append(v2); + REQUIRE(ls.Count() == 2); + auto i = 0; + for (const auto& v : ls){ + if (i == 0) CHECK(v == v1); + else if (i == 1) CHECK(v == v2); + i++; + } +} + +#endif \ No newline at end of file