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()) + 
")");
 
 
  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 
 
  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;
 
 
  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));
 
 
  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));
 
 
  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