diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-23 11:40:44 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-23 11:40:44 +0100 |
| commit | a2a407efd453635af9ff6d3514114bfee95bcbb9 (patch) | |
| tree | 64c65df834fe3d20e45d4ebfab4d0f80d78161fd /libs | |
| parent | bb7a6bd989b748a29c1a1e68807da2dd3176186a (diff) | |
| download | teachos-a2a407efd453635af9ff6d3514114bfee95bcbb9.tar.xz teachos-a2a407efd453635af9ff6d3514114bfee95bcbb9.zip | |
kstd/vector: add more tests for different types
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/kstd/tests/src/vector.cpp | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/libs/kstd/tests/src/vector.cpp b/libs/kstd/tests/src/vector.cpp index 2440247..1427ce8 100644 --- a/libs/kstd/tests/src/vector.cpp +++ b/libs/kstd/tests/src/vector.cpp @@ -6,6 +6,7 @@ #include <catch2/catch_test_macros.hpp> #include <array> +#include <cstddef> #include <ranges> #include <utility> @@ -560,4 +561,189 @@ SCENARIO("Vector comparison", "[vector]") } } } +} + +struct non_default_constructible +{ + int value; + non_default_constructible() = delete; + explicit non_default_constructible(int v) + : value{v} + {} + + bool operator==(non_default_constructible const & other) const noexcept = default; +}; + +SCENARIO("Vector with non-default-constructible types", "[vector]") +{ + GIVEN("A type without a default constructor") + { + WHEN("constructing an empty vector") + { + kstd::vector<non_default_constructible> v; + + THEN("the vector is empty") + { + REQUIRE(v.empty()); + } + } + + WHEN("using emplace_back") + { + kstd::vector<non_default_constructible> v; + v.emplace_back(42); + + THEN("the element is added and the size and capacity increase") + { + REQUIRE(v.size() == 1); + REQUIRE(v.back() == non_default_constructible{42}); + } + } + } +} + +template<typename T> +struct tracking_allocator +{ + using value_type = T; + + int * allocation_count; + + tracking_allocator(int * counter) + : allocation_count{counter} + {} + + template<typename U> + tracking_allocator(tracking_allocator<U> const & other) noexcept + : allocation_count{other.allocation_count} + {} + + T * allocate(std::size_t n) + { + if (allocation_count) + { + (*allocation_count)++; + } + return static_cast<T *>(::operator new(n * sizeof(T))); + } + + void deallocate(T * p, std::size_t n) noexcept + { + ::operator delete(p, n * sizeof(T)); + } + + bool operator==(tracking_allocator const & other) + { + return allocation_count == other.allocation_count; + } +}; + +SCENARIO("Vector with custom allocator", "[vector]") +{ + GIVEN("a tracking allocator acting as the vector's memory manager") + { + auto allocations = 0; + tracking_allocator<int> allocator{&allocations}; + + WHEN("a vector uses this allocator to allocate memory") + { + kstd::vector<int, tracking_allocator<int>> v{allocator}; + REQUIRE(allocations == 0); + + v.reserve(10); + + THEN("the allocator was used to allocate memory") + { + REQUIRE(allocations > 0); + } + } + } +} + +struct move_tracker +{ + int value; + bool was_copied{}; + bool was_moved{}; + + move_tracker() = default; + explicit move_tracker(int v) + : value{v} + {} + + move_tracker(move_tracker const & other) + : value{other.value} + , was_copied{true} + , was_moved{false} + {} + + move_tracker(move_tracker && other) noexcept + : value{other.value} + , was_copied{false} + , was_moved{true} + { + other.value = -1; + } + + move_tracker & operator=(move_tracker const & other) + { + value = other.value; + was_copied = true; + was_moved = false; + return *this; + } + + move_tracker & operator=(move_tracker && other) noexcept + { + value = other.value; + was_moved = true; + was_copied = false; + other.value = -1; + return *this; + } +}; + +SCENARIO("Vector modifier move semantics", "[vector]") +{ + GIVEN("An empty vector and a move tracker element") + { + kstd::vector<move_tracker> v; + move_tracker tracker{42}; + + WHEN("push_back is called with the move tracker") + { + v.push_back(std::move(tracker)); + + THEN("the element is added and the size and capacity increase") + { + REQUIRE(v.size() == 1); + REQUIRE(v.back().was_moved); + REQUIRE_FALSE(v.back().was_copied); + REQUIRE(v.back().value == 42); + } + + THEN("the original tracker is left in a valid but unspecified state") + { + REQUIRE(tracker.value == -1); + } + } + } + + GIVEN("An empty vector") + { + kstd::vector<move_tracker> v; + + WHEN("emplace_back is called with constructor arguments") + { + v.emplace_back(42); + + THEN("the element is constructed directly, without moves or copies") + { + REQUIRE(v.size() == 1); + REQUIRE_FALSE(v.back().was_moved); + REQUIRE_FALSE(v.back().was_copied); + REQUIRE(v.back().value == 42); + } + } + } }
\ No newline at end of file |
