Skip to content

Commit 1b9ecf4

Browse files
authored
Merge pull request #13 from vinitjames/feature/add_citerators
Feature/add citerators
2 parents b0a58fc + 96a59b8 commit 1b9ecf4

File tree

6 files changed

+593
-24
lines changed

6 files changed

+593
-24
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Build and Test
2+
3+
on: [push]
4+
5+
env:
6+
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
7+
BUILD_TYPE: Release
8+
9+
jobs:
10+
build:
11+
# The CMake configure and build commands are platform agnostic and should work equally
12+
# well on Windows or Mac. You can convert this to a matrix build if you need
13+
# cross-platform coverage.
14+
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- uses: actions/checkout@v2
19+
20+
- name: Create Build Environment
21+
# Some projects don't allow in-source building, so create a separate build directory
22+
# We'll use this as our working directory for all subsequent commands
23+
run: cmake -E make_directory ${{github.workspace}}/build
24+
25+
- name: Configure CMake
26+
# Use a bash shell so we can use the same syntax for environment variable
27+
# access regardless of the host operating system
28+
shell: bash
29+
working-directory: ${{github.workspace}}/build
30+
# Note the current convention is to use the -S and -B options here to specify source
31+
# and build directories, but this is only available with CMake 3.13 and higher.
32+
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
33+
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE
34+
35+
- name: Build
36+
working-directory: ${{github.workspace}}/build
37+
shell: bash
38+
# Execute the build. You can specify a specific target with "--target <NAME>"
39+
run: cmake --build . --config $BUILD_TYPE
40+
41+
- name: Test
42+
working-directory: ${{github.workspace}}/build
43+
shell: bash
44+
# Execute tests defined by the CMake configuration.
45+
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
46+
run: ctest -C $BUILD_TYPE

README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,33 @@
1-
#A simple, general purpose STL style circular buffer in C++
1+
CircularBuffer
2+
===========
3+
4+
[![Actions Status](https://github.com/vinitjames/circularbuffer_CPP/workflows/Build%20and%20Test/badge.svg)](https://github.com/vinitjames/circularbuffer_CPP/actions) &nbsp; [![MIT License](https://img.shields.io/github/license/vinitjames/circularbuffer?color=blue)](https://github.com/vinitjames/circularbuffer/blob/master/LICENSE)
5+
## About
6+
circularbuffer_CPP is a simple, general purpose STL style [circularbuffer](https://en.wikipedia.org/wiki/Circular_buffer) implementation in C++.
7+
8+
9+
## Features
10+
* STL style implementaion of Circular Buffer
11+
* Lightweight (only single header file)
12+
* Simple API conforming to STL container semantics.
13+
* Random Access Iterator for easy forwad and reverse iteration and looping through elements.
14+
* Test suites
15+
16+
## Installation
17+
Run:
18+
```
19+
git clone https://github.com/vinitjames/circularbuffer_CPP.git
20+
```
21+
## Without CMAKE
22+
copy circular_buffer.h to your project
23+
24+
## With CMAKE
25+
To locally build and run test run the following commands
26+
```sh
27+
$ mkdir build
28+
$ cd build
29+
$ cmake ..
30+
$ cmake --build .
31+
$ ctest
32+
```
33+
To include in project as a submodule just clone the repo in a subdirectory and use `add_subdirectory()` in the top level `CMakeLists.txt`

circular_buffer.h

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -104,10 +101,15 @@ 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;
111113

112114
private:
113115
void _increment_bufferstate();
@@ -127,14 +129,15 @@ class CircularBuffer {
127129
typedef std::random_access_iterator_tag iterator_type;
128130
typedef typename std::conditional<isConst, const value_type&, value_type&>::type reference;
129131
typedef typename std::conditional<isConst, const value_type*, value_type*>::type pointer;
130-
typedef CircularBuffer* cbuf_pointer;
132+
typedef typename std::conditional<isConst, const CircularBuffer<value_type>*,
133+
CircularBuffer<value_type>*>::type cbuf_pointer;
131134

132135
cbuf_pointer _ptrToBuffer;
133136
size_type _offset;
134137
size_type _index;
135138
bool _reverse;
136139

137-
bool _comparable(const BufferIterator& other){
140+
bool _comparable(const BufferIterator<isConst>& other) const{
138141
return (_ptrToBuffer == other._ptrToBuffer)&&(_reverse == other._reverse);
139142
}
140143

@@ -191,6 +194,7 @@ class CircularBuffer {
191194
rhsiter._index += n;
192195
return rhsiter;
193196
}
197+
194198

195199
BufferIterator& operator+=(difference_type n){
196200
_index += n;
@@ -207,37 +211,37 @@ class CircularBuffer {
207211
return *this;
208212
}
209213

210-
bool operator==(const BufferIterator& other){
214+
bool operator==(const BufferIterator& other) const{
211215
if (!_comparable(other))
212216
return false;
213217
return ((_index == other._index)&&(_offset == other._offset));
214218
}
215219

216-
bool operator!=(const BufferIterator& other){
220+
bool operator!=(const BufferIterator& other) const{
217221
if (!_comparable(other))
218222
return true;
219223
return ((_index != other._index)||(_offset != other._offset));
220224
}
221225

222-
bool operator<(const BufferIterator& other){
226+
bool operator<(const BufferIterator& other) const {
223227
if (!_comparable(other))
224228
return false;
225229
return ((_index + _offset)<(other._index+other._offset));
226230
}
227231

228-
bool operator>(const BufferIterator& other){
232+
bool operator>(const BufferIterator& other) const{
229233
if (!_comparable(other))
230234
return false;
231235
return ((_index + _offset)>(other._index+other._offset));
232236
}
233237

234-
bool operator<=(const BufferIterator& other){
238+
bool operator<=(const BufferIterator& other) const {
235239
if (!_comparable(other))
236240
return false;
237241
return ((_index + _offset)<=(other._index+other._offset));
238242
}
239243

240-
bool operator>=(const BufferIterator& other){
244+
bool operator>=(const BufferIterator& other) const {
241245
if (!_comparable(other))
242246
return false;
243247
return ((_index + _offset)>=(other._index+other._offset));
@@ -268,7 +272,7 @@ template<typename T>
268272
inline
269273
void CircularBuffer<T>::clear(){
270274
std::lock_guard<std::mutex> _lck(_mtx);
271-
_head = _tail = _size = _max_size = 0;
275+
_head = _tail = _size = 0;
272276
}
273277

274278
template<typename T>
@@ -363,8 +367,8 @@ template<typename T>
363367
inline
364368
typename CircularBuffer<T>::reference CircularBuffer<T>::operator[](size_t index) {
365369
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");
370+
if((index<0)||(index>=_size))
371+
throw std::out_of_range("Index is out of Range of buffer size");
368372
index += _tail;
369373
index %= _max_size;
370374
return _buff[index];
@@ -374,8 +378,8 @@ template<typename T>
374378
inline
375379
typename CircularBuffer<T>::const_reference CircularBuffer<T>::operator[](size_t index) const {
376380
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");
381+
if((index<0)||(index>=_size))
382+
throw std::out_of_range("Index is out of Range of buffer size");
379383
index += _tail;
380384
index %= _max_size;
381385
return _buff[index];
@@ -419,7 +423,7 @@ template<typename T>
419423
inline
420424
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::begin() const{
421425
std::lock_guard<std::mutex> _lck(_mtx);
422-
iterator iter;
426+
const_iterator iter;
423427
iter._ptrToBuffer = this;
424428
iter._offset = _tail;
425429
iter._index = 0;
@@ -443,12 +447,35 @@ template<typename T>
443447
inline
444448
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::end() const{
445449
std::lock_guard<std::mutex> _lck(_mtx);
446-
iterator iter;
450+
const_iterator iter;
447451
iter._ptrToBuffer = this;
448452
iter._offset = _tail;
449453
iter._index = _size;
450454
iter._reverse = false;
451455
return iter;
452456
}
453457

458+
template<typename T>
459+
inline
460+
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::cbegin() const noexcept{
461+
std::lock_guard<std::mutex> _lck(_mtx);
462+
const_iterator iter;
463+
iter._ptrToBuffer = this;
464+
iter._offset = _tail;
465+
iter._index = 0;
466+
iter._reverse = false;
467+
return iter;
468+
}
469+
470+
template<typename T>
471+
inline
472+
typename CircularBuffer<T>::const_iterator CircularBuffer<T>::cend() 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 = _size;
478+
iter._reverse = false;
479+
return iter;
480+
}
454481
#endif /* CIRCULAR_BUFFER_H */

tests/CMakeLists.txt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,18 @@ 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(int_buffer int_buffer.cpp)
37+
target_link_libraries(int_buffer
3838
circularbuffer
3939
gtest_main
4040
)
41-
add_test(NAME test_circularbuffer_int COMMAND circularbuffer_int)
41+
add_test(NAME test_int_buffer COMMAND int_buffer)
42+
43+
add_executable(string_buffer string_buffer.cpp)
44+
target_link_libraries(string_buffer
45+
circularbuffer
46+
gtest_main
47+
)
48+
add_test(NAME test_string_buffer COMMAND string_buffer)
49+
50+

tests/circularbuffer_int.cpp renamed to tests/int_buffer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ TEST_F(CircularBufferTest, PushAndPopTest){
8080
test.push_back(i);
8181
EXPECT_EQ(TEST_BUFFER_SIZE, test.size());
8282
EXPECT_EQ(test.size(), test.capacity());
83+
8384
for(int i=0; i<TEST_BUFFER_SIZE - 1; i++)
8485
test.pop_front();
8586
EXPECT_EQ(1, test.size());

0 commit comments

Comments
 (0)