Skip to content

Commit 9f75274

Browse files
authored
Merge pull request #17 from vinitjames/develop
Merging first release version
2 parents bd60506 + 067eb60 commit 9f75274

File tree

6 files changed

+733
-39
lines changed

6 files changed

+733
-39
lines changed

circular_buffer.h

Lines changed: 123 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#ifndef CIRCULAR_BUFFER_H
22
#define CIRCULAR_BUFFER_H
33

4-
#include <iostream>
4+
#include <algorithm>
5+
#include <iterator>
56
#include <mutex>
67
#include <memory>
7-
#include <iterator>
8-
#include <type_traits>
9-
#include <algorithm>
8+
#include <stdexcept>
109
#include <utility>
1110

11+
1212
template<typename T>
1313
class CircularBuffer {
1414
private:
@@ -20,13 +20,10 @@ class CircularBuffer {
2020
typedef const T& const_reference;
2121
typedef size_t size_type;
2222
typedef ptrdiff_t difference_type;
23-
template <bool isConst>
24-
struct BufferIterator;
25-
typedef BufferIterator<false> iterator;
26-
typedef BufferIterator<true> const_iterator;
23+
template <bool isConst> struct BufferIterator;
24+
2725

2826
public:
29-
3027
explicit CircularBuffer(size_t size)
3128
:_buff{std::unique_ptr<T[]>(new value_type[size])}, _max_size{size}{}
3229

@@ -83,7 +80,7 @@ class CircularBuffer {
8380
}
8481
return *this;
8582
}
86-
83+
8784
void push_back(const value_type& data);
8885
void push_back(value_type&& data) noexcept;
8986
void pop_front();
@@ -104,40 +101,53 @@ class CircularBuffer {
104101
const_reference at(size_type index) const;
105102
reference at(size_type index);
106103

104+
typedef BufferIterator<false> iterator;
105+
typedef BufferIterator<true> const_iterator;
106+
107107
iterator begin();
108108
const_iterator begin() const;
109109
iterator end();
110110
const_iterator end() const;
111+
const_iterator cbegin() const noexcept;
112+
const_iterator cend() const noexcept;
113+
iterator rbegin() noexcept;
114+
const_iterator rbegin() const noexcept;
115+
iterator rend() noexcept;
116+
const_iterator rend() const noexcept;
117+
111118

112119
private:
113120
void _increment_bufferstate();
114121
void _decrement_bufferstate();
115122
mutable std::mutex _mtx;
116123
std::unique_ptr<value_type[]> _buff;
117-
118124
size_type _head = 0;
119125
size_type _tail = 0;
120126
size_type _size = 0;
121127
size_type _max_size = 0;
122-
128+
123129
template<bool isConst = false>
124130
struct BufferIterator{
125131
public:
126-
127-
typedef std::random_access_iterator_tag iterator_type;
132+
friend class CircularBuffer<T>;
133+
typedef std::random_access_iterator_tag iterator_category;
134+
typedef ptrdiff_t difference_type;
135+
typedef T value_type;
128136
typedef typename std::conditional<isConst, const value_type&, value_type&>::type reference;
129137
typedef typename std::conditional<isConst, const value_type*, value_type*>::type pointer;
130-
typedef CircularBuffer* cbuf_pointer;
131-
138+
typedef typename std::conditional<isConst, const CircularBuffer<value_type>*,
139+
CircularBuffer<value_type>*>::type cbuf_pointer;
140+
private:
132141
cbuf_pointer _ptrToBuffer;
133142
size_type _offset;
134143
size_type _index;
135144
bool _reverse;
136-
137-
bool _comparable(const BufferIterator& other){
145+
146+
bool _comparable(const BufferIterator<isConst>& other) const{
138147
return (_ptrToBuffer == other._ptrToBuffer)&&(_reverse == other._reverse);
139148
}
140149

150+
public:
141151
BufferIterator()
142152
:_ptrToBuffer{nullptr}, _offset{0}, _index{0}, _reverse{false}{}
143153

@@ -149,15 +159,16 @@ class CircularBuffer {
149159

150160
reference operator*(){
151161
if(_reverse)
152-
return (*_ptrToBuffer)[(_ptrToBuffer->size() - _index)];
162+
return (*_ptrToBuffer)[(_ptrToBuffer->size() - _index - 1)];
153163
return (*_ptrToBuffer)[_index];
154164
}
155165

156166
pointer operator->() { return &(operator*()); }
157167

158168
reference operator[](size_type index){
159-
this->_index += index;
160-
return this->operator*();
169+
BufferIterator iter = *this;
170+
iter._index += index;
171+
return *iter;
161172
}
162173

163174
BufferIterator& operator++(){
@@ -191,6 +202,7 @@ class CircularBuffer {
191202
rhsiter._index += n;
192203
return rhsiter;
193204
}
205+
194206

195207
BufferIterator& operator+=(difference_type n){
196208
_index += n;
@@ -202,47 +214,51 @@ class CircularBuffer {
202214
return lhsiter;
203215
}
204216

217+
friend difference_type operator-(const BufferIterator& lhsiter, const BufferIterator& rhsiter){
218+
219+
return lhsiter._index - rhsiter._index;
220+
}
221+
205222
BufferIterator& operator-=(difference_type n){
206223
_index -= n;
207224
return *this;
208225
}
209226

210-
bool operator==(const BufferIterator& other){
227+
bool operator==(const BufferIterator& other) const{
211228
if (!_comparable(other))
212229
return false;
213230
return ((_index == other._index)&&(_offset == other._offset));
214231
}
215232

216-
bool operator!=(const BufferIterator& other){
233+
bool operator!=(const BufferIterator& other) const{
217234
if (!_comparable(other))
218235
return true;
219236
return ((_index != other._index)||(_offset != other._offset));
220237
}
221238

222-
bool operator<(const BufferIterator& other){
239+
bool operator<(const BufferIterator& other) const {
223240
if (!_comparable(other))
224241
return false;
225242
return ((_index + _offset)<(other._index+other._offset));
226243
}
227244

228-
bool operator>(const BufferIterator& other){
245+
bool operator>(const BufferIterator& other) const{
229246
if (!_comparable(other))
230247
return false;
231248
return ((_index + _offset)>(other._index+other._offset));
232249
}
233250

234-
bool operator<=(const BufferIterator& other){
251+
bool operator<=(const BufferIterator& other) const {
235252
if (!_comparable(other))
236253
return false;
237254
return ((_index + _offset)<=(other._index+other._offset));
238255
}
239256

240-
bool operator>=(const BufferIterator& other){
257+
bool operator>=(const BufferIterator& other) const {
241258
if (!_comparable(other))
242259
return false;
243260
return ((_index + _offset)>=(other._index+other._offset));
244261
}
245-
246262
};
247263
};
248264

@@ -268,7 +284,7 @@ template<typename T>
268284
inline
269285
void CircularBuffer<T>::clear(){
270286
std::lock_guard<std::mutex> _lck(_mtx);
271-
_head = _tail = _size = _max_size = 0;
287+
_head = _tail = _size = 0;
272288
}
273289

274290
template<typename T>
@@ -363,8 +379,8 @@ template<typename T>
363379
inline
364380
typename CircularBuffer<T>::reference CircularBuffer<T>::operator[](size_t index) {
365381
std::lock_guard<std::mutex> _lck(_mtx);
366-
if((index<0)||(index>=_max_size))
367-
throw std::out_of_range("Index is out of Range of buffer capacity");
382+
if((index<0)||(index>=_size))
383+
throw std::out_of_range("Index is out of Range of buffer size");
368384
index += _tail;
369385
index %= _max_size;
370386
return _buff[index];
@@ -374,8 +390,8 @@ template<typename T>
374390
inline
375391
typename CircularBuffer<T>::const_reference CircularBuffer<T>::operator[](size_t index) const {
376392
std::lock_guard<std::mutex> _lck(_mtx);
377-
if((index<0)||(index>=_max_size))
378-
throw std::out_of_range("Index is out of Range of buffer capacity");
393+
if((index<0)||(index>=_size))
394+
throw std::out_of_range("Index is out of Range of buffer size");
379395
index += _tail;
380396
index %= _max_size;
381397
return _buff[index];
@@ -419,7 +435,7 @@ template<typename T>
419435
inline
420436
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::begin() const{
421437
std::lock_guard<std::mutex> _lck(_mtx);
422-
iterator iter;
438+
const_iterator iter;
423439
iter._ptrToBuffer = this;
424440
iter._offset = _tail;
425441
iter._index = 0;
@@ -443,12 +459,84 @@ template<typename T>
443459
inline
444460
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::end() const{
445461
std::lock_guard<std::mutex> _lck(_mtx);
446-
iterator iter;
462+
const_iterator iter;
447463
iter._ptrToBuffer = this;
448464
iter._offset = _tail;
449465
iter._index = _size;
450466
iter._reverse = false;
451467
return iter;
452468
}
453469

470+
template<typename T>
471+
inline
472+
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::cbegin() const noexcept{
473+
std::lock_guard<std::mutex> _lck(_mtx);
474+
const_iterator iter;
475+
iter._ptrToBuffer = this;
476+
iter._offset = _tail;
477+
iter._index = 0;
478+
iter._reverse = false;
479+
return iter;
480+
}
481+
482+
template<typename T>
483+
inline
484+
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::cend() const noexcept{
485+
std::lock_guard<std::mutex> _lck(_mtx);
486+
const_iterator iter;
487+
iter._ptrToBuffer = this;
488+
iter._offset = _tail;
489+
iter._index = _size;
490+
iter._reverse = false;
491+
return iter;
492+
}
493+
494+
template<typename T>
495+
inline
496+
typename CircularBuffer<T>::iterator CircularBuffer<T>::rbegin() noexcept{
497+
std::lock_guard<std::mutex> _lck(_mtx);
498+
iterator iter;
499+
iter._ptrToBuffer = this;
500+
iter._offset = _tail;
501+
iter._index = 0;
502+
iter._reverse = true;
503+
return iter;
504+
}
505+
506+
template<typename T>
507+
inline
508+
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::rbegin() const noexcept{
509+
std::lock_guard<std::mutex> _lck(_mtx);
510+
const_iterator iter;
511+
iter._ptrToBuffer = this;
512+
iter._offset = _tail;
513+
iter._index = 0;
514+
iter._reverse = true;
515+
return iter;
516+
}
517+
518+
template<typename T>
519+
inline
520+
typename CircularBuffer<T>::iterator CircularBuffer<T>::rend() noexcept{
521+
std::lock_guard<std::mutex> _lck(_mtx);
522+
iterator iter;
523+
iter._ptrToBuffer = this;
524+
iter._offset = _tail;
525+
iter._index = _size;
526+
iter._reverse = true;
527+
return iter;
528+
}
529+
530+
template<typename T>
531+
inline
532+
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::rend() const noexcept{
533+
std::lock_guard<std::mutex> _lck(_mtx);
534+
const_iterator iter;
535+
iter._ptrToBuffer = this;
536+
iter._offset = _tail;
537+
iter._index = _size;
538+
iter._reverse = true;
539+
return iter;
540+
}
541+
454542
#endif /* CIRCULAR_BUFFER_H */

conanfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
class CircularBufferConan(ConanFile):
55
name = "circular_buffer"
6-
version = "0.0.1"
6+
version = "0.1.0"
77
license = "MIT License"
88
author = "vinit james [email protected]"
99
url = "https://github.com/vinitjames/circularbuffer"

tests/CMakeLists.txt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,23 @@ add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
3333
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
3434
EXCLUDE_FROM_ALL)
3535

36-
add_executable(circularbuffer_int circularbuffer_int.cpp)
37-
target_link_libraries(circularbuffer_int
36+
add_executable(simple_int_test simple_int_test.cpp)
37+
target_link_libraries(simple_int_test
3838
circularbuffer
3939
gtest_main
4040
)
41-
add_test(NAME test_circularbuffer_int COMMAND circularbuffer_int)
41+
add_test(NAME simple_int_test COMMAND simple_int_test)
42+
43+
add_executable(member_func_test member_func_test.cpp)
44+
target_link_libraries(member_func_test
45+
circularbuffer
46+
gtest_main
47+
)
48+
add_test(NAME member_func_test COMMAND member_func_test)
49+
50+
add_executable(iterator_test iterator_test.cpp)
51+
target_link_libraries(iterator_test
52+
circularbuffer
53+
gtest_main
54+
)
55+
add_test(NAME iterator_test COMMAND iterator_test)

0 commit comments

Comments
 (0)