0.2.0
Loading...
Searching...
No Matches
ScrollingBuffer.hpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
13
14#pragma once
15
16#include <vector>
17#include <string>
18#include <iostream>
19#include <fmt/ostream.h>
20
21namespace NAV
22{
23
27template<class T, size_t _Padding = 0>
29{
30 public:
31 // ###########################################################################################################
32 // Constructors
33 // ###########################################################################################################
34
37 explicit ScrollingBuffer(size_t maxSize = 0)
38 : _infiniteBuffer(maxSize == 0), _maxSize(maxSize + _Padding), _dataStart(_Padding), _dataEnd(_infiniteBuffer ? 0 : _Padding)
39 {
40 _data.reserve(maxSize + _Padding);
41 _data.resize(_Padding);
42 }
43
46 ScrollingBuffer(std::initializer_list<T> init)
47 : _infiniteBuffer(init.size() == 0), _maxSize(init.size())
48 {
49 _data.reserve(init.size());
50
51 for (auto& val : init)
52 {
53 push_back(val);
54 }
55 }
56
57 // ###########################################################################################################
58 // Element access
59 // ###########################################################################################################
60
65 T& at(size_t pos)
66 {
67 // Cast the const away and reuse the implementation below
68 return const_cast<T&>(static_cast<const ScrollingBuffer&>(*this).at(pos)); // NOLINT(cppcoreguidelines-pro-type-const-cast)
69 }
70
75 [[nodiscard]] const T& at(size_t pos) const
76 {
77 if (!(pos < size()))
78 {
79 throw std::out_of_range("ScrollingBuffer::at: pos (which is "
80 + std::to_string(pos) + ") >= this->size() (which is " + std::to_string(size()) + ")");
81 }
82
83 // start/end
84 // |
85 // 8 9 3 4 5 6 7
86 // at(0) = 3, at(4) = 7, at(5) = 8
87 if (_dataStart + pos >= _maxSize)
88 {
89 return _data.at(_dataStart + pos - _maxSize);
90 }
91
92 return _data.at(_dataStart + pos);
93 }
94
98 T& front()
99 {
100 // Cast the const away and reuse the implementation below (don't repeat yourself)
101 return const_cast<T&>(static_cast<const ScrollingBuffer&>(*this).front()); // NOLINT(cppcoreguidelines-pro-type-const-cast)
102 }
103
107 [[nodiscard]] const T& front() const
108 {
109 return _data.at(_dataStart);
110 }
111
115 T& back()
116 {
117 return const_cast<T&>(static_cast<const ScrollingBuffer&>(*this).back()); // NOLINT(cppcoreguidelines-pro-type-const-cast)
118 }
119
123 [[nodiscard]] const T& back() const
124 {
125 if (_data.size() < _maxSize || _dataEnd == 0)
126 {
127 return _data.back();
128 }
129
130 return _data.at(_dataEnd - 1);
131 }
132
133 // ###########################################################################################################
134 // Iterators
135 // ###########################################################################################################
136
139 {
140 public:
141 using iterator_category = std::forward_iterator_tag;
142 using difference_type = std::ptrdiff_t;
143 using value_type = T;
144 using pointer = T*;
145 using reference = T&;
146
150 explicit Iterator(ScrollingBuffer& buffer, size_t index = 0)
151 : buffer(buffer), index(index) {}
152
154 reference operator*() const { return buffer.at(index); }
156 pointer operator->() { return &buffer.at(index); }
157
160 {
161 if (index == buffer.size()) { return *this; }
162 index++;
163 return *this;
164 }
167 {
168 Iterator tmp = *this;
169 operator++();
170 return tmp;
171 }
172
177 friend bool operator==(const Iterator& lhs, const Iterator& rhs) { return &lhs.buffer == &rhs.buffer && lhs.index == rhs.index; };
182 friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return !(lhs == rhs); };
183
184 private:
185 ScrollingBuffer& buffer;
186 size_t index;
187 };
188
192 Iterator begin() { return Iterator(*this, 0); }
196 Iterator end() { return Iterator(*this, size()); }
197
200 {
201 public:
202 using iterator_category = std::forward_iterator_tag;
203 using difference_type = std::ptrdiff_t;
204 using value_type = T;
205 using pointer = const T*;
206 using reference = const T&;
207
211 explicit ConstIterator(const ScrollingBuffer& buffer, size_t index = 0)
212 : buffer(buffer), index(index) {}
213
215 reference operator*() const { return buffer.at(index); }
217 pointer operator->() { return &buffer.at(index); }
218
221 {
222 if (index == buffer.size()) { return *this; }
223 index++;
224 return *this;
225 }
228 {
229 ConstIterator tmp = *this;
230 operator++();
231 return tmp;
232 }
233
238 friend bool operator==(const ConstIterator& lhs, const ConstIterator& rhs) { return &lhs.buffer == &rhs.buffer && lhs.index == rhs.index; };
243 friend bool operator!=(const ConstIterator& lhs, const ConstIterator& rhs) { return !(lhs == rhs); };
244
245 private:
246 const ScrollingBuffer& buffer;
247 size_t index;
248 };
249
253 [[nodiscard]] ConstIterator begin() const { return ConstIterator(*this, 0); }
257 [[nodiscard]] ConstIterator end() const { return ConstIterator(*this, size()); }
261 [[nodiscard]] ConstIterator cbegin() const { return ConstIterator(*this, 0); }
265 [[nodiscard]] ConstIterator cend() const { return ConstIterator(*this, size()); }
266
269 {
270 public:
271 using iterator_category = std::forward_iterator_tag;
272 using difference_type = std::ptrdiff_t;
273 using value_type = T;
274 using pointer = T*;
275 using reference = T&;
276
280 explicit ReverseIterator(ScrollingBuffer& buffer, int64_t index = 0)
281 : buffer(buffer), index(index) {}
282
284 reference operator*() const { return buffer.at(static_cast<size_t>(index)); }
286 pointer operator->() { return &buffer.at(static_cast<size_t>(index)); }
287
290 {
291 if (index < 0) { return *this; }
292 index--;
293 return *this;
294 }
297 {
298 ReverseIterator tmp = *this;
299 operator++();
300 return tmp;
301 }
302
307 friend bool operator==(const ReverseIterator& lhs, const ReverseIterator& rhs) { return &lhs.buffer == &rhs.buffer && lhs.index == rhs.index; };
312 friend bool operator!=(const ReverseIterator& lhs, const ReverseIterator& rhs) { return !(lhs == rhs); };
313
314 private:
315 ScrollingBuffer& buffer;
316 int64_t index;
317 };
318
323 ReverseIterator rbegin() { return ReverseIterator(*this, static_cast<int64_t>(size()) - 1); }
328 ReverseIterator rend() { return ReverseIterator(*this, -1); }
329
332 {
333 public:
334 using iterator_category = std::forward_iterator_tag;
335 using difference_type = std::ptrdiff_t;
336 using value_type = T;
337 using pointer = const T*;
338 using reference = const T&;
339
343 explicit ConstReverseIterator(const ScrollingBuffer& buffer, int64_t index = 0)
344 : buffer(buffer), index(index) {}
345
347 reference operator*() const { return buffer.at(static_cast<size_t>(index)); }
349 pointer operator->() { return &buffer.at(static_cast<size_t>(index)); }
350
353 {
354 if (index < 0) { return *this; }
355 index--;
356 return *this;
357 }
360 {
361 ConstReverseIterator tmp = *this;
362 operator++();
363 return tmp;
364 }
365
370 friend bool operator==(const ConstReverseIterator& lhs, const ConstReverseIterator& rhs) { return &lhs.buffer == &rhs.buffer && lhs.index == rhs.index; };
375 friend bool operator!=(const ConstReverseIterator& lhs, const ConstReverseIterator& rhs) { return !(lhs == rhs); };
376
377 private:
378 const ScrollingBuffer& buffer;
379 int64_t index;
380 };
381
386 [[nodiscard]] ConstReverseIterator rbegin() const { return ConstReverseIterator(*this, static_cast<int64_t>(size()) - 1); }
391 [[nodiscard]] ConstReverseIterator rend() const { return ConstReverseIterator(*this, -1); }
396 [[nodiscard]] ConstReverseIterator crbegin() const { return ConstReverseIterator(*this, static_cast<int64_t>(size()) - 1); }
401 [[nodiscard]] ConstReverseIterator crend() const { return ConstReverseIterator(*this, -1); }
402
403 // ###########################################################################################################
404 // Capacity
405 // ###########################################################################################################
406
408 [[nodiscard]] bool empty() const
409 {
410 return size() == 0;
411 }
412
414 [[nodiscard]] bool full() const
415 {
416 return !_infiniteBuffer && _maxSize - _Padding == size();
417 }
418
420 [[nodiscard]] size_t size() const
421 {
422 if (_dataStart == _Padding && _dataEnd == _Padding) // Buffer empty or full and not scrolled
423 {
424 return _data.size() - _Padding;
425 }
426 if (_dataStart < _dataEnd) // not scrolled buffer
427 {
428 return _dataEnd - _dataStart;
429 }
430
431 // scrolled buffer
432 return _maxSize - (_dataStart - _dataEnd);
433 }
434
437 void reserve(size_t new_cap)
438 {
439 _data.reserve(new_cap);
440 }
441
443 [[nodiscard]] size_t capacity() const
444 {
445 return _infiniteBuffer ? 0 : (_maxSize - _Padding);
446 }
447
448 // ###########################################################################################################
449 // Modifiers
450 // ###########################################################################################################
451
453 void clear()
454 {
455 _data.clear();
456 _dataStart = _Padding;
457 _dataEnd = _infiniteBuffer ? 0 : _Padding;
458
459 for (size_t i = 0; i < _Padding; i++)
460 {
461 _data.push_back({});
462 }
463 }
464
467 void push_back(const T& value)
468 {
469 if (_infiniteBuffer) // The buffer should grow when adding new values
470 {
471 _data.push_back(value);
472 _maxSize = _data.size();
473 }
474 else if (_data.size() < _maxSize) // The real buffer is smaller than the allowed buffer size
475 {
476 _data.push_back(value);
477 _dataEnd = (_dataEnd + 1) % _maxSize;
478 }
479 else // The real buffer as large as or bigger than the allowed buffer size, so we have to scroll the buffer
480 {
481 _data.at(_dataEnd) = value;
482 if (size() >= capacity())
483 {
484 // "5, 6, _, _, 2, 3, 4"
485 // "5, 6, 7, _, 2, 3, 4"
486 _dataStart = (_dataStart + 1) % _maxSize;
487 }
488 _dataEnd = (_dataEnd + 1) % _maxSize;
489 }
490 }
491
494 {
495 if (empty())
496 {
497 return;
498 }
499 if (size() == 1)
500 {
501 clear();
502 return;
503 }
504
505 if (_infiniteBuffer)
506 {
507 _data.erase(_data.begin());
508 _maxSize = _data.size();
509 }
510 else
511 {
512 // se e s e s s e se
513 // 5, 6, 2, 3, 4 // 5, 6, _, _, 2, 3, 4 // 5, 6, X, X, 2, 3, 4 // X, 6, 7, 8, 9, 10, X // 5, 6, 7, 4
514 // e s e s e s s e s e
515 // 5, 6, _, 3, 4 // 5, 6, _, _, _, 3, 4 // 5, 6, _, X, X, 3, 4 // X, X, 7, 8, 9, 10, _ // 5, 6, 7, _
516 _dataStart = (_dataStart + 1) % _maxSize;
517 }
518 }
519
522 void resize(size_t targetSize)
523 {
524 if (targetSize == 0) // Buffer should grow indefinitely when adding new values
525 {
526 _infiniteBuffer = true;
527
528 if (isScrolled()) // Buffer is scrolled and needs to be sorted in order of insertion
529 {
530 // se e s e s s e
531 // 5, 6, 2, 3, 4 // 5, 6, _, _, 2, 3, 4 // 5, 6, X, X, 2, 3, 4 // X, 6, 7, 8, 9, 10, X
532 // 2, 3, 4, 5, 6 // 2, 3, 4, 5, 6, _, _ // X, X, 2, 3, 4, 5, 6 // X, X, 6, 7, 8, 9, 10
533 std::vector<T> to_vector;
534
535 if (_dataEnd > _dataStart)
536 {
537 std::copy(std::next(_data.begin(), static_cast<int64_t>(_dataEnd)), _data.end(),
538 std::back_inserter(to_vector));
539 _maxSize = _dataEnd;
540 }
541
542 std::copy(std::next(_data.begin(), std::max(static_cast<int>(_dataStart - _Padding), 0)),
543 std::next(_data.begin(), static_cast<int64_t>(std::max(_dataEnd, _maxSize))),
544 std::back_inserter(to_vector));
545
546 if (int64_t elementsFront = std::min(static_cast<int64_t>(_dataEnd), static_cast<int64_t>(_dataStart - _Padding));
547 elementsFront > 0)
548 {
549 std::copy(_data.begin(), std::next(_data.begin(), elementsFront),
550 std::back_inserter(to_vector));
551 }
552 _data.swap(to_vector);
553
554 _maxSize = _data.size();
555
556 _dataStart = _Padding;
557 _dataEnd = 0;
558 }
559 }
560 else // Buffer should have scrolling behaviour when adding new values
561 {
562 _infiniteBuffer = false;
563
564 if (_maxSize - _Padding > targetSize) // We make the buffer smaller
565 {
566 if (!isScrolled()) // Buffer is not scrolled, so shrinking removes the values from the front of the buffer
567 {
568 size_t elementsToDelete = _maxSize - _Padding - targetSize;
569
570 if (size_t emptyAtTheBack = _maxSize - _dataEnd;
571 size_t emptyAtTheBackToDelete = std::min(emptyAtTheBack, elementsToDelete))
572 {
573 // 1, 2, 3, _, _, // X, X, 1, 2, 3, _, _,
574 // 1, 2, 3, _, // X, X, 1, 2, 3, _,
575 _maxSize -= emptyAtTheBackToDelete;
576 _dataEnd %= _maxSize; // NOLINT(clang-analyzer-core.DivideZero) // this lint is wrong, even when wrapped by `if(_maxSize != 0)` appearing
577 elementsToDelete -= emptyAtTheBackToDelete;
578 // 1, 2, 3, // X, X, 1, 2, 3,
579 }
580
581 // 1, 2, 3,
582 // 2, 3,
583 if (elementsToDelete)
584 {
585 _data.erase(std::next(_data.begin(), static_cast<int64_t>(_dataStart)),
586 std::next(_data.begin(), static_cast<int64_t>(_dataStart + elementsToDelete)));
587 _maxSize -= elementsToDelete;
588 }
589 }
590 else // Buffer is scrolled, so the correct values have to be erased from the buffer when shrinking
591 {
592 // 5, 6, _, _, 2, 3, 4, // 5, 6, _, _, X, X, 2, 3, 4,
593 // 6, // 6, X, X
594
595 // 6, 7, 3, 4, 5, // 5, 6, X, X, 2, 3, 4
596 // 6, 7, 4, 5, // 5, 6, X, X, 3, 4
597
598 // X, 6, 7, 8, 9, 10, X
599 // X, 9, 10, X
600
601 size_t elementsToDelete = _maxSize - _Padding - targetSize;
602
603 if (size_t emptyInBetween = static_cast<size_t>(std::max(static_cast<int>(_dataStart - _Padding - _dataEnd), 0));
604 size_t emptyInBetweenToDelete = std::min(emptyInBetween, elementsToDelete))
605 {
606 // 5, 6, _, _, 2, 3, 4, // 5, 6, _, _, X, X, 2, 3, 4,
607 _data.erase(std::next(_data.begin(), static_cast<int64_t>(_dataEnd)),
608 std::next(_data.begin(), static_cast<int64_t>(_dataEnd + emptyInBetweenToDelete)));
609 // 5, 6, _, 2, 3, 4, // 5, 6, _, X, X, 2, 3, 4,
610 _dataStart -= emptyInBetweenToDelete;
611 _maxSize -= emptyInBetweenToDelete;
612 elementsToDelete -= emptyInBetweenToDelete;
613 }
614
615 // s e
616 // X , 6, 7 , 8 , 9, 10, X
617 // X(8), 9, 10, X(7)
618 if (size_t paddingAtTheEnd = static_cast<size_t>(std::max(static_cast<int>(_Padding - _dataStart), 0));
619 size_t paddingAtTheEndToDelete = std::min(paddingAtTheEnd, elementsToDelete))
620 {
621 _data.erase(std::next(_data.begin(), static_cast<int64_t>(_dataEnd)),
622 std::next(_data.begin(), static_cast<int64_t>(_dataEnd + paddingAtTheEndToDelete)));
623 _maxSize -= paddingAtTheEndToDelete;
624 _dataStart += paddingAtTheEndToDelete;
625 _dataEnd %= _maxSize;
626 elementsToDelete -= paddingAtTheEndToDelete;
627 }
628 // e s
629 // X, X, 6, 7 , 8 , 9, 10
630 // X, X, 7 , 8 , 9, 10
631
632 if (size_t elementsAtTheBack = _maxSize - _dataStart - (_dataEnd > _dataStart ? _maxSize - _dataEnd : 0);
633 size_t elementsAtTheBackToDelete = std::min(elementsAtTheBack, elementsToDelete))
634 {
635 // 5, 6, 2, 3, 4, // 5, 6, X, X, 2, 3, 4,
636 _data.erase(std::next(_data.begin(), static_cast<int64_t>(_dataStart - _Padding)),
637 std::next(_data.begin(), static_cast<int64_t>(_dataStart - _Padding + elementsAtTheBackToDelete)));
638 // 5, 6, 4, // 5, 6, X, X, 4,
639 // 5, 6, // 5, 6, X, X,
640 _maxSize -= elementsAtTheBackToDelete;
641 _dataStart %= _maxSize;
642 if (_dataEnd > _maxSize)
643 {
644 _dataEnd -= elementsToDelete;
645 }
646 _dataEnd %= _maxSize;
647 elementsToDelete -= elementsAtTheBackToDelete;
648 }
649 if (elementsToDelete)
650 {
651 // 5, 6, // 5, 6, X, X,
652 _data.erase(std::next(_data.begin(), static_cast<int64_t>(_dataStart)),
653 std::next(_data.begin(), static_cast<int64_t>(std::min(_dataStart + elementsToDelete, _maxSize - _Padding))));
654 // 6, // 6, X, X
655 _maxSize -= elementsToDelete;
656 if (_dataEnd >= elementsToDelete)
657 {
658 _dataEnd -= elementsToDelete;
659 }
660 }
661 }
662 }
663 else if (_maxSize - _Padding < targetSize) // We make the buffer bigger
664 {
665 // 1, 2, 3, _, _, // X, X, 0, 1, 2, 3, _, _
666 // 1, 2, 3, _, _, _, _, // X, X, 0, 1, 2, 3, _, _, _, _
667 if (!isScrolled()) // Buffer not scrolled, so we can simply reserve more space
668 {
669 _maxSize = targetSize + _Padding;
670 _data.reserve(_maxSize);
671 }
672 // se e s s e
673 // 6, 7, 3, 4, 5, // 5, 6, X, X, 2, 3, 4 // X, 6, 7, 8, 9, 10, X
674 // 6, 7, _, 3, 4, 5, // 5, 6, _, X, X, 2, 3, 4 // X, 6, 7, 8, 9, 10, _, _, X
675 else // (_dataStart != 0) // Buffer scrolled, so we need to copy the values to the correct positions
676 {
677 _data.resize(targetSize + _Padding);
678
679 std::copy_backward(std::next(_data.begin(), static_cast<int64_t>(_dataEnd)),
680 std::next(_data.begin(), static_cast<int64_t>(_maxSize)),
681 std::next(_data.begin(), static_cast<int64_t>(targetSize + _Padding)));
682
683 auto diff = targetSize + _Padding - _maxSize;
684 if (_dataStart >= _dataEnd)
685 {
686 _dataStart += diff;
687 }
688
689 _maxSize = targetSize + _Padding;
690 }
691 }
692 }
693 }
694
695 // ###########################################################################################################
696 // Other
697 // ###########################################################################################################
698
700 [[nodiscard]] T max() const
701 {
702 T currentMax = front();
703 for (size_t i = 0; i < _data.size(); i++)
704 {
705 if (i >= _dataStart || i < _dataEnd)
706 {
707 currentMax = std::max(currentMax, _data.at(i));
708 }
709 }
710 return currentMax;
711 }
712
714 [[nodiscard]] T min() const
715 {
716 T currentMin = front();
717 for (size_t i = 0; i < _data.size(); i++)
718 {
719 if (i >= _dataStart || i < _dataEnd)
720 {
721 currentMin = std::min(currentMin, _data.at(i));
722 }
723 }
724 return currentMin;
725 }
726
728 [[nodiscard]] int offset() const
729 {
730 return static_cast<int>(_dataStart);
731 }
732
734 [[nodiscard]] const T* data() const
735 {
736 return _data.data();
737 }
738
740 [[nodiscard]] T* data()
741 {
742 return _data.data();
743 }
744
746 [[nodiscard]] bool isInfiniteBuffer() const
747 {
748 return _infiniteBuffer;
749 }
750
752 [[nodiscard]] std::string getRawString() const
753 {
754 // Scrolled
755 // e s
756 // 5, 6, _, _, X, 2, 3, 4
757
758 // se
759 // 5, 6, 2, 3, 4
760
761 // s e
762 // _, 6, _, _, _
763
764 // Not scrolled
765 // s e
766 // X, X, 0, 1, 2, 3, _, _
767
768 // s e
769 // X, 6, 7, 8, 9, 10, _, _, X
770
771 // s e
772 // 6, X, X,
773
774 // s e
775 // 6, _, X, X,
776
777 // se
778 // X, X, _, _, _,
779
780 std::string out;
781
782 for (int i = 0; static_cast<size_t>(i) < _maxSize; i++) // X, 6, 7, 8, 9, 10, _, _, X
783 {
784 if ((i >= static_cast<int>(_dataStart - _Padding) && static_cast<size_t>(i) < _dataStart)
785 || (static_cast<size_t>(i) >= _dataStart + _maxSize - _Padding))
786 {
787 out += "X"; // padding
788 }
789 else if (bool scrolled = isScrolled();
790 (scrolled && static_cast<size_t>(i) >= _dataEnd && (static_cast<int>(_dataStart - _Padding) < 0 || i < static_cast<int>(_dataStart - _Padding)))
791 || (scrolled && _dataStart < _dataEnd && (static_cast<size_t>(i) < _dataStart || static_cast<size_t>(i) >= _dataEnd))
792 || (!scrolled && static_cast<size_t>(i) >= _dataEnd))
793 {
794 out += "_"; // empty
795 }
796 else
797 {
798 out += std::to_string(_data.at(static_cast<size_t>(i)));
799 }
800 if (static_cast<size_t>(i) != _maxSize - 1)
801 {
802 out += ", ";
803 }
804 }
805 return out;
806 }
807
812 friend std::ostream& operator<<(std::ostream& os, const ScrollingBuffer<T, _Padding>& buffer)
813 {
814 os << fmt::format("{}", fmt::join(buffer, ", "));
815 return os;
816 }
817
818 private:
820 bool _infiniteBuffer{ false };
823 size_t _maxSize;
825 size_t _dataStart{ 0 };
827 size_t _dataEnd{ 0 };
829 std::vector<T> _data;
830
832 [[nodiscard]] bool isScrolled() const
833 {
834 // e s
835 // 5, 6, _, _, X, 2, 3, 4
836
837 // se
838 if (_dataEnd == 0 && !empty()) // 1, 2, 3, 4
839 {
840 return true;
841 }
842
843 return _dataEnd < _dataStart
844 || (_dataStart != _Padding);
845
846 // se // se
847 // 5, 6, 2, 3, 4 // X, X, _, _, _
848
849 // s e
850 // X, 0, 1, 2, 3, _, _, X // Scrolled
851 // s e
852 // X, X, 0, 1, 2, 3, _, _ // Not scrolled
853 }
854};
855
856} // namespace NAV
857
858#ifndef DOXYGEN_IGNORE
859
860template<class T, size_t _Padding>
861struct fmt::formatter<NAV::ScrollingBuffer<T, _Padding>> : ostream_formatter
862{};
863
864#endif
Const iterator.
Definition ScrollingBuffer.hpp:200
reference operator*() const
Returns a reference to the current element.
Definition ScrollingBuffer.hpp:215
const T * pointer
value_type*
Definition ScrollingBuffer.hpp:205
ConstIterator(const ScrollingBuffer &buffer, size_t index=0)
Constructor.
Definition ScrollingBuffer.hpp:211
std::ptrdiff_t difference_type
Signed integer type (usually std::ptrdiff_t)
Definition ScrollingBuffer.hpp:203
pointer operator->()
Returns a pointer to the current element.
Definition ScrollingBuffer.hpp:217
ConstIterator operator++(int)
Advances the iterator.
Definition ScrollingBuffer.hpp:227
friend bool operator!=(const ConstIterator &lhs, const ConstIterator &rhs)
Inequality comparison operator.
Definition ScrollingBuffer.hpp:243
std::forward_iterator_tag iterator_category
To categorize the iteration direction.
Definition ScrollingBuffer.hpp:202
const T & reference
value_type&
Definition ScrollingBuffer.hpp:206
friend bool operator==(const ConstIterator &lhs, const ConstIterator &rhs)
Equality comparison operator.
Definition ScrollingBuffer.hpp:238
T value_type
T.
Definition ScrollingBuffer.hpp:204
const ConstIterator & operator++()
Advances the iterator.
Definition ScrollingBuffer.hpp:220
Const reverse iterator.
Definition ScrollingBuffer.hpp:332
const T & reference
value_type&
Definition ScrollingBuffer.hpp:338
const ConstReverseIterator & operator++()
Advances the iterator.
Definition ScrollingBuffer.hpp:352
const T * pointer
value_type*
Definition ScrollingBuffer.hpp:337
friend bool operator==(const ConstReverseIterator &lhs, const ConstReverseIterator &rhs)
Equality comparison operator.
Definition ScrollingBuffer.hpp:370
std::ptrdiff_t difference_type
Signed integer type (usually std::ptrdiff_t)
Definition ScrollingBuffer.hpp:335
friend bool operator!=(const ConstReverseIterator &lhs, const ConstReverseIterator &rhs)
Inequality comparison operator.
Definition ScrollingBuffer.hpp:375
std::forward_iterator_tag iterator_category
To categorize the iteration direction.
Definition ScrollingBuffer.hpp:334
reference operator*() const
Returns a reference to the current element.
Definition ScrollingBuffer.hpp:347
pointer operator->()
Returns a pointer to the current element.
Definition ScrollingBuffer.hpp:349
ConstReverseIterator operator++(int)
Advances the iterator.
Definition ScrollingBuffer.hpp:359
ConstReverseIterator(const ScrollingBuffer &buffer, int64_t index=0)
Constructor.
Definition ScrollingBuffer.hpp:343
T value_type
T.
Definition ScrollingBuffer.hpp:336
Iterator.
Definition ScrollingBuffer.hpp:139
T & reference
value_type&
Definition ScrollingBuffer.hpp:145
Iterator(ScrollingBuffer &buffer, size_t index=0)
Constructor.
Definition ScrollingBuffer.hpp:150
Iterator operator++(int)
Advances the iterator.
Definition ScrollingBuffer.hpp:166
reference operator*() const
Returns a reference to the current element.
Definition ScrollingBuffer.hpp:154
friend bool operator==(const Iterator &lhs, const Iterator &rhs)
Equality comparison operator.
Definition ScrollingBuffer.hpp:177
friend bool operator!=(const Iterator &lhs, const Iterator &rhs)
Inequality comparison operator.
Definition ScrollingBuffer.hpp:182
std::forward_iterator_tag iterator_category
To categorize the iteration direction.
Definition ScrollingBuffer.hpp:141
T * pointer
value_type*
Definition ScrollingBuffer.hpp:144
Iterator & operator++()
Advances the iterator.
Definition ScrollingBuffer.hpp:159
pointer operator->()
Returns a pointer to the current element.
Definition ScrollingBuffer.hpp:156
T value_type
T.
Definition ScrollingBuffer.hpp:143
std::ptrdiff_t difference_type
Signed integer type (usually std::ptrdiff_t)
Definition ScrollingBuffer.hpp:142
Reverse Iterator.
Definition ScrollingBuffer.hpp:269
std::forward_iterator_tag iterator_category
To categorize the iteration direction.
Definition ScrollingBuffer.hpp:271
friend bool operator!=(const ReverseIterator &lhs, const ReverseIterator &rhs)
Inequality comparison operator.
Definition ScrollingBuffer.hpp:312
T & reference
value_type&
Definition ScrollingBuffer.hpp:275
ReverseIterator operator++(int)
Advances the iterator.
Definition ScrollingBuffer.hpp:296
ReverseIterator(ScrollingBuffer &buffer, int64_t index=0)
Constructor.
Definition ScrollingBuffer.hpp:280
friend bool operator==(const ReverseIterator &lhs, const ReverseIterator &rhs)
Equality comparison operator.
Definition ScrollingBuffer.hpp:307
T value_type
T.
Definition ScrollingBuffer.hpp:273
reference operator*() const
Returns a reference to the current element.
Definition ScrollingBuffer.hpp:284
std::ptrdiff_t difference_type
Signed integer type (usually std::ptrdiff_t)
Definition ScrollingBuffer.hpp:272
pointer operator->()
Returns a pointer to the current element.
Definition ScrollingBuffer.hpp:286
T * pointer
value_type*
Definition ScrollingBuffer.hpp:274
ReverseIterator & operator++()
Advances the iterator.
Definition ScrollingBuffer.hpp:289
A buffer which is overwriting itself from the start when full.
Definition ScrollingBuffer.hpp:29
T * data()
Returns a pointer to the raw data array (not in scrolled order)
Definition ScrollingBuffer.hpp:740
bool isInfiniteBuffer() const
Returns whether the buffer is infinite and growing.
Definition ScrollingBuffer.hpp:746
T & at(size_t pos)
Returns a reference to the element at specified location pos, with bounds checking....
Definition ScrollingBuffer.hpp:65
ConstIterator end() const
Returns an iterator to the element following the last element of the vector.
Definition ScrollingBuffer.hpp:257
const T * data() const
Returns a pointer to the raw data array (not in scrolled order)
Definition ScrollingBuffer.hpp:734
bool empty() const
Checks if the container has no elements.
Definition ScrollingBuffer.hpp:408
void reserve(size_t new_cap)
Increase the capacity of the vector to a value that's greater or equal to new_cap.
Definition ScrollingBuffer.hpp:437
ConstReverseIterator crbegin() const
Returns a reverse iterator to the first element of the reversed vector.
Definition ScrollingBuffer.hpp:396
ConstReverseIterator rbegin() const
Returns a reverse iterator to the first element of the reversed vector.
Definition ScrollingBuffer.hpp:386
Iterator end()
Returns an iterator to the element following the last element of the vector.
Definition ScrollingBuffer.hpp:196
int offset() const
Returns the data index of the first element in the buffer.
Definition ScrollingBuffer.hpp:728
ReverseIterator rbegin()
Returns a reverse iterator to the first element of the reversed vector.
Definition ScrollingBuffer.hpp:323
void push_back(const T &value)
Appends the given element value to the end of the container.
Definition ScrollingBuffer.hpp:467
const T & front() const
Returns a reference to the first element in the container. Calling front on an empty container is und...
Definition ScrollingBuffer.hpp:107
const T & back() const
Returns a reference to the last element in the container. Calling back on an empty container causes u...
Definition ScrollingBuffer.hpp:123
bool full() const
Checks if the container is full (never full when infinite buffer)
Definition ScrollingBuffer.hpp:414
ConstIterator cend() const
Returns an iterator to the element following the last element of the vector.
Definition ScrollingBuffer.hpp:265
ConstReverseIterator rend() const
Returns a reverse iterator to the element following the last element of the reversed vector.
Definition ScrollingBuffer.hpp:391
ScrollingBuffer(size_t maxSize=0)
Reserves space for the buffer but does not fill the buffer with values.
Definition ScrollingBuffer.hpp:37
size_t size() const
Returns the number of elements in the container.
Definition ScrollingBuffer.hpp:420
ReverseIterator rend()
Returns a reverse iterator to the element following the last element of the reversed vector.
Definition ScrollingBuffer.hpp:328
size_t capacity() const
Returns the number of elements that can be held in currently allocated storage.
Definition ScrollingBuffer.hpp:443
friend std::ostream & operator<<(std::ostream &os, const ScrollingBuffer< T, _Padding > &buffer)
Prints the buffer to the output stream.
Definition ScrollingBuffer.hpp:812
ConstReverseIterator crend() const
Returns a reverse iterator to the element following the last element of the reversed vector.
Definition ScrollingBuffer.hpp:401
const T & at(size_t pos) const
Returns a reference to the element at specified location pos, with bounds checking....
Definition ScrollingBuffer.hpp:75
T min() const
Returns the smallest value in the buffer.
Definition ScrollingBuffer.hpp:714
void pop_front()
Removes the first element of the container.
Definition ScrollingBuffer.hpp:493
std::string getRawString() const
Converts the raw buffer to a string.
Definition ScrollingBuffer.hpp:752
ScrollingBuffer(std::initializer_list< T > init)
Constructs a new container with the contents of the initializer list init.
Definition ScrollingBuffer.hpp:46
void clear()
Erases all elements from the container. After this call, size() returns zero.
Definition ScrollingBuffer.hpp:453
T & back()
Returns a reference to the last element in the container. Calling back on an empty container causes u...
Definition ScrollingBuffer.hpp:115
void resize(size_t targetSize)
Resizes the buffer to the specified size.
Definition ScrollingBuffer.hpp:522
ConstIterator cbegin() const
Returns an iterator to the first element of the vector.
Definition ScrollingBuffer.hpp:261
ConstIterator begin() const
Returns an iterator to the first element of the vector.
Definition ScrollingBuffer.hpp:253
T max() const
Returns the largest value in the buffer.
Definition ScrollingBuffer.hpp:700
Iterator begin()
Returns an iterator to the first element of the vector.
Definition ScrollingBuffer.hpp:192
T & front()
Returns a reference to the first element in the container. Calling front on an empty container is und...
Definition ScrollingBuffer.hpp:98