mirror of
https://github.com/aicodix/dsp.git
synced 2026-04-27 14:30:36 +00:00
added ring buffer based double-ended queue
This commit is contained in:
parent
18a72daa4c
commit
fde7c654b6
3 changed files with 183 additions and 0 deletions
|
|
@ -131,6 +131,10 @@ fwd(out, history(another_value));
|
|||
|
||||
A [Digital delay line](https://en.wikipedia.org/wiki/Digital_delay_line) can be used to align signals with different delays - after filtering, for example.
|
||||
|
||||
### [deque.hh](deque.hh)
|
||||
|
||||
A [ring buffer](https://en.wikipedia.org/wiki/Circular_buffer) based, fixed-size [double-ended queue](https://en.wikipedia.org/wiki/Double-ended_queue).
|
||||
|
||||
### [calculus.hh](calculus.hh)
|
||||
|
||||
Some [calculus](https://en.wikipedia.org/wiki/Calculus) functions:
|
||||
|
|
|
|||
81
deque.hh
Normal file
81
deque.hh
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Double-ended queue
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace DSP {
|
||||
|
||||
template <typename TYPE, int SIZE>
|
||||
class Deque
|
||||
{
|
||||
TYPE buf[SIZE];
|
||||
int head, tail, count;
|
||||
public:
|
||||
Deque() : head(SIZE-1), tail(0), count(0)
|
||||
{
|
||||
}
|
||||
void push_back(TYPE input)
|
||||
{
|
||||
assert(count < SIZE);
|
||||
++count;
|
||||
if (--tail < 0)
|
||||
tail = SIZE-1;
|
||||
buf[tail] = input;
|
||||
}
|
||||
void push_front(TYPE input)
|
||||
{
|
||||
assert(count < SIZE);
|
||||
++count;
|
||||
if (++head >= SIZE)
|
||||
head = 0;
|
||||
buf[head] = input;
|
||||
}
|
||||
void pop_back()
|
||||
{
|
||||
assert(count > 0);
|
||||
--count;
|
||||
if (++tail >= SIZE)
|
||||
tail = 0;
|
||||
}
|
||||
void pop_front()
|
||||
{
|
||||
assert(count > 0);
|
||||
--count;
|
||||
if (--head < 0)
|
||||
head = SIZE-1;
|
||||
}
|
||||
TYPE back()
|
||||
{
|
||||
assert(count > 0);
|
||||
return buf[tail];
|
||||
}
|
||||
TYPE front()
|
||||
{
|
||||
assert(count > 0);
|
||||
return buf[head];
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return count == 0;
|
||||
}
|
||||
bool full()
|
||||
{
|
||||
return count == SIZE;
|
||||
}
|
||||
int size()
|
||||
{
|
||||
return count;
|
||||
}
|
||||
int max_size()
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
98
tests/deque_test.cc
Normal file
98
tests/deque_test.cc
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
Test for the double-ended queue
|
||||
|
||||
Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <random>
|
||||
#include <deque>
|
||||
#include "deque.hh"
|
||||
|
||||
template <int SIZE>
|
||||
void test()
|
||||
{
|
||||
std::deque<int> ref;
|
||||
DSP::Deque<int, SIZE> dut;
|
||||
std::random_device ran;
|
||||
std::default_random_engine gen(ran());
|
||||
typedef std::uniform_int_distribution<int> dis;
|
||||
for (int loop = 0; loop < 1000000; ++loop) {
|
||||
assert((int)ref.size() == dut.size());
|
||||
int operation = dis(0, 5)(gen);
|
||||
switch (operation) {
|
||||
case 0:
|
||||
assert(ref.empty() == dut.empty());
|
||||
if (!dut.empty())
|
||||
assert(ref.front() == dut.front());
|
||||
break;
|
||||
case 1:
|
||||
assert(ref.empty() == dut.empty());
|
||||
if (!dut.empty())
|
||||
assert(ref.back() == dut.back());
|
||||
break;
|
||||
case 2:
|
||||
for (int n = dis(0, dut.size())(gen), i = 0; i < n; ++i) {
|
||||
ref.pop_front();
|
||||
dut.pop_front();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (int n = dis(0, dut.size())(gen), i = 0; i < n; ++i) {
|
||||
ref.pop_back();
|
||||
dut.pop_back();
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (int n = dis(0, dut.max_size() - dut.size())(gen), i = 0; i < n; ++i) {
|
||||
int val = gen();
|
||||
ref.push_front(val);
|
||||
dut.push_front(val);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
for (int n = dis(0, dut.max_size() - dut.size())(gen), i = 0; i < n; ++i) {
|
||||
int val = gen();
|
||||
ref.push_back(val);
|
||||
dut.push_back(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
DSP::Deque<int, 1> dut;
|
||||
assert(dut.empty());
|
||||
assert(!dut.full());
|
||||
assert(dut.size() == 0);
|
||||
assert(dut.max_size() == 1);
|
||||
dut.push_front(42);
|
||||
assert(dut.full());
|
||||
assert(dut.size() == 1);
|
||||
assert(dut.front() == 42);
|
||||
assert(dut.back() == 42);
|
||||
dut.pop_back();
|
||||
assert(dut.empty());
|
||||
dut.push_back(42);
|
||||
assert(dut.full());
|
||||
assert(dut.size() == 1);
|
||||
assert(dut.front() == 42);
|
||||
assert(dut.back() == 42);
|
||||
dut.pop_front();
|
||||
test<1>();
|
||||
test<2>();
|
||||
test<3>();
|
||||
test<4>();
|
||||
test<5>();
|
||||
test<6>();
|
||||
test<7>();
|
||||
test<8>();
|
||||
test<42>();
|
||||
test<123>();
|
||||
std::cerr << "Double-ended queue test passed!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue