openMSX
CircularBuffer.hh
Go to the documentation of this file.
1#ifndef CIRCULARBUFFER_HH
2#define CIRCULARBUFFER_HH
3
4#include <array>
5#include <cassert>
6#include <cstddef>
7#include <utility>
8
9namespace openmsx {
10
11template<typename T, size_t MAXSIZE>
13{
14public:
15 constexpr CircularBuffer() = default;
16
17 constexpr void push_front(const T& element) {
18 assert(!full());
19 first = prev(first);
20 buffer[first] = element;
21 }
22 constexpr void push_front(T&& element) {
23 assert(!full());
24 first = prev(first);
25 buffer[first] = std::move(element);
26 }
27 constexpr void push_back(const T& element) {
28 assert(!full());
29 buffer[last] = element;
30 last = next(last);
31 }
32 constexpr void push_back(T&& element) {
33 assert(!full());
34 buffer[last] = std::move(element);
35 last = next(last);
36 }
37 constexpr T& pop_front() {
38 assert(!empty());
39 auto tmp = first;
40 first = next(first);
41 return buffer[tmp];
42 }
43 constexpr T& pop_back() {
44 assert(!empty());
45 last = prev(last);
46 return buffer[last];
47 }
48
49 [[nodiscard]] constexpr T& operator[](size_t pos) {
50 assert(pos < size());
51 auto tmp = first + pos;
52 if (tmp > MAXSIZE) {
53 tmp -= (MAXSIZE + 1);
54 }
55 return buffer[tmp];
56 }
57 [[nodiscard]] constexpr const T& operator[](size_t pos) const {
58 return const_cast<CircularBuffer&>(*this)[pos];
59 }
60
61 [[nodiscard]] constexpr T& front() {
62 assert(!empty());
63 return buffer[first];
64 }
65 [[nodiscard]] constexpr const T& front() const {
66 return const_cast<CircularBuffer&>(*this)->front();
67 }
68
69 [[nodiscard]] constexpr T& back() {
70 assert(!empty());
71 return buffer[prev(last)];
72 }
73 [[nodiscard]] constexpr const T& back() const {
74 return const_cast<CircularBuffer&>(*this)->back();
75 }
76
77 [[nodiscard]] constexpr bool empty() const {
78 return (first == last);
79 }
80 [[nodiscard]] constexpr bool full() const {
81 return (first == next(last));
82 }
83 [[nodiscard]] constexpr size_t size() const {
84 if (first > last) {
85 return MAXSIZE + 1 - first + last;
86 } else {
87 return last - first;
88 }
89 }
90
91 void clear() {
92 first = last = 0;
93 }
94
95private:
96 [[nodiscard]] constexpr size_t next(size_t a) const {
97 return (a != MAXSIZE) ? a + 1 : 0;
98 }
99 [[nodiscard]] constexpr size_t prev(size_t a) const {
100 return (a != 0) ? a - 1 : MAXSIZE;
101 }
102
103 size_t first = 0;
104 size_t last = 0;
105 // one extra to be able to distinguish full and empty
106 std::array<T, MAXSIZE + 1> buffer;
107};
108
109} // namespace openmsx
110
111#endif
constexpr bool full() const
constexpr void push_back(T &&element)
constexpr const T & front() const
constexpr T & operator[](size_t pos)
constexpr CircularBuffer()=default
constexpr bool empty() const
constexpr void push_front(const T &element)
constexpr size_t size() const
constexpr T & pop_front()
constexpr void push_front(T &&element)
constexpr const T & operator[](size_t pos) const
constexpr const T & back() const
constexpr void push_back(const T &element)
This file implemented 3 utility functions:
Definition Autofire.cc:11