aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt18
-rw-r--r--kernel/kapi/interrupts.cpp7
-rw-r--r--libs/kstd/include/kstd/vector22
-rw-r--r--libs/kstd/tests/src/vector.cpp60
4 files changed, 96 insertions, 11 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d785d4e..6cc8a2f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,15 +18,17 @@ include("GenerateBootableIso")
include("FetchContent")
-FetchContent_Declare(
- "Catch2"
- URL "https://github.com/catchorg/Catch2/archive/refs/tags/v3.7.1.tar.gz"
- URL_HASH "SHA256=c991b247a1a0d7bb9c39aa35faf0fe9e19764213f28ffba3109388e62ee0269c"
- EXCLUDE_FROM_ALL
- FIND_PACKAGE_ARGS
-)
+if (NOT CMAKE_CROSSCOMPILING)
+ FetchContent_Declare(
+ "Catch2"
+ URL "https://github.com/catchorg/Catch2/archive/refs/tags/v3.7.1.tar.gz"
+ URL_HASH "SHA256=c991b247a1a0d7bb9c39aa35faf0fe9e19764213f28ffba3109388e62ee0269c"
+ EXCLUDE_FROM_ALL
+ FIND_PACKAGE_ARGS
+ )
-FetchContent_MakeAvailable("Catch2")
+ FetchContent_MakeAvailable("Catch2")
+endif()
#[============================================================================[
# Global Build System Options
diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp
index 27427bb..e172e70 100644
--- a/kernel/kapi/interrupts.cpp
+++ b/kernel/kapi/interrupts.cpp
@@ -3,6 +3,7 @@
#include <kstd/print>
#include <kstd/vector>
+#include <algorithm>
#include <array>
#include <cstdint>
@@ -22,9 +23,9 @@ namespace kapi::interrupts
auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void
{
- static_cast<void>(irq_number);
- static_cast<void>(handler);
- kstd::println("[OS:interrupts] TODO: support erasure from vector.");
+ auto & handler_list = handlers.at(irq_number);
+ auto [first, last] = std::ranges::remove(handler_list, &handler);
+ handler_list.erase(first, last);
}
auto dispatch(std::uint32_t irq_number) -> status
diff --git a/libs/kstd/include/kstd/vector b/libs/kstd/include/kstd/vector
index 771fc87..9e41cb6 100644
--- a/libs/kstd/include/kstd/vector
+++ b/libs/kstd/include/kstd/vector
@@ -711,6 +711,28 @@ namespace kstd
return begin() + prefix_size;
}
+ //! Erase a range of elements from this vector.
+ //!
+ //! @param first The start of the range to erase.
+ //! @param last The end of the range to erase.
+ //! @return An iterator pointing to the element after the last deleted element.
+ constexpr auto erase(const_iterator first, const_iterator last) -> iterator
+ {
+ if (first == last)
+ {
+ return begin() + std::ranges::distance(cbegin(), first);
+ }
+
+ auto prefix_size = std::ranges::distance(cbegin(), first);
+ auto element_count = std::ranges::distance(first, last);
+
+ std::ranges::move(begin() + prefix_size + element_count, end(), begin() + prefix_size);
+ destroy_n(end() - element_count, element_count);
+ m_size -= element_count;
+
+ return begin() + prefix_size;
+ }
+
//! Append a given element to this vector via copy construction.
constexpr auto push_back(value_type const & value) -> void
{
diff --git a/libs/kstd/tests/src/vector.cpp b/libs/kstd/tests/src/vector.cpp
index 913427c..b7971f4 100644
--- a/libs/kstd/tests/src/vector.cpp
+++ b/libs/kstd/tests/src/vector.cpp
@@ -760,6 +760,33 @@ SCENARIO("Vector modifiers", "[vector]")
REQUIRE_THROWS_AS(v.erase(v.end()), kstd::tests::os_panic);
}
}
+
+ WHEN("erasing a range of elements")
+ {
+ auto it = v.erase(v.cbegin() + 1, v.cend() - 1);
+
+ THEN("the specified range is removed and the size decreases")
+ {
+ REQUIRE(v.size() == 2);
+ REQUIRE(v[0] == 10);
+ REQUIRE(v[1] == 30);
+ REQUIRE(it == v.begin() + 1);
+ }
+ }
+
+ WHEN("erasing an empty range")
+ {
+ auto it = v.erase(v.cbegin() + 1, v.cbegin() + 1);
+
+ THEN("the vector is unchanged")
+ {
+ REQUIRE(v.size() == 3);
+ REQUIRE(v[0] == 10);
+ REQUIRE(v[1] == 20);
+ REQUIRE(v[2] == 30);
+ REQUIRE(it == v.begin() + 1);
+ }
+ }
}
}
@@ -1031,6 +1058,39 @@ SCENARIO("Vector modifier move semantics", "[vector]")
REQUIRE(it == v.end());
}
}
+
+ WHEN("erasing a range of elements in the middle")
+ {
+ v.emplace_back(40);
+ v.emplace_back(50);
+
+ for (auto & elem : v)
+ {
+ elem.was_copied = false;
+ elem.was_moved = false;
+ }
+
+ auto it = v.erase(v.cbegin() + 1, v.cbegin() + 3);
+
+ THEN("the specified elements are destroyed and subsequent elements are move-assigned leftwards")
+ {
+ REQUIRE(v.size() == 3);
+
+ REQUIRE(v[0].value == 10);
+ REQUIRE_FALSE(v[0].was_moved);
+ REQUIRE_FALSE(v[0].was_copied);
+
+ REQUIRE(v[1].value == 40);
+ REQUIRE(v[1].was_moved);
+ REQUIRE_FALSE(v[1].was_copied);
+
+ REQUIRE(v[2].value == 50);
+ REQUIRE(v[2].was_moved);
+ REQUIRE_FALSE(v[2].was_copied);
+
+ REQUIRE(it == v.begin() + 1);
+ }
+ }
}
}