aboutsummaryrefslogtreecommitdiff
path: root/libs/kstd/tests/include
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-23 12:48:52 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-23 12:48:52 +0100
commitf7b065d72684526aedd580cb564f6d010653a22e (patch)
tree6993544d049b5d4d38ae859609f62019602e1ec5 /libs/kstd/tests/include
parent3b5f694af4c366e6e699800d9b2fbcb977f1612d (diff)
downloadteachos-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.hpp251
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