blob: 331991a1d05c5718f380d65bc1d83a6b0b52137a [file] [log] [blame]
Parker Schuhecd057f2017-03-11 20:03:01 -08001#ifndef AOS_COMMON_RING_BUFFER_H_
2#define AOS_COMMON_RING_BUFFER_H_
3
4#include <array>
5
6namespace aos {
7
8// This is a helper to keep track of some amount of recent data. As you push
9// data into the ring buffer, it gets stored. If the buffer becomes full, it
10// will start overwriting the oldest data.
11template <typename Data, size_t buffer_size>
12class RingBuffer {
13 public:
Parker Schuhfea48582017-03-11 20:15:32 -080014 static constexpr size_t kBufferSize = buffer_size;
15
Parker Schuhecd057f2017-03-11 20:03:01 -080016 RingBuffer() {}
17
18 // Add an item to the RingBuffer, overwriting the oldest element if necessary
19 void Push(const Data &data) {
20 if (full()) {
21 data_[oldest_] = data;
22 oldest_ = (oldest_ + 1) % buffer_size;
23 } else {
24 data_[(oldest_ + size_) % buffer_size] = data;
25 ++size_;
26 }
27 }
28
29 // Return the value of the index requested, adjusted so that the RingBuffer
30 // contians the oldest element first and the newest last.
31 Data &operator[](size_t index) {
32 return data_[(oldest_ + index) % buffer_size];
33 }
34
35 const Data &operator[](size_t index) const {
36 return data_[(oldest_ + index) % buffer_size];
37 }
38
39 // Returns the capacity of the RingBuffer
40 size_t capacity() const { return buffer_size; }
41
42 // Returns the number of elements stored in the RingBuffer
43 size_t size() const { return size_; }
44
45 // Is the RingBuffer empty or full?
46 bool empty() const { return size_ == 0; }
47
48 bool full() const { return size_ == buffer_size; }
49
50 private:
51 ::std::array<Data, buffer_size> data_;
52
53 // Oldest contains the oldest item added to the RingBuffer which will be the
54 // next one to be overwritten
55 size_t oldest_ = 0;
56 size_t size_ = 0;
57};
58
59} // namespace aos
60
61#endif // AOS_COMMON_RING_BUFFER_H_