diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-10-05 16:14:38 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-10-05 16:14:38 +0200 |
| commit | d466390c43965fafd1474d3a263afc688ca4ac6a (patch) | |
| tree | baea30c775b359d37207401d12d20fe2a13cc3a3 | |
| parent | b636d6a31a9bfb0bbe0e4e4a3c10963cc1e29de7 (diff) | |
| download | kernel-d466390c43965fafd1474d3a263afc688ca4ac6a.tar.xz kernel-d466390c43965fafd1474d3a263afc688ca4ac6a.zip | |
kstd: extract construction_guard
| -rw-r--r-- | libs/kstd/kstd/bits/construction_guard.hpp | 46 | ||||
| -rw-r--r-- | libs/kstd/kstd/ring_buffer.hpp | 48 |
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. |
