77#include < iterator>
88#include < type_traits>
99#include < algorithm>
10+ #include < utility>
1011
1112template <typename T>
1213class CircularBuffer {
@@ -27,27 +28,64 @@ class CircularBuffer {
2728public:
2829
2930 explicit CircularBuffer (size_t size)
30- :_buff{std::unique_ptr<T[]>(new T [size])}, _max_size{size}{}
31+ :_buff{std::unique_ptr<T[]>(new value_type [size])}, _max_size{size}{}
3132
3233 CircularBuffer (const CircularBuffer& other)
33- :_buff{std::unique_ptr<T[]>(new T [other.capacity () ])},
34- _max_size{other.capacity () },
34+ :_buff{std::unique_ptr<T[]>(new value_type [other._max_size ])},
35+ _max_size{other._max_size },
3536 _size{other._size },
3637 _head{other._head },
37- _tail{other._tail },
38- _full{other._full }{
39-
38+ _tail{other._tail }{
4039 std::copy (other.data (), other.data () + _max_size, _buff.get ());
4140 }
4241
42+
4343 CircularBuffer& operator =(const CircularBuffer& other){
44- _buff = std::unique_ptr<T[]>(new T[other.capacity ()]);
45- _max_size = other.capacity ();
46- std::copy (other.data (), other.data () + _max_size, _buff.get ());
44+ if ( this != &other){
45+ _buff.reset (new value_type[other._max_size ]);
46+ _max_size = other._max_size ;
47+ _size = other._size ;
48+ _head = other._head ;
49+ _tail = other._tail ;
50+ std::copy (other.data (), other.data () + _max_size, _buff.get ());
51+ }
52+ return *this ;
53+ }
54+
55+ CircularBuffer (CircularBuffer&& other) noexcept
56+ :_buff{std::move (other._buff )},
57+ _max_size{other._max_size },
58+ _size{other._size },
59+ _head{other._head },
60+ _tail{other._tail }{
61+
62+ other._buff = nullptr ;
63+ other._max_size = 0 ;
64+ other._size = 0 ;
65+ other._head = 0 ;
66+ other._tail = 0 ;
67+ }
68+
69+
70+ CircularBuffer& operator =(CircularBuffer&& other) noexcept {
71+ if ( this != &other){
72+ _buff = std::move (other._buff );
73+ _max_size = other._max_size ;
74+ _size = other._size ;
75+ _head = other._head ;
76+ _tail = other._tail ;
77+
78+ other._buff = nullptr ;
79+ other._max_size = 0 ;
80+ other._size = 0 ;
81+ other._head = 0 ;
82+ other._tail = 0 ;
83+ }
4784 return *this ;
4885 }
4986
5087 void push_back (const value_type& data);
88+ void push_back (value_type&& data) noexcept ;
5189 void pop_front ();
5290 reference front ();
5391 reference back ();
@@ -58,7 +96,7 @@ class CircularBuffer {
5896 bool full () const ;
5997 size_type capacity () const ;
6098 size_type size () const ;
61- size_type buffer_size () const {return sizeof (T )*_max_size;};
99+ size_type buffer_size () const {return sizeof (value_type )*_max_size;};
62100 const_pointer data () const { return _buff.get (); }
63101
64102 const_reference operator [](size_type index) const ;
@@ -75,21 +113,20 @@ class CircularBuffer {
75113 void _increment_bufferstate ();
76114 void _decrement_bufferstate ();
77115 mutable std::mutex _mtx;
78- std::unique_ptr<T []> _buff;
116+ std::unique_ptr<value_type []> _buff;
79117
80118 size_type _head = 0 ;
81119 size_type _tail = 0 ;
82120 size_type _size = 0 ;
83121 size_type _max_size = 0 ;
84- bool _full = false ;
85122
86123 template <bool isConst = false >
87- class BufferIterator {
124+ struct BufferIterator {
88125 public:
89126
90127 typedef std::random_access_iterator_tag iterator_type;
91- typedef typename std::conditional<isConst, const T &, T &>::type reference;
92- typedef typename std::conditional<isConst, const T *, T *>::type pointer;
128+ typedef typename std::conditional<isConst, const value_type &, value_type &>::type reference;
129+ typedef typename std::conditional<isConst, const value_type *, value_type *>::type pointer;
93130 typedef CircularBuffer* cbuf_pointer;
94131
95132 cbuf_pointer _ptrToBuffer;
@@ -212,14 +249,12 @@ class CircularBuffer {
212249template <typename T>
213250inline
214251bool CircularBuffer<T>::full() const {
215- // return _full;
216252 return _size == _max_size;
217253}
218254
219255template <typename T>
220256inline
221257bool CircularBuffer<T>::empty() const {
222- // return ((!full()) &&(_head == _tail));
223258 return _size == 0 ;
224259}
225260
@@ -258,7 +293,6 @@ typename CircularBuffer<T>::reference CircularBuffer<T>::back() {
258293 std::lock_guard<std::mutex> _lck (_mtx);
259294 if (empty ())
260295 throw std::length_error (" back function called on empty buffer" );
261- // return _buff[_head - 1];
262296 return _head == 0 ? _buff[_max_size - 1 ] : _buff[_head - 1 ];
263297}
264298
@@ -277,11 +311,11 @@ typename CircularBuffer<T>::const_reference CircularBuffer<T>::back() const{
277311 std::lock_guard<std::mutex> _lck (_mtx);
278312 if (empty ())
279313 throw std::length_error (" back function called on empty buffer" );
280- // return _buff[_head - 1];
281314 return _head == 0 ? _buff[_max_size - 1 ] : _buff[_head - 1 ];
282315}
283316
284- template <typename T>
317+ template <typename T>
318+ inline
285319void CircularBuffer<T>::push_back(const T& data){
286320 std::lock_guard<std::mutex> _lck (_mtx);
287321 // if(full())
@@ -290,6 +324,15 @@ void CircularBuffer<T>::push_back(const T& data){
290324 _increment_bufferstate ();
291325}
292326
327+ template <typename T>
328+ inline
329+ void CircularBuffer<T>::push_back(T&& data) noexcept {
330+ std::lock_guard<std::mutex> _lck (_mtx);
331+ _buff[_head] = std::move (data);
332+ _increment_bufferstate ();
333+ }
334+
335+
293336template <typename T>
294337inline
295338void CircularBuffer<T>::_increment_bufferstate(){
0 commit comments