UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
RingBuffer.hpp
[詳解]
1//
2// 疑似可変長リングバッファコンテナ
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
10#include <algorithm>
11#include <cstddef>
12#include <iterator>
13
14namespace Udon
15{
16
20 template <typename T, size_t Capacity>
22 {
23 public:
24 struct iterator;
25 struct const_iterator;
26
27 using value_type = T;
28 using reference = T&;
29 using const_reference = const T&;
30 using pointer = T*;
31 using const_pointer = const T*;
32 using reverse_iterator = std::reverse_iterator<iterator>;
33 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
34
35 private:
36 value_type m_data[Capacity];
37 size_t m_head;
38 size_t m_tail;
39 size_t m_size;
40
41 public:
43 constexpr RingBuffer()
44 : m_data{}
45 , m_head{}
46 , m_tail{}
47 , m_size{}
48 {
49 }
50
53 constexpr RingBuffer(const RingBuffer& other)
54 : m_data{ other.m_data }
55 , m_head{ other.m_head }
56 , m_tail{ other.m_tail }
57 , m_size{ other.m_size }
58 {
59 }
60
65 : m_data{}
66 , m_head{}
67 , m_tail{}
68 , m_size{ std::min(size, capacity()) }
69 {
70 std::fill(begin(), end(), value);
71 }
72
75 constexpr explicit RingBuffer(size_t size)
76 : m_data{}
77 , m_head{}
78 , m_tail{}
79 , m_size{ std::min(size, capacity()) }
80 {
81 }
82
83 RingBuffer(std::initializer_list<value_type> init)
84 : m_data{}
85 , m_head{}
86 , m_tail{}
87 , m_size{ std::min(init.size, capacity()) }
88 {
89 std::copy(init.begin(), init.end(), begin());
90 }
91
94 constexpr size_t capacity() const
95 {
96 return Capacity;
97 }
98
101 constexpr size_t size() const
102 {
103 return m_size;
104 }
105
108 void resize(size_t size)
109 {
110 m_size = std::min(size, capacity());
111 }
112
113 constexpr bool empty() const
114 {
115 return m_size == 0;
116 }
117
118 constexpr bool full() const
119 {
120 return m_size == capacity();
121 }
122
126 {
127 if (full())
128 {
129 pop();
130 }
131 m_data[m_tail] = value;
132 if (++m_tail == Capacity)
133 {
134 m_tail = 0;
135 }
136 ++m_size;
137 }
138
141 void push(value_type&& value)
142 {
143 if (full())
144 {
145 pop();
146 }
147 m_data[m_tail] = std::move(value);
148 if (++m_tail == Capacity)
149 {
150 m_tail = 0;
151 }
152 ++m_size;
153 }
154
158 {
159 if (empty())
160 {
161 return {};
162 }
163 auto&& retval = std::move(m_data[m_head]);
164 if (++m_head == Capacity)
165 {
166 m_head = 0;
167 }
168 --m_size;
169 return retval;
170 }
171
173 {
174 return m_data[(m_tail + Capacity - 1) % Capacity];
175 }
177 {
178 return m_data[(m_tail + Capacity - 1) % Capacity];
179 }
180
182 {
183 return m_data[m_head];
184 }
186 {
187 return m_data[m_head];
188 }
189
190 reference operator[](size_t index)
191 {
192 return m_data[(m_head + index) % Capacity];
193 }
194 const_reference operator[](size_t index) const
195 {
196 return m_data[(m_head + index) % Capacity];
197 }
198
200 {
201 using iterator_category = std::random_access_iterator_tag;
202 using value_type = T;
203 using difference_type = std::ptrdiff_t;
204 using pointer = const T*;
205 using reference = const T&;
206
208 size_t m_index;
209 size_t m_size;
210
211 const_iterator(pointer data, size_t index, size_t size)
212 : m_data{ data }
213 , m_index{ index }
214 , m_size{ size }
215 {
216 }
217
219 {
220 return m_data[m_index % m_size];
221 }
223 {
224 return &m_data[m_index % m_size];
225 }
227 {
228 ++m_index;
229 return *this;
230 }
232 {
233 --m_index;
234 return *this;
235 }
236 const_iterator operator+(size_t offset) const
237 {
238 return { m_data, m_index + offset, m_size };
239 }
240 const_iterator operator-(size_t offset) const
241 {
242 return { m_data, m_index - offset, m_size };
243 }
245 {
246 return m_index - other.m_index;
247 }
249 {
250 m_index += offset;
251 return *this;
252 }
254 {
255 m_index -= offset;
256 return *this;
257 }
258 bool operator!=(const const_iterator& other) const
259 {
260 return m_index != other.m_index;
261 }
262 bool operator==(const const_iterator& other) const
263 {
264 return m_index == other.m_index;
265 }
266 bool operator<(const const_iterator& other) const
267 {
268 return m_index < other.m_index;
269 }
270 bool operator<=(const const_iterator& other) const
271 {
272 return m_index <= other.m_index;
273 }
274 bool operator>(const const_iterator& other) const
275 {
276 return m_index > other.m_index;
277 }
278 bool operator>=(const const_iterator& other) const
279 {
280 return m_index >= other.m_index;
281 }
282 reference operator[](size_t offset) const
283 {
284 return m_data[(m_index + offset) % m_size];
285 }
286 };
287
288 struct iterator
289 : public const_iterator
290 {
291 using iterator_category = std::random_access_iterator_tag;
292 using value_type = T;
293 using difference_type = std::ptrdiff_t;
294 using pointer = T*;
295 using reference = T&;
296
297 iterator(pointer data, size_t index, size_t size)
298 : const_iterator{ data, index, size }
299 {
300 }
301
303 {
304 return const_cast<reference>(const_iterator::operator*());
305 }
307 {
308 return const_cast<pointer>(const_iterator::operator->());
309 }
310
312 {
314 return *this;
315 }
317 {
319 return *this;
320 }
321 iterator operator+(size_t offset) const
322 {
324 }
325 iterator operator-(size_t offset) const
326 {
328 }
330 {
331 return const_iterator::operator-(other);
332 }
333 iterator operator+=(size_t offset)
334 {
336 return *this;
337 }
338 iterator operator-=(size_t offset)
339 {
341 return *this;
342 }
343 reference operator[](size_t offset)
344 {
345 return const_cast<reference>(const_iterator::operator[](offset));
346 }
347 };
348
352 {
353 return { m_data, m_head, Capacity };
354 }
355
359 {
360 return { m_data, m_head + m_size, Capacity };
361 }
362
366 {
367 return { m_data, m_head, Capacity };
368 }
372 {
373 return { m_data, m_head + m_size, Capacity };
374 }
375
379 {
380 return { m_data, m_head, Capacity };
381 }
382
386 {
387 return { m_data, m_head + m_size, Capacity };
388 }
389
391 {
392 return const_reverse_iterator{ end() };
393 }
395 {
396 return reverse_iterator{ end() };
397 }
398
400 {
401 return const_reverse_iterator{ begin() };
402 }
404 {
405 return reverse_iterator{ begin() };
406 }
407
409 {
410 return const_reverse_iterator{ cend() };
411 }
412
414 {
415 return const_reverse_iterator{ cbegin() };
416 }
417 };
418
419} // namespace Udon
リングバッファ
Definition RingBuffer.hpp:22
reference operator[](size_t index)
Definition RingBuffer.hpp:190
const T * const_pointer
Definition RingBuffer.hpp:31
constexpr size_t capacity() const
capacityを取得
Definition RingBuffer.hpp:94
void push(const_reference value)
バッファの先頭に要素を追加
Definition RingBuffer.hpp:125
std::reverse_iterator< iterator > reverse_iterator
Definition RingBuffer.hpp:32
T & reference
Definition RingBuffer.hpp:28
constexpr bool empty() const
Definition RingBuffer.hpp:113
reference back()
Definition RingBuffer.hpp:172
value_type pop()
バッファの末尾を取得し要素を削除
Definition RingBuffer.hpp:157
T * pointer
Definition RingBuffer.hpp:30
iterator end()
バッファの末尾イテレーターを取得
Definition RingBuffer.hpp:358
const_iterator cend() const
バッファの末尾イテレーターを取得
Definition RingBuffer.hpp:385
reverse_iterator rbegin()
Definition RingBuffer.hpp:394
reverse_iterator rend()
Definition RingBuffer.hpp:403
RingBuffer(std::initializer_list< value_type > init)
Definition RingBuffer.hpp:83
const_reference operator[](size_t index) const
Definition RingBuffer.hpp:194
void resize(size_t size)
バッファサイズを変更
Definition RingBuffer.hpp:108
const_reverse_iterator crbegin() const
Definition RingBuffer.hpp:408
const_reverse_iterator rbegin() const
Definition RingBuffer.hpp:390
void push(value_type &&value)
バッファの先頭に要素を追加
Definition RingBuffer.hpp:141
T value_type
Definition RingBuffer.hpp:27
const_reverse_iterator rend() const
Definition RingBuffer.hpp:399
constexpr RingBuffer(const RingBuffer &other)
コピーコンストラクタ
Definition RingBuffer.hpp:53
const_iterator cbegin() const
バッファの先頭イテレーターを取得
Definition RingBuffer.hpp:378
iterator begin()
バッファの先頭イテレーターを取得
Definition RingBuffer.hpp:351
const_iterator begin() const
バッファの先頭イテレーターを取得
Definition RingBuffer.hpp:365
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition RingBuffer.hpp:33
const_reverse_iterator crend() const
Definition RingBuffer.hpp:413
reference front()
Definition RingBuffer.hpp:181
const_reference back() const
Definition RingBuffer.hpp:176
constexpr size_t size() const
バッファサイズを取得
Definition RingBuffer.hpp:101
const_reference front() const
Definition RingBuffer.hpp:185
constexpr RingBuffer()
コンストラクタ
Definition RingBuffer.hpp:43
constexpr bool full() const
Definition RingBuffer.hpp:118
const_iterator end() const
バッファの末尾イテレーターを取得
Definition RingBuffer.hpp:371
constexpr RingBuffer(size_t size)
デフォルトで初期化しないコンストラクタ
Definition RingBuffer.hpp:75
const T & const_reference
Definition RingBuffer.hpp:29
RingBuffer(size_t size, const_reference value)
デフォルトで初期化するコンストラクタ
Definition RingBuffer.hpp:64
Definition Bit.hpp:12
Definition Typedef.hpp:94
Definition RingBuffer.hpp:200
bool operator>(const const_iterator &other) const
Definition RingBuffer.hpp:274
const_iterator operator-=(size_t offset)
Definition RingBuffer.hpp:253
pointer operator->() const
Definition RingBuffer.hpp:222
const_iterator operator+=(size_t offset)
Definition RingBuffer.hpp:248
bool operator<=(const const_iterator &other) const
Definition RingBuffer.hpp:270
bool operator<(const const_iterator &other) const
Definition RingBuffer.hpp:266
const_iterator(pointer data, size_t index, size_t size)
Definition RingBuffer.hpp:211
const_iterator operator+(size_t offset) const
Definition RingBuffer.hpp:236
const_iterator operator-(size_t offset) const
Definition RingBuffer.hpp:240
std::random_access_iterator_tag iterator_category
Definition RingBuffer.hpp:201
const_iterator & operator++()
Definition RingBuffer.hpp:226
bool operator!=(const const_iterator &other) const
Definition RingBuffer.hpp:258
pointer m_data
Definition RingBuffer.hpp:207
const_iterator & operator--()
Definition RingBuffer.hpp:231
bool operator==(const const_iterator &other) const
Definition RingBuffer.hpp:262
size_t m_index
Definition RingBuffer.hpp:208
const T & reference
Definition RingBuffer.hpp:205
std::ptrdiff_t difference_type
Definition RingBuffer.hpp:203
const T * pointer
Definition RingBuffer.hpp:204
T value_type
Definition RingBuffer.hpp:202
bool operator>=(const const_iterator &other) const
Definition RingBuffer.hpp:278
size_t m_size
Definition RingBuffer.hpp:209
difference_type operator-(const const_iterator &other) const
Definition RingBuffer.hpp:244
reference operator[](size_t offset) const
Definition RingBuffer.hpp:282
reference operator*() const
Definition RingBuffer.hpp:218
Definition RingBuffer.hpp:290
iterator operator-=(size_t offset)
Definition RingBuffer.hpp:338
reference operator*()
Definition RingBuffer.hpp:302
T value_type
Definition RingBuffer.hpp:292
iterator(pointer data, size_t index, size_t size)
Definition RingBuffer.hpp:297
difference_type operator-(const iterator &other) const
Definition RingBuffer.hpp:329
iterator operator+=(size_t offset)
Definition RingBuffer.hpp:333
reference operator[](size_t offset)
Definition RingBuffer.hpp:343
iterator operator+(size_t offset) const
Definition RingBuffer.hpp:321
std::random_access_iterator_tag iterator_category
Definition RingBuffer.hpp:291
iterator operator-(size_t offset) const
Definition RingBuffer.hpp:325
std::ptrdiff_t difference_type
Definition RingBuffer.hpp:293
iterator & operator++()
Definition RingBuffer.hpp:311
T * pointer
Definition RingBuffer.hpp:294
iterator & operator--()
Definition RingBuffer.hpp:316
pointer operator->()
Definition RingBuffer.hpp:306
T & reference
Definition RingBuffer.hpp:295