Ring buffer: Add multi-value insert
This commit is contained in:
@@ -13,6 +13,9 @@
|
|||||||
#include "alloc_type.hpp"
|
#include "alloc_type.hpp"
|
||||||
#include "bitmath_func.hpp"
|
#include "bitmath_func.hpp"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Self-resizing ring-buffer
|
* Self-resizing ring-buffer
|
||||||
*
|
*
|
||||||
@@ -613,6 +616,42 @@ public:
|
|||||||
return this->emplace(pos, std::move(value));
|
return this->emplace(pos, std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterator insert(ring_buffer_iterator_base pos, size_t count, const T& value)
|
||||||
|
{
|
||||||
|
if (count == 0) return iterator(pos);
|
||||||
|
|
||||||
|
dbg_assert(pos.ring == this);
|
||||||
|
|
||||||
|
const uint32 new_pos_start = this->setup_insert(pos.pos, count);
|
||||||
|
uint32 new_pos = new_pos_start;
|
||||||
|
for (size_t i = 0; i != count; i++) {
|
||||||
|
new (this->raw_ptr_at_pos(new_pos)) T(value);
|
||||||
|
++new_pos;
|
||||||
|
}
|
||||||
|
return iterator(this, new_pos_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename InputIt, typename = std::enable_if_t<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category, std::input_iterator_tag>::value>>
|
||||||
|
iterator insert(ring_buffer_iterator_base pos, InputIt first, InputIt last)
|
||||||
|
{
|
||||||
|
if (first == last) return iterator(pos);
|
||||||
|
|
||||||
|
dbg_assert(pos.ring == this);
|
||||||
|
|
||||||
|
const uint32 new_pos_start = this->setup_insert(pos.pos, (uint32)std::distance(first, last));
|
||||||
|
uint32 new_pos = new_pos_start;
|
||||||
|
for (auto iter = first; iter != last; ++iter) {
|
||||||
|
new (this->raw_ptr_at_pos(new_pos)) T(*iter);
|
||||||
|
++new_pos;
|
||||||
|
}
|
||||||
|
return iterator(this, new_pos_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator insert(ring_buffer_iterator_base pos, std::initializer_list<T> values)
|
||||||
|
{
|
||||||
|
return this->insert(pos, values.begin(), values.end());
|
||||||
|
}
|
||||||
|
|
||||||
void reserve(size_t new_cap)
|
void reserve(size_t new_cap)
|
||||||
{
|
{
|
||||||
if (new_cap <= this->capacity()) return;
|
if (new_cap <= this->capacity()) return;
|
||||||
|
@@ -296,6 +296,63 @@ TEST_CASE("RingBuffer - insert in middle (end) grow")
|
|||||||
CHECK(iter == ring.begin() + 6);
|
CHECK(iter == ring.begin() + 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("RingBuffer - insert multi at start")
|
||||||
|
{
|
||||||
|
ring_buffer<uint32> ring({ 3, 4, 5, 6, 7, 8 });
|
||||||
|
auto iter = ring.insert(ring.begin(), { 1, 2 });
|
||||||
|
CHECK(Matches(ring, { 1, 2, 3, 4, 5, 6, 7, 8 }));
|
||||||
|
CHECK(ring.capacity() == 8);
|
||||||
|
CHECK(iter == ring.begin());
|
||||||
|
|
||||||
|
iter = ring.insert(ring.begin(), { 10, 11 });
|
||||||
|
CHECK(Matches(ring, { 10, 11, 1, 2, 3, 4, 5, 6, 7, 8 }));
|
||||||
|
CHECK(ring.capacity() == 16);
|
||||||
|
CHECK(iter == ring.begin());
|
||||||
|
|
||||||
|
iter = ring.insert(ring.begin(), 2, 24);
|
||||||
|
CHECK(Matches(ring, { 24, 24, 10, 11, 1, 2, 3, 4, 5, 6, 7, 8 }));
|
||||||
|
CHECK(ring.capacity() == 16);
|
||||||
|
CHECK(iter == ring.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("RingBuffer - insert multi at end")
|
||||||
|
{
|
||||||
|
ring_buffer<uint32> ring({ 3, 4, 5, 6, 7, 8 });
|
||||||
|
auto iter = ring.insert(ring.end(), { 1, 2 });
|
||||||
|
CHECK(Matches(ring, { 3, 4, 5, 6, 7, 8, 1, 2 }));
|
||||||
|
CHECK(ring.capacity() == 8);
|
||||||
|
CHECK(iter == ring.end() - 2);
|
||||||
|
|
||||||
|
iter = ring.insert(ring.end(), { 10, 11 });
|
||||||
|
CHECK(Matches(ring, { 3, 4, 5, 6, 7, 8, 1, 2, 10, 11 }));
|
||||||
|
CHECK(ring.capacity() == 16);
|
||||||
|
CHECK(iter == ring.end() - 2);
|
||||||
|
|
||||||
|
iter = ring.insert(ring.end(), 2, 24);
|
||||||
|
CHECK(Matches(ring, { 3, 4, 5, 6, 7, 8, 1, 2, 10, 11, 24, 24 }));
|
||||||
|
CHECK(ring.capacity() == 16);
|
||||||
|
CHECK(iter == ring.end() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("RingBuffer - insert multi in middle")
|
||||||
|
{
|
||||||
|
ring_buffer<uint32> ring({ 3, 4, 5, 6, 7, 8 });
|
||||||
|
auto iter = ring.insert(ring.begin() + 3, { 1, 2 });
|
||||||
|
CHECK(Matches(ring, { 3, 4, 5, 1, 2, 6, 7, 8 }));
|
||||||
|
CHECK(ring.capacity() == 8);
|
||||||
|
CHECK(iter == ring.begin() + 3);
|
||||||
|
|
||||||
|
iter = ring.insert(ring.begin() + 7, { 10, 11 });
|
||||||
|
CHECK(Matches(ring, { 3, 4, 5, 1, 2, 6, 7, 10, 11, 8 }));
|
||||||
|
CHECK(ring.capacity() == 16);
|
||||||
|
CHECK(iter == ring.begin() + 7);
|
||||||
|
|
||||||
|
iter = ring.insert(ring.begin() + 2, 2, 24);
|
||||||
|
CHECK(Matches(ring, { 3, 4, 24, 24, 5, 1, 2, 6, 7, 10, 11, 8 }));
|
||||||
|
CHECK(ring.capacity() == 16);
|
||||||
|
CHECK(iter == ring.begin() + 2);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("RingBuffer - shrink to fit")
|
TEST_CASE("RingBuffer - shrink to fit")
|
||||||
{
|
{
|
||||||
ring_buffer<uint32> ring({ 3, 4, 5, 6, 7, 8 });
|
ring_buffer<uint32> ring({ 3, 4, 5, 6, 7, 8 });
|
||||||
|
Reference in New Issue
Block a user