-
Notifications
You must be signed in to change notification settings - Fork 3
/
cyclic_buffer.hpp
133 lines (103 loc) · 2.2 KB
/
cyclic_buffer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef CYCLIC_BUFFER
#define CYCLIC_BUFFER
#include <vector>
template <typename T> class cyclic_buffer;
template <typename T>
class cyclic_buffer {
public:
cyclic_buffer() : period_(0), current_(0), storage_()
{
storage_.reserve(period_);
}
explicit cyclic_buffer( int period )
: period_(period), current_(0), storage_()
{
storage_.reserve(period_);
}
cyclic_buffer( const cyclic_buffer &o )
: period_( o.period() ), current_(0), storage_( o.storage() ) {}
cyclic_buffer &operator=( const cyclic_buffer &o )
{
if( *this != &o ){
if( period_ >= o.period() ){
// No need to resize.
}
// Copy contents of storage:
storage_.resize( o.period() );
period_ = o.period();
current_ = o.current();
std::copy( o.storage().begin(), o.storage().end(),
storage_.begin() );
}
return *this;
}
~cyclic_buffer(){}
std::vector<T> &storage()
{
return storage_;
}
const std::vector<T> &storage() const
{
return storage_;
}
T* data() { return storage_.data(); }
const T* data() const { return storage_.data(); }
/**
\brief is the buffer empty?
\returns true if buffer is empty, false otherwise.
*/
bool empty() const {
return storage_.empty();
}
T operator[]( std::size_t i ) const
{
long j = current_ - i - 1;
if( j < 0 ) j += period_;
return storage_[j];
}
T& operator[]( std::size_t i )
{
long j = current_ - i - 1;
if( j < 0 ) j += period_;
return storage_[j];
}
void push_back( const T &t )
{
int storage_size = storage_.size();
if( storage_size < period_ ){
storage_.push_back(t);
}else{
if( current_ == period_ ){
current_ = 0;
}
storage_[current_] = t;
}
++current_;
}
std::size_t size() const { return storage_.size(); }
std::size_t period() const { return period_; }
int current() const { return current_; }
/**
\brief Resizes the internal storage.
\warning This invalidates the contents of the cyclic buffer!
*/
void resize( std::size_t size )
{
storage_.clear();
storage_.reserve( size );
period_ = size;
current_ = 0;
}
/*
max_size
capacity
empty
reserve
shrink_to_fit
*/
private:
int period_;
int current_;
std::vector<T> storage_;
};
#endif // CYCLIC_BUFFER