83 lines
2.6 KiB
C++
83 lines
2.6 KiB
C++
//===================================================================
|
|
// File: circular_buffer.cpp
|
|
//
|
|
// Desc: A Circular Buffer implementation in C++.
|
|
//
|
|
// Copyright © 2019 Edwin Cloud. All rights reserved.
|
|
//
|
|
//===================================================================
|
|
|
|
//-------------------------------------------------------------------
|
|
// Includes
|
|
//-------------------------------------------------------------------
|
|
#include <memory>
|
|
#include <stdexcept>
|
|
|
|
//-------------------------------------------------------------------
|
|
// Circular_Buffer (Class)
|
|
// We will implement the buffer with a templated class so
|
|
// the buffer can be a buffer of specified type.
|
|
//-------------------------------------------------------------------
|
|
template <typename T> class Circular_Buffer {
|
|
private:
|
|
//---------------------------------------------------------------
|
|
// Circular_Buffer - Private Member Variables
|
|
//---------------------------------------------------------------
|
|
|
|
std::unique_ptr<T[]> buffer; // using a smart pointer is safer (and we don't
|
|
// have to implement a destructor)
|
|
size_t head = 0; // size_t is an unsigned long
|
|
size_t tail = 0;
|
|
size_t max_size;
|
|
T empty_item; // we will use this to clear data
|
|
public:
|
|
//---------------------------------------------------------------
|
|
// Circular_Buffer - Public Methods
|
|
//---------------------------------------------------------------
|
|
|
|
// Create a new Circular_Buffer.
|
|
Circular_Buffer<T>(size_t max_size)
|
|
: buffer(std::unique_ptr<T[]>(new T[max_size])), max_size(max_size){};
|
|
|
|
// Add an item to this circular buffer.
|
|
void enqueue(T item) {
|
|
|
|
// insert item at back of buffer
|
|
buffer[tail] = item;
|
|
|
|
// increment tail
|
|
tail = (tail + 1) % max_size;
|
|
}
|
|
|
|
// Remove an item from this circular buffer and return it.
|
|
T dequeue() {
|
|
|
|
T item = buffer[head];
|
|
|
|
// set item at head to be empty
|
|
T empty;
|
|
buffer[head] = empty_item;
|
|
|
|
// move head foward
|
|
head = (head + 1) % max_size;
|
|
|
|
// return item
|
|
return item;
|
|
}
|
|
|
|
// Return the item at the front of this circular buffer.
|
|
T front() { return buffer[head]; }
|
|
|
|
// Return true if this circular buffer is empty, and false otherwise.
|
|
bool is_empty() { return head == tail; }
|
|
|
|
// Return true if this circular buffer is full, and false otherwise.
|
|
bool is_full() { return tail == (head - 1) % max_size; }
|
|
|
|
// Return the size of this circular buffer.
|
|
size_t size() {
|
|
if (tail >= head)
|
|
return tail - head;
|
|
return max_size - head - tail;
|
|
}
|
|
}; |