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