Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 63 additions & 20 deletions circular_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <iterator>
#include <type_traits>
#include <algorithm>
#include <utility>

template<typename T>
class CircularBuffer {
Expand All @@ -27,27 +28,64 @@ class CircularBuffer {
public:

explicit CircularBuffer(size_t size)
:_buff{std::unique_ptr<T[]>(new T[size])}, _max_size{size}{}
:_buff{std::unique_ptr<T[]>(new value_type[size])}, _max_size{size}{}

CircularBuffer(const CircularBuffer& other)
:_buff{std::unique_ptr<T[]>(new T[other.capacity()])},
_max_size{other.capacity()},
:_buff{std::unique_ptr<T[]>(new value_type[other._max_size])},
_max_size{other._max_size},
_size{other._size},
_head{other._head},
_tail{other._tail},
_full{other._full}{

_tail{other._tail}{
std::copy(other.data(), other.data() + _max_size, _buff.get());
}


CircularBuffer& operator=(const CircularBuffer& other){
_buff = std::unique_ptr<T[]>(new T[other.capacity()]);
_max_size = other.capacity();
std::copy(other.data(), other.data() + _max_size, _buff.get());
if ( this != &other){
_buff.reset(new value_type[other._max_size]);
_max_size = other._max_size;
_size = other._size;
_head = other._head;
_tail = other._tail;
std::copy(other.data(), other.data() + _max_size, _buff.get());
}
return *this;
}

CircularBuffer(CircularBuffer&& other) noexcept
:_buff{std::move(other._buff)},
_max_size{other._max_size},
_size{other._size},
_head{other._head},
_tail{other._tail}{

other._buff = nullptr;
other._max_size = 0;
other._size = 0;
other._head = 0;
other._tail = 0;
}


CircularBuffer& operator=(CircularBuffer&& other) noexcept{
if ( this != &other){
_buff = std::move(other._buff);
_max_size = other._max_size;
_size = other._size;
_head = other._head;
_tail = other._tail;

other._buff = nullptr;
other._max_size = 0;
other._size = 0;
other._head = 0;
other._tail = 0;
}
return *this;
}

void push_back(const value_type& data);
void push_back(value_type&& data) noexcept;
void pop_front();
reference front();
reference back();
Expand All @@ -58,7 +96,7 @@ class CircularBuffer {
bool full() const ;
size_type capacity() const ;
size_type size() const;
size_type buffer_size() const {return sizeof(T)*_max_size;};
size_type buffer_size() const {return sizeof(value_type)*_max_size;};
const_pointer data() const { return _buff.get(); }

const_reference operator[](size_type index) const;
Expand All @@ -75,21 +113,20 @@ class CircularBuffer {
void _increment_bufferstate();
void _decrement_bufferstate();
mutable std::mutex _mtx;
std::unique_ptr<T[]> _buff;
std::unique_ptr<value_type[]> _buff;

size_type _head = 0;
size_type _tail = 0;
size_type _size = 0;
size_type _max_size = 0;
bool _full = false;

template<bool isConst = false>
class BufferIterator{
struct BufferIterator{
public:

typedef std::random_access_iterator_tag iterator_type;
typedef typename std::conditional<isConst, const T&, T&>::type reference;
typedef typename std::conditional<isConst, const T*, T*>::type pointer;
typedef typename std::conditional<isConst, const value_type&, value_type&>::type reference;
typedef typename std::conditional<isConst, const value_type*, value_type*>::type pointer;
typedef CircularBuffer* cbuf_pointer;

cbuf_pointer _ptrToBuffer;
Expand Down Expand Up @@ -212,14 +249,12 @@ class CircularBuffer {
template<typename T>
inline
bool CircularBuffer<T>::full() const{
//return _full;
return _size == _max_size;
}

template<typename T>
inline
bool CircularBuffer<T>::empty() const{
//return ((!full()) &&(_head == _tail));
return _size == 0;
}

Expand Down Expand Up @@ -258,7 +293,6 @@ typename CircularBuffer<T>::reference CircularBuffer<T>::back() {
std::lock_guard<std::mutex> _lck(_mtx);
if(empty())
throw std::length_error("back function called on empty buffer");
//return _buff[_head - 1];
return _head == 0 ? _buff[_max_size - 1] : _buff[_head - 1];
}

Expand All @@ -277,11 +311,11 @@ typename CircularBuffer<T>::const_reference CircularBuffer<T>::back() const{
std::lock_guard<std::mutex> _lck(_mtx);
if(empty())
throw std::length_error("back function called on empty buffer");
//return _buff[_head - 1];
return _head == 0 ? _buff[_max_size - 1] : _buff[_head - 1];
}

template<typename T>
template<typename T>
inline
void CircularBuffer<T>::push_back(const T& data){
std::lock_guard<std::mutex> _lck(_mtx);
//if(full())
Expand All @@ -290,6 +324,15 @@ void CircularBuffer<T>::push_back(const T& data){
_increment_bufferstate();
}

template<typename T>
inline
void CircularBuffer<T>::push_back(T&& data) noexcept{
std::lock_guard<std::mutex> _lck(_mtx);
_buff[_head] = std::move(data);
_increment_bufferstate();
}


template<typename T>
inline
void CircularBuffer<T>::_increment_bufferstate(){
Expand Down