diff --git a/circular_buffer.h b/circular_buffer.h index 0ce1fcd..03fb98d 100644 --- a/circular_buffer.h +++ b/circular_buffer.h @@ -7,6 +7,7 @@ #include #include #include +#include template class CircularBuffer { @@ -27,27 +28,64 @@ class CircularBuffer { public: explicit CircularBuffer(size_t size) - :_buff{std::unique_ptr(new T[size])}, _max_size{size}{} + :_buff{std::unique_ptr(new value_type[size])}, _max_size{size}{} CircularBuffer(const CircularBuffer& other) - :_buff{std::unique_ptr(new T[other.capacity()])}, - _max_size{other.capacity()}, + :_buff{std::unique_ptr(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(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(); @@ -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; @@ -75,21 +113,20 @@ class CircularBuffer { void _increment_bufferstate(); void _decrement_bufferstate(); mutable std::mutex _mtx; - std::unique_ptr _buff; + std::unique_ptr _buff; size_type _head = 0; size_type _tail = 0; size_type _size = 0; size_type _max_size = 0; - bool _full = false; template - class BufferIterator{ + struct BufferIterator{ public: typedef std::random_access_iterator_tag iterator_type; - typedef typename std::conditional::type reference; - typedef typename std::conditional::type pointer; + typedef typename std::conditional::type reference; + typedef typename std::conditional::type pointer; typedef CircularBuffer* cbuf_pointer; cbuf_pointer _ptrToBuffer; @@ -212,14 +249,12 @@ class CircularBuffer { template inline bool CircularBuffer::full() const{ - //return _full; return _size == _max_size; } template inline bool CircularBuffer::empty() const{ - //return ((!full()) &&(_head == _tail)); return _size == 0; } @@ -258,7 +293,6 @@ typename CircularBuffer::reference CircularBuffer::back() { std::lock_guard _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]; } @@ -277,11 +311,11 @@ typename CircularBuffer::const_reference CircularBuffer::back() const{ std::lock_guard _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 +template +inline void CircularBuffer::push_back(const T& data){ std::lock_guard _lck(_mtx); //if(full()) @@ -290,6 +324,15 @@ void CircularBuffer::push_back(const T& data){ _increment_bufferstate(); } +template +inline +void CircularBuffer::push_back(T&& data) noexcept{ + std::lock_guard _lck(_mtx); + _buff[_head] = std::move(data); + _increment_bufferstate(); +} + + template inline void CircularBuffer::_increment_bufferstate(){