diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-23 12:48:52 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-23 12:48:52 +0100 |
| commit | f7b065d72684526aedd580cb564f6d010653a22e (patch) | |
| tree | 6993544d049b5d4d38ae859609f62019602e1ec5 /libs/kstd/tests/include | |
| parent | 3b5f694af4c366e6e699800d9b2fbcb977f1612d (diff) | |
| download | teachos-f7b065d72684526aedd580cb564f6d010653a22e.tar.xz teachos-f7b065d72684526aedd580cb564f6d010653a22e.zip | |
kstd/tests: extract test helper types
Diffstat (limited to 'libs/kstd/tests/include')
| -rw-r--r-- | libs/kstd/tests/include/kstd/tests/test_types.hpp | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/libs/kstd/tests/include/kstd/tests/test_types.hpp b/libs/kstd/tests/include/kstd/tests/test_types.hpp new file mode 100644 index 0000000..6a06311 --- /dev/null +++ b/libs/kstd/tests/include/kstd/tests/test_types.hpp @@ -0,0 +1,251 @@ +#ifndef KSTD_TESTS_TEST_TYPES_HPP +#define KSTD_TESTS_TEST_TYPES_HPP + +#include <cstddef> +#include <iterator> +#include <type_traits> + +namespace kstd::tests +{ + + //! A type tracking copy and move operations + //! + //! This type is designed to test move and copy semantics of standard library containers implemented in kstd. + struct move_tracker + { + //! A value indicating that the object was moved from. + constexpr auto static moved_from_v = -1; + + //! A simple value to be able to track the move-from state. + int value{}; + //! A flag to track if an instance of this type was either copy constructed or copy assigned. + bool was_copied{false}; + //! A flag to track if an instance of this type was either move constructed or move assigned. + bool was_moved{false}; + + //! Construct a new move tracker with the given value, if any. + constexpr move_tracker(int v = 0) + : value{v} + {} + + //! Construct a new move tracker by copying an existing one. + constexpr move_tracker(move_tracker const & other) + : value{other.value} + , was_copied{true} + {} + + //! Construct a new move tracker by moving from an existing one. + constexpr move_tracker(move_tracker && other) noexcept + : value{other.value} + , was_moved{true} + { + other.value = moved_from_v; + } + + //! Copy assign a new move tracker from an existing one. + constexpr auto operator=(move_tracker const & other) -> move_tracker & + { + if (this != &other) + { + value = other.value; + was_copied = true; + } + return *this; + } + + //! Move assign a new move tracker from an existing one. + //! + //! This function ensures that the moved-from state is marked. + constexpr auto operator=(move_tracker && other) noexcept -> move_tracker & + { + if (this != &other) + { + value = other.value; + was_moved = true; + other.value = moved_from_v; + } + return *this; + } + }; + + //! A type that is not default constructible. + //! + //! This type is designed to test default construction semantics of standard library containers implemented in kstd. + struct non_default_constructible + { + //! A simple placeholder value. + int value{}; + + //! Construct a new non-default-constructible object with the given value. + constexpr explicit non_default_constructible(int v) + : value{v} + {} + + //! Compare two non-default-constructible objects for equality. + [[nodiscard]] constexpr auto operator==(non_default_constructible const & other) const -> bool + { + return value == other.value; + } + }; + + //! An allocator that tracks the number of allocations. + //! + //! This allocator is designed to test allocation semantics of standard library containers implemented in kstd. + //! + //! @tparam T The type of the elements to be allocated. + template<typename T> + struct tracking_allocator + { + using value_type = T; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + //! A pointer to a counter that is incremented on allocation. + //! + //! A pointer is used so that multiple allocators can share the same counter. + int * allocation_count{}; + + //! Construct a new tracking allocator referencing the given counter. + tracking_allocator(int * counter) + : allocation_count{counter} + {} + + //! Construct a new tracking allocator by copying from another tracking allocator. + //! + //! This constructor is templated to allow for conversion from allocators of different types. + //! + //! @tparam U The type of the elements to be allocated by the other allocator. + template<typename U> + tracking_allocator(tracking_allocator<U> const & other) noexcept + : allocation_count{other.allocation_count} + {} + + //! Allocate memory for n elements of type T. + //! + //! @param n The number of elements to allocate. + //! @return A pointer to the allocated memory. + [[nodiscard]] auto allocate(std::size_t n) -> T * + { + if (allocation_count != nullptr) + { + ++(*allocation_count); + } + return static_cast<T *>(::operator new(n * sizeof(T))); + } + + //! Deallocate memory for n elements of type T. + //! + //! @param p A pointer to the memory to deallocate. + //! @param n The number of elements to deallocate. + auto deallocate(T * p, std::size_t n) noexcept -> void + { + ::operator delete(p, n * sizeof(T)); + } + + //! Compare two tracking allocators for equality. + //! + //! Two allocators are considered equal if they reference the same allocation counter. + //! + //! @param other The other tracking allocator to compare to. + //! @return True if the two tracking allocators are equal, false otherwise. + [[nodiscard]] auto operator==(tracking_allocator const & other) const -> bool + { + return allocation_count == other.allocation_count; + } + + //! Compare two tracking_allocators for inequality. + //! + //! @param other The other tracking_allocator to compare to. + //! @return True if the two tracking_allocators are not equal, false otherwise. + [[nodiscard]] auto operator!=(tracking_allocator const & other) const -> bool + { + return allocation_count != other.allocation_count; + } + }; + + //! An allocator that propagates copy assignment. + //! + //! This allocator is designed to test copy assignment semantics of standard library containers implemented in kstd. + //! + //! @tparam T The type of the elements to be allocated. + template<typename T> + struct propagating_allocator : tracking_allocator<T> + { + //! A flag to indicate that the allocator propagates copy assignment. + using propagate_on_container_copy_assignment = std::true_type; + + //! Construct a new propagating allocator referencing the given counter. + //! + //! @param counter A pointer to a counter that is incremented on allocation. + //! @see tracking_allocator::tracking_allocator(int*) + propagating_allocator(int * counter) + : tracking_allocator<T>{counter} + {} + + //! Construct a new propagating allocator by copying from another propagating allocator. + //! + //! This constructor is templated to allow for conversion from allocators of different types. + //! + //! @tparam U The type of the elements to be allocated by the other allocator. + //! @see tracking_allocator::tracking_allocator(tracking_allocator<U> const&) + template<typename U> + propagating_allocator(propagating_allocator<U> const & other) noexcept + : tracking_allocator<T>{other.allocation_count} + {} + }; + + //! A test input iterator. + //! + //! This iterator is designed to test input iterator semantics of standard library containers implemented in kstd. + struct test_input_iterator + { + using iterator_concept = std::input_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = int; + + //! The current element pointed to by the iterator. + int const * current; + + //! Construct a new test input iterator. + //! + //! @param current The current element pointed to by the iterator. + constexpr explicit test_input_iterator(int const * current) + : current{current} + {} + + //! Dereference the iterator to get the current element. + //! + //! @return The current element pointed to by the iterator. + [[nodiscard]] auto operator*() const -> int + { + return *current; + } + + //! Increment the iterator to point to the next element. + //! + //! @return A reference to the incremented iterator. + auto operator++() -> test_input_iterator & + { + ++current; + return *this; + } + + //! Increment the iterator to point to the next element. + auto operator++(int) -> void + { + ++*this; + } + + //! Compare two test input iterators for equality. + //! + //! @param other The other test input iterator to compare to. + //! @return True if the two test input iterators are equal, false otherwise. + [[nodiscard]] auto operator==(test_input_iterator const & other) const -> bool + { + return current == other.current; + } + }; + +} // namespace kstd::tests + +#endif |
