19#include <fmt/ostream.h>
20#include <fmt/ranges.h>
28template<
class T,
size_t _Padding = 0>
41 _data.reserve(maxSize + _Padding);
42 _data.resize(_Padding);
50 _data.reserve(init.size());
52 for (
auto& val : init)
69 return const_cast<T&
>(
static_cast<const ScrollingBuffer&
>(*this).at(pos));
76 [[nodiscard]]
const T&
at(
size_t pos)
const
80 throw std::out_of_range(
"ScrollingBuffer::at: pos (which is "
81 + std::to_string(pos) +
") >= this->size() (which is " + std::to_string(
size()) +
")");
76 [[nodiscard]]
const T&
at(
size_t pos)
const {
…}
102 return const_cast<T&
>(
static_cast<const ScrollingBuffer&
>(*this).front());
108 [[nodiscard]]
const T&
front()
const
118 return const_cast<T&
>(
static_cast<const ScrollingBuffer&
>(*this).back());
124 [[nodiscard]]
const T&
back()
const
124 [[nodiscard]]
const T&
back()
const {
…}
292 if (
index < 0) {
return *
this; }
355 if (
index < 0) {
return *
this; }
415 [[nodiscard]]
bool full()
const
421 [[nodiscard]]
size_t size()
const
425 return _data.size() - _Padding;
421 [[nodiscard]]
size_t size()
const {
…}
440 _data.reserve(new_cap);
460 for (
size_t i = 0; i < _Padding; i++)
472 _data.push_back(value);
477 _data.push_back(value);
561 std::vector<T> to_vector;
566 std::back_inserter(to_vector));
570 std::copy(std::next(
_data.begin(), std::max(
static_cast<int>(
_dataStart - _Padding), 0)),
572 std::back_inserter(to_vector));
574 if (int64_t elementsFront = std::min(
static_cast<int64_t
>(
_dataEnd),
static_cast<int64_t
>(
_dataStart - _Padding));
577 std::copy(
_data.begin(), std::next(
_data.begin(), elementsFront),
578 std::back_inserter(to_vector));
580 _data.swap(to_vector);
592 if (
_maxSize - _Padding > targetSize)
596 size_t elementsToDelete =
_maxSize - _Padding - targetSize;
599 size_t emptyAtTheBackToDelete = std::min(emptyAtTheBack, elementsToDelete))
605 elementsToDelete -= emptyAtTheBackToDelete;
611 if (elementsToDelete)
614 std::next(
_data.begin(),
static_cast<int64_t
>(
_dataStart + elementsToDelete)));
629 size_t elementsToDelete =
_maxSize - _Padding - targetSize;
631 if (
size_t emptyInBetween =
static_cast<size_t>(std::max(
static_cast<int>(
_dataStart - _Padding -
_dataEnd), 0));
632 size_t emptyInBetweenToDelete = std::min(emptyInBetween, elementsToDelete))
636 std::next(
_data.begin(),
static_cast<int64_t
>(
_dataEnd + emptyInBetweenToDelete)));
640 elementsToDelete -= emptyInBetweenToDelete;
646 if (
size_t paddingAtTheEnd =
static_cast<size_t>(std::max(
static_cast<int>(_Padding -
_dataStart), 0));
647 size_t paddingAtTheEndToDelete = std::min(paddingAtTheEnd, elementsToDelete))
650 std::next(
_data.begin(),
static_cast<int64_t
>(
_dataEnd + paddingAtTheEndToDelete)));
651 _maxSize -= paddingAtTheEndToDelete;
654 elementsToDelete -= paddingAtTheEndToDelete;
661 size_t elementsAtTheBackToDelete = std::min(elementsAtTheBack, elementsToDelete))
665 std::next(
_data.begin(),
static_cast<int64_t
>(
_dataStart - _Padding + elementsAtTheBackToDelete)));
668 _maxSize -= elementsAtTheBackToDelete;
675 elementsToDelete -= elementsAtTheBackToDelete;
677 if (elementsToDelete)
691 else if (
_maxSize - _Padding < targetSize)
714 _data.resize(targetSize + _Padding);
716 auto copy_backward = [](
auto first,
auto last,
auto d_last) {
717 while (first != last)
719 *(--d_last) = *(--last);
723 copy_backward(std::next(
_data.begin(),
static_cast<int64_t
>(
_dataEnd)),
725 std::next(
_data.begin(),
static_cast<int64_t
>(targetSize + _Padding)));
727 auto diff = targetSize + _Padding -
_maxSize;
744 [[nodiscard]] T
max()
const
746 T currentMax =
front();
747 for (
size_t i = 0; i <
_data.size(); i++)
751 currentMax = std::max(currentMax,
_data.at(i));
744 [[nodiscard]] T
max()
const {
…}
758 [[nodiscard]] T
min()
const
760 T currentMin =
front();
761 for (
size_t i = 0; i <
_data.size(); i++)
765 currentMin = std::min(currentMin,
_data.at(i));
758 [[nodiscard]] T
min()
const {
…}
778 [[nodiscard]]
const T*
data()
const
778 [[nodiscard]]
const T*
data()
const {
…}
826 for (
int i = 0;
static_cast<size_t>(i) <
_maxSize; i++)
834 static_cast<size_t>(i) >=
_data.size()
835 || (scrolled &&
static_cast<size_t>(i) >=
_dataEnd && (
static_cast<int>(
_dataStart - _Padding) < 0 || i <
static_cast<int>(
_dataStart - _Padding)))
837 || (
_data.size() > 1 && !scrolled &&
static_cast<size_t>(i) >=
_dataEnd))
843 out += std::to_string(
_data.at(
static_cast<size_t>(i)));
845 if (
static_cast<size_t>(i) !=
_maxSize - 1)
859 os << fmt::format(
"{}", fmt::join(buffer,
", "));
879 if (
_data.size() == 1) {
return false; }
905#ifndef DOXYGEN_IGNORE
907template<
class T,
size_t _Padding>
908struct fmt::formatter<
NAV::ScrollingBuffer<T, _Padding>> : ostream_formatter