openMSX
CircularBuffer.hh
Go to the documentation of this file.
1 #ifndef CIRCULARBUFFER_HH
2 #define CIRCULARBUFFER_HH
3 
4 #include <cassert>
5 
6 namespace openmsx {
7 
8 template<class T, size_t MAXSIZE>
10 {
11 public:
12  CircularBuffer() = default;
13 
14  void addFront(const T& element) {
15  assert(!isFull());
16  first = prev(first);
17  buffer[first] = element;
18  }
19  void addBack(const T& element) {
20  assert(!isFull());
21  buffer[last] = element;
22  last = next(last);
23  }
24  T& removeFront() {
25  assert(!isEmpty());
26  auto tmp = first;
27  first = next(first);
28  return buffer[tmp];
29  }
30  T& removeBack() {
31  assert(!isEmpty());
32  last = prev(last);
33  return buffer[last];
34  }
35  T& operator[](size_t pos) {
36  assert(pos < MAXSIZE);
37  auto tmp = first + pos;
38  if (tmp > MAXSIZE) {
39  tmp -= (MAXSIZE + 1);
40  }
41  return buffer[tmp];
42  }
43  const T& operator[](size_t pos) const {
44  return const_cast<CircularBuffer&>(*this)[pos];
45  }
46  bool isEmpty() const {
47  return (first == last);
48  }
49  bool isFull() const {
50  return (first == next(last));
51  }
52  size_t size() const {
53  if (first > last) {
54  return MAXSIZE + 1 - first + last;
55  } else {
56  return last - first;
57  }
58  }
59 
60 private:
61  inline size_t next(size_t a) const {
62  return (a != MAXSIZE) ? a + 1 : 0;
63  }
64  inline size_t prev(size_t a) const {
65  return (a != 0) ? a - 1 : MAXSIZE;
66  }
67 
68  size_t first = 0;
69  size_t last = 0;
70  // one extra to be able to distinguish full and empty
71  T buffer[MAXSIZE + 1];
72 };
73 
74 } // namespace openmsx
75 
76 #endif
const T & operator[](size_t pos) const
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
T & operator[](size_t pos)
void addBack(const T &element)
void addFront(const T &element)