Skip to content

Commit 2d21de6

Browse files
authored
Merge pull request #10 from vinitjames/feature/add_move_constructor
Feature/add move constructor
2 parents 03f3ed2 + 3268696 commit 2d21de6

File tree

1 file changed

+63
-20
lines changed

1 file changed

+63
-20
lines changed

circular_buffer.h

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <iterator>
88
#include <type_traits>
99
#include <algorithm>
10+
#include <utility>
1011

1112
template<typename T>
1213
class CircularBuffer {
@@ -27,27 +28,64 @@ class CircularBuffer {
2728
public:
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 {
212249
template<typename T>
213250
inline
214251
bool CircularBuffer<T>::full() const{
215-
//return _full;
216252
return _size == _max_size;
217253
}
218254

219255
template<typename T>
220256
inline
221257
bool 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
285319
void 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+
293336
template<typename T>
294337
inline
295338
void CircularBuffer<T>::_increment_bufferstate(){

0 commit comments

Comments
 (0)