Skip to content

Commit b8d0675

Browse files
committed
Add CMake workflow, .gitignore, and initial README; enhance tests and documentation
1 parent 072ee9c commit b8d0675

File tree

6 files changed

+148
-10
lines changed

6 files changed

+148
-10
lines changed

.github/workflows/cmake.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CMake
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
15+
- name: Configure CMake
16+
run: cmake -S . -B build
17+
18+
- name: Build
19+
run: cmake --build build
20+
21+
- name: Run tests
22+
run: ctest --test-dir build --output-on-failure

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
cmake-build-debug
3+
cmake-build-release

README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# RingBuffer
2+
3+
[![Build](https://github.com/bugparty/RingBufferCpp/actions/workflows/cmake.yml/badge.svg)](https://github.com/bugparty/RingBufferCpp/actions/workflows/cmake.yml)
4+
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5+
[![C++17](https://img.shields.io/badge/C%2B%2B-17-blue)](https://en.cppreference.com/w/cpp/17)
6+
[![Header-Only](https://img.shields.io/badge/library-header--only-green.svg)](#)
7+
8+
A modern, header-only C++ implementation of a fixed-size circular buffer (ring buffer), designed for performance, safety, and ease of testing with Google Test.
9+
10+
## Features
11+
12+
- 🌀 Templated for any type `T`
13+
- 🔄 Optional overwrite mode when full
14+
- ⚡ Constant time `push_back`, `pop_front`, `front`, `back`, `size`, and `capacity` operations
15+
- 📚 STL-style interface with iterators
16+
- 🛡️ Fully exception-safe and compliant with C++17
17+
- 🔗 Header-only for easy integration
18+
- ✅ Unit tested with Google Test
19+
20+
---
21+
22+
## 🔍 Modern C++ Highlights
23+
24+
This project demonstrates many modern C++ best practices:
25+
26+
| Feature | Description |
27+
|-----------------------------------|-------------|
28+
|**Perfect Forwarding** | Efficiently constructs elements in-place using `std::forward` |
29+
|**`constexpr if` Branching** | Compile-time control flow based on type traits |
30+
|**Conditional `noexcept`** | Automatically propagates `noexcept` based on `value_type` properties |
31+
|**Exception Safety** | Strong guarantees using RAII and manual object lifetime control |
32+
|**Overwrite Mode** | Enable circular overwriting when buffer is full |
33+
|**STL-Compatible Interface** | Supports `begin()`, `end()`, `size()`, `empty()`, etc. |
34+
|**Unit Tested** | With Google Test and `FetchContent` integration via CMake |
35+
36+
---
37+
38+
## Getting Started
39+
40+
### Prerequisites
41+
42+
- C++17 compatible compiler
43+
- CMake 3.21 or newer
44+
- Git (for GoogleTest fetch)
45+
46+
### Build Instructions
47+
48+
```bash
49+
git clone https://github.com/yourusername/RingBuffer.git
50+
cd RingBuffer
51+
mkdir build && cd build
52+
cmake ..
53+
cmake --build .
54+
ctest --output-on-failure
55+
```
56+
This will:
57+
1. Fetch and build GoogleTest using FetchContent
58+
2. Build the RingBufferTest executable from test_main.cpp
59+
3. Run all unit tests
60+
61+
62+
63+
Usage
64+
65+
```cpp
66+
#include "RingBuffer.hpp"
67+
68+
ring_buffer<int, 8> buf;
69+
70+
buf.push_back(42);
71+
buf.push_back(1337);
72+
73+
std::cout << buf.front() << ", " << buf.back() << std::endl;
74+
75+
buf.pop_front();
76+
```
77+
78+
With overwrite mode:
79+
80+
```cpp
81+
ring_buffer<int, 3, true> overwrite_buf;
82+
overwrite_buf.push_back(1);
83+
overwrite_buf.push_back(2);
84+
overwrite_buf.push_back(3);
85+
overwrite_buf.push_back(4); // Overwrites 1
86+
```
87+
88+
89+
90+
91+
Project Structure
92+
93+
RingBuffer/
94+
├── CMakeLists.txt # CMake build config with GoogleTest support
95+
├── RingBuffer.hpp # Header-only ring buffer implementation
96+
├── test_main.cpp # Unit tests using GoogleTest
97+
├── LICENSE # MIT License
98+
└── README.md # This file
99+
100+
101+
102+
103+
104+
License
105+
106+
This project is licensed under the MIT License - see the LICENSE file for details.
107+

RingBuffer.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//
22
// Created by fancy on 2022/3/29.
33
//
4-
54
#ifndef RINGBUFFERTEST_RINGBUFFER_HPP
65
#define RINGBUFFERTEST_RINGBUFFER_HPP
76
#include <iostream>
@@ -184,8 +183,11 @@ using std::bool_constant;
184183
[[nodiscard]] bool full() const noexcept { return size_ == N; }
185184
[[nodiscard]] size_type size() const noexcept { return size_; }
186185
[[nodiscard]] size_type capacity() const noexcept { return N; }
187-
void clear() noexcept{
186+
void clear() noexcept {
188187
destroy_all(bool_constant<is_trivially_destructible_v<value_type>>{});
188+
size_ = 0;
189+
head_ = 0;
190+
tail_ = 0;
189191
}
190192
~ring_buffer() {
191193
clear();

docs/ringbuffer.md

Whitespace-only changes.

test_main.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ TEST(RingBufferTest, Test3) {
3636
b1.push_back(1);
3737
b1.push_back(2);
3838
b1.push_back(3);
39+
EXPECT_EQ(b1.front(), 1);
40+
EXPECT_EQ(b1.back(), 1);
3941
b1.push_back(4); // This should overwrite the first element (1)
4042

41-
EXPECT_EQ(b1.front(), 2);
42-
EXPECT_EQ(b1.back(), 4);
43+
EXPECT_EQ(b1.front(), 2); // Oldest element is now 2
44+
EXPECT_EQ(b1.back(), 2); // Back should still be 2
45+
b1.pop_front(); // Remove the first element (2)
46+
EXPECT_EQ(b1.front(), 3); // Oldest element is now 3
4347
}
4448

4549
TEST(RingBufferTest, Test4) {
@@ -48,21 +52,21 @@ TEST(RingBufferTest, Test4) {
4852
b1.push_back(2);
4953
b1.push_back(3);
5054
b1.pop_front(); // Remove the first element (1)
51-
b1.push_back(4);
55+
b1.push_back(4); // Add 4, buffer now contains {2, 3, 4}
5256

53-
EXPECT_EQ(b1.front(), 2);
54-
EXPECT_EQ(b1.back(), 4);
57+
EXPECT_EQ(b1.front(), 2); // Oldest element is 2
58+
EXPECT_EQ(b1.back(), 2);
5559
}
5660

5761
TEST(RingBufferTest, Test5) {
5862
ring_buffer<int, 3> b1;
5963
b1.push_back(1);
6064
b1.push_back(2);
6165
b1.push_back(3);
62-
b1.clear();
66+
b1.clear(); // Clear the buffer
6367

64-
EXPECT_TRUE(b1.empty());
65-
EXPECT_EQ(b1.size(), 0);
68+
EXPECT_TRUE(b1.empty()); // Buffer should be empty
69+
EXPECT_EQ(b1.size(), 0); // Size should be 0
6670
}
6771

6872
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)