aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-10-05 16:14:38 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-10-05 16:14:38 +0200
commitd466390c43965fafd1474d3a263afc688ca4ac6a (patch)
treebaea30c775b359d37207401d12d20fe2a13cc3a3
parentb636d6a31a9bfb0bbe0e4e4a3c10963cc1e29de7 (diff)
downloadkernel-d466390c43965fafd1474d3a263afc688ca4ac6a.tar.xz
kernel-d466390c43965fafd1474d3a263afc688ca4ac6a.zip
kstd: extract construction_guard
-rw-r--r--libs/kstd/kstd/bits/construction_guard.hpp46
-rw-r--r--libs/kstd/kstd/ring_buffer.hpp48
2 files changed, 54 insertions, 40 deletions
diff --git a/libs/kstd/kstd/bits/construction_guard.hpp b/libs/kstd/kstd/bits/construction_guard.hpp
new file mode 100644
index 00000000..38e7bbb6
--- /dev/null
+++ b/libs/kstd/kstd/bits/construction_guard.hpp
@@ -0,0 +1,46 @@
+#ifndef KSTD_BITS_CONSTRUCTION_GUARD_HPP
+#define KSTD_BITS_CONSTRUCTION_GUARD_HPP
+
+namespace kstd::bits
+{
+
+ //! An RAII guard to ensure partially constructed container elements are properly cleaned up.
+ //!
+ //! @tparam Container The type of the container being guarded.
+ template<typename Container>
+ requires requires(Container * c) { c->clear(); }
+ struct construction_guard
+ {
+ //! Construct a new construction guard for the given container.
+ constexpr explicit construction_guard(Container * container)
+ : m_container{container}
+ {}
+
+ constexpr construction_guard(construction_guard const &) = delete;
+ constexpr construction_guard(construction_guard &&) = delete;
+
+ //! Destroy the construction guard, clearing the container if it is still engaged.
+ constexpr ~construction_guard()
+ {
+ if (m_container)
+ {
+ m_container->clear();
+ }
+ }
+
+ constexpr auto operator=(construction_guard const &) -> construction_guard & = delete;
+ constexpr auto operator=(construction_guard &&) -> construction_guard & = delete;
+
+ //! Disarm the construction guard, preventing it from clearing the container.
+ constexpr auto disarm() noexcept -> void
+ {
+ m_container = nullptr;
+ }
+
+ private:
+ Container * m_container;
+ };
+
+} // namespace kstd::bits
+
+#endif \ No newline at end of file
diff --git a/libs/kstd/kstd/ring_buffer.hpp b/libs/kstd/kstd/ring_buffer.hpp
index a87ee381..e9a733a3 100644
--- a/libs/kstd/kstd/ring_buffer.hpp
+++ b/libs/kstd/kstd/ring_buffer.hpp
@@ -3,6 +3,7 @@
#include <kstd/bits/basic_storage.hpp>
#include <kstd/bits/concepts.hpp>
+#include <kstd/bits/construction_guard.hpp>
#include <kstd/os/error.hpp>
#include <kstd/ranges.hpp>
@@ -267,7 +268,7 @@ namespace kstd
//! Construct a ring buffer by copying from an existing one.
constexpr ring_buffer(ring_buffer const & other) noexcept(std::is_nothrow_copy_constructible_v<ValueType>)
{
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
std::ranges::for_each(std::views::iota(0uz, other.size()), [&](auto const i) {
m_storage.construct(i, other[i]);
++m_size;
@@ -279,7 +280,7 @@ namespace kstd
constexpr ring_buffer(ring_buffer && other) noexcept(std::is_nothrow_move_constructible_v<ValueType> &&
std::is_nothrow_destructible_v<ValueType>)
{
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
std::ranges::for_each(std::views::iota(0uz, other.size()), [&](auto) {
m_storage.construct(m_size, std::move(other[0]));
++m_size;
@@ -307,7 +308,7 @@ namespace kstd
os::panic("[KSTD] Tried to construct a ring buffer with more elements than it can support.");
}
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
std::ranges::for_each(std::views::iota(0uz, count), [&](auto i) {
m_storage.construct(i);
++m_size;
@@ -326,7 +327,7 @@ namespace kstd
os::panic("[KSTD] Tried to construct a ring buffer with more elements than it can support.");
}
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
std::ranges::for_each(std::views::iota(0uz, count), [&](auto i) {
m_storage.construct(i, value);
++m_size;
@@ -344,7 +345,7 @@ namespace kstd
template<std::input_iterator InputIterator>
constexpr ring_buffer(InputIterator first, InputIterator last)
{
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
if constexpr (Capacity > 0)
{
for (; first != last && m_size < capacity(); ++first)
@@ -379,7 +380,7 @@ namespace kstd
if constexpr (Capacity > 0)
{
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
std::ranges::for_each(first, last, [this](auto const & element) { this->push_back(element); });
guard.disarm();
}
@@ -403,7 +404,7 @@ namespace kstd
if constexpr (Capacity > 0)
{
- auto guard = construction_guard{*this};
+ auto guard = bits::construction_guard{this};
std::ranges::for_each(std::forward<Range>(range),
[this](auto && element) { this->push_back(std::forward<decltype(element)>(element)); });
guard.disarm();
@@ -928,39 +929,6 @@ namespace kstd
//! @}
private:
- //! An RAII guard to ensure partially constructed buffers are properly cleaned up.
- struct construction_guard
- {
- //! Construct a new construction guard for the given ring buffer.
- constexpr explicit construction_guard(ring_buffer & buf)
- : m_buffer{&buf}
- {}
-
- constexpr construction_guard(construction_guard const &) = delete;
- constexpr construction_guard(construction_guard &&) = delete;
-
- //! Destroy the construction guard, clearing the buffer if it is still engaged.
- constexpr ~construction_guard()
- {
- if (m_buffer)
- {
- m_buffer->clear();
- }
- }
-
- constexpr auto operator=(construction_guard const &) -> construction_guard & = delete;
- constexpr auto operator=(construction_guard &&) -> construction_guard & = delete;
-
- //! Disarm the construction guard, preventing it from clearing the buffer.
- constexpr auto disarm() noexcept -> void
- {
- m_buffer = nullptr;
- }
-
- private:
- ring_buffer * m_buffer;
- };
-
//! Get a pointer to the element at the given read-index relative position.
//!
//! @param position The logical (read-index relative) index of the element.