Ringbuffer added

This commit is contained in:
2019-05-04 21:10:44 +02:00
parent b1cf71d41f
commit 4717d4e2e3
2 changed files with 135 additions and 0 deletions

75
sequential/ringbuffer.hpp Normal file
View File

@@ -0,0 +1,75 @@
#include "vector.hpp"
template<class T>
class RingBuffer
{
private:
Vector<T> data;
std::size_t head, tail;
void AdvanceHead()
{
++head;
if(head >= data.GetSize())
{
head = 0;
}
}
void AdvanceTail()
{
++tail;
if(tail >= data.GetSize())
{
tail = 0;
}
if(tail == head)
{
AdvanceHead();
}
}
public:
void Push(const T value)
{
data[tail] = value;
AdvanceTail();
}
T Pop()
{
if(head == tail)
{
throw std::out_of_range("Cannot retrieve value when size is 0");
}
T const & toReturn = data[head];
AdvanceHead();
return toReturn;
}
std::size_t GetSize() const
{
if(head <= tail)
{
return tail - head;
}
else
{
return tail + (data.GetSize() - head);
}
}
bool IsEmpty() const
{
return head == tail;
}
RingBuffer(std::size_t const size)
: data(),
head(0),
tail(0)
{
data.Resize(size + 1ul);
}
};

60
test/ringbuffer.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "../sequential/ringbuffer.hpp"
#include "testutil.hpp"
bool TestInsertion()
{
std::size_t const testSize = 512u;
std::vector<unsigned> truth;
truth.resize(testSize);
RingBuffer<unsigned> ringBuffer(512u);
for(std::size_t i = 0; i < testSize; ++i)
{
truth[i] = Util::GetRandomNumber();
ringBuffer.Push(truth[i]);
}
for(std::size_t i = 0; i < testSize; ++i)
{
if(truth[i] != ringBuffer.Pop())
{
return false;
}
}
return true;
}
bool TestWrapAround()
{
std::size_t const testSize = 32u;
RingBuffer<unsigned> ringBuffer(testSize);
for(std::size_t i = 0; i < testSize / 2u; ++i)
{
ringBuffer.Push(42u);
}
for(std::size_t i = 0; i < testSize; ++i)
{
ringBuffer.Push(i);
}
for(std::size_t i = 0; i < testSize; ++i)
{
if(ringBuffer.Pop() != i)
{
return false;
}
}
return true;
}
int main()
{
Test::Execute(TestInsertion, "Insertion test");
Test::Execute(TestWrapAround, "Wrap around test");
return 0;
}