collection2  v0.6.0
Loading...
Searching...
No Matches
buffer.hpp
1//
2// リングバッファ
3//
4
5#ifndef _COLLECTION2_BUFFER_H_
6#define _COLLECTION2_BUFFER_H_
7
8#include <stddef.h>
9
10#include "common.hpp"
11
12namespace collection2 {
13
20template <typename Element, typename Size = size_t>
21class Buffer {
22 private:
26 Element* const internalData;
27
31 Size internalDataSize;
32
36 Size head = 0;
37
41 Size tail = 0;
42
46 Size count = 0;
47
48 public:
56 Buffer(Element* const data, const Size& dataSize);
57
58 Buffer(const Buffer&) = delete;
59 Buffer& operator=(const Buffer&) = delete;
60
61 ~Buffer() = default;
62
69 OperationResult append(const Element& data);
70
77 OperationResult pop(Element* const data);
78
84 Size capacity() const {
85 return internalDataSize;
86 }
87
93 Size amount() const {
94 return count;
95 }
96
102 bool hasSpace() const {
103 return count < internalDataSize;
104 }
105
111 bool isEmpty() const {
112 return count == 0;
113 }
114};
115
116template <typename Element, typename Size>
117Buffer<Element, Size>::Buffer(Element* const data, const Size& dataSize) : internalData(data) {
118 // ゼロ長のバッファなら何もしない
119 if (dataSize == 0) {
120 internalDataSize = dataSize;
121 return;
122 }
123
124 // 与えられたサイズを上回らない最大の2の冪数を探す
125 unsigned char maxbitPos = 0;
126 Size size = dataSize;
127 while ((size >>= 1) != 0) {
128 maxbitPos++;
129 }
130 internalDataSize = 1 << maxbitPos;
131};
132
133template <typename Element, typename Size>
135 // サイズ0のバッファに値を追加することはできない
136 if (internalDataSize == 0) {
137 return OperationResult::Overflow;
138 }
139
140 // バッファがいっぱいなら、要素を一つ読み捨てる
141 if (!hasSpace()) {
142 auto result = pop(nullptr);
143 }
144
145 // tailの位置にデータを書き込む
146 *(internalData + tail) = data;
147
148 tail = (tail + 1) & (internalDataSize - 1);
149 count++;
150
151 return OperationResult::Success;
152}
153
154template <typename Element, typename Size>
156 // バッファが空なら戻る
157 if (isEmpty()) {
158 return OperationResult::Empty;
159 }
160
161 // 読み出して渡す。nullptrなら何もしないでheadを進める。
162 if (data != nullptr) {
163 *data = *(internalData + head);
164 }
165
166 head = (head + 1) & (internalDataSize - 1);
167 count--;
168
169 return OperationResult::Success;
170}
171
172} // namespace collection2
173
174#endif
リングバッファ
Definition: buffer.hpp:21
OperationResult append(const Element &data)
バッファの末尾にデータを追加
Definition: buffer.hpp:134
bool isEmpty() const
バッファが空かどうか
Definition: buffer.hpp:111
OperationResult pop(Element *const data)
バッファの先頭からデータを取り出し
Definition: buffer.hpp:155
Buffer(Element *const data, const Size &dataSize)
内部データを扱う領域とそのサイズを指定してバッファを初期化
Definition: buffer.hpp:117
Size capacity() const
バッファの全体長を返す
Definition: buffer.hpp:84
Size amount() const
現在バッファ内にあるデータ数を返す
Definition: buffer.hpp:93
bool hasSpace() const
バッファに値を追加できるか
Definition: buffer.hpp:102
OperationResult
コレクション操作結果
Definition: common.hpp:14