7
7
#include < iterator>
8
8
#include < type_traits>
9
9
#include < algorithm>
10
+ #include < utility>
10
11
11
12
template <typename T>
12
13
class CircularBuffer {
@@ -27,27 +28,64 @@ class CircularBuffer {
27
28
public:
28
29
29
30
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}{}
31
32
32
33
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 },
35
36
_size{other._size },
36
37
_head{other._head },
37
- _tail{other._tail },
38
- _full{other._full }{
39
-
38
+ _tail{other._tail }{
40
39
std::copy (other.data (), other.data () + _max_size, _buff.get ());
41
40
}
42
41
42
+
43
43
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
+ }
47
84
return *this ;
48
85
}
49
86
50
87
void push_back (const value_type& data);
88
+ void push_back (value_type&& data) noexcept ;
51
89
void pop_front ();
52
90
reference front ();
53
91
reference back ();
@@ -58,7 +96,7 @@ class CircularBuffer {
58
96
bool full () const ;
59
97
size_type capacity () const ;
60
98
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;};
62
100
const_pointer data () const { return _buff.get (); }
63
101
64
102
const_reference operator [](size_type index) const ;
@@ -75,21 +113,20 @@ class CircularBuffer {
75
113
void _increment_bufferstate ();
76
114
void _decrement_bufferstate ();
77
115
mutable std::mutex _mtx;
78
- std::unique_ptr<T []> _buff;
116
+ std::unique_ptr<value_type []> _buff;
79
117
80
118
size_type _head = 0 ;
81
119
size_type _tail = 0 ;
82
120
size_type _size = 0 ;
83
121
size_type _max_size = 0 ;
84
- bool _full = false ;
85
122
86
123
template <bool isConst = false >
87
- class BufferIterator {
124
+ struct BufferIterator {
88
125
public:
89
126
90
127
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;
93
130
typedef CircularBuffer* cbuf_pointer;
94
131
95
132
cbuf_pointer _ptrToBuffer;
@@ -212,14 +249,12 @@ class CircularBuffer {
212
249
template <typename T>
213
250
inline
214
251
bool CircularBuffer<T>::full() const {
215
- // return _full;
216
252
return _size == _max_size;
217
253
}
218
254
219
255
template <typename T>
220
256
inline
221
257
bool CircularBuffer<T>::empty() const {
222
- // return ((!full()) &&(_head == _tail));
223
258
return _size == 0 ;
224
259
}
225
260
@@ -258,7 +293,6 @@ typename CircularBuffer<T>::reference CircularBuffer<T>::back() {
258
293
std::lock_guard<std::mutex> _lck (_mtx);
259
294
if (empty ())
260
295
throw std::length_error (" back function called on empty buffer" );
261
- // return _buff[_head - 1];
262
296
return _head == 0 ? _buff[_max_size - 1 ] : _buff[_head - 1 ];
263
297
}
264
298
@@ -277,11 +311,11 @@ typename CircularBuffer<T>::const_reference CircularBuffer<T>::back() const{
277
311
std::lock_guard<std::mutex> _lck (_mtx);
278
312
if (empty ())
279
313
throw std::length_error (" back function called on empty buffer" );
280
- // return _buff[_head - 1];
281
314
return _head == 0 ? _buff[_max_size - 1 ] : _buff[_head - 1 ];
282
315
}
283
316
284
- template <typename T>
317
+ template <typename T>
318
+ inline
285
319
void CircularBuffer<T>::push_back(const T& data){
286
320
std::lock_guard<std::mutex> _lck (_mtx);
287
321
// if(full())
@@ -290,6 +324,15 @@ void CircularBuffer<T>::push_back(const T& data){
290
324
_increment_bufferstate ();
291
325
}
292
326
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
+
293
336
template <typename T>
294
337
inline
295
338
void CircularBuffer<T>::_increment_bufferstate(){
0 commit comments