General Utility Library for C++14  2.11
SlidingBuffer.h
Go to the documentation of this file.
1 
23 #ifndef GUL14_SLIDINGBUFFER_H_
24 #define GUL14_SLIDINGBUFFER_H_
25 
26 #include <algorithm>
27 #include <array>
28 #include <ostream>
29 #include <vector>
30 
31 #include "gul14/cat.h"
32 #include "gul14/internal.h"
33 
34 namespace gul14 {
35 
66 enum class ShrinkBehavior { keep_front_elements, keep_back_elements };
67 
176 template<typename ElementT, std::size_t fixed_capacity = 0u,
177  typename Container = typename std::conditional_t<(fixed_capacity >= 1u),
178  std::array<ElementT, fixed_capacity>,
179  std::vector<ElementT>>
180  >
182 public:
183  template <typename>
184  class SlidingBufferIterator;
186  using container_type = Container;
188  using value_type = ElementT;
190  using size_type = typename Container::size_type;
192  using difference_type = typename Container::difference_type;
194  using reference = typename Container::reference;
196  using const_reference = typename Container::const_reference;
198  using pointer = typename Container::pointer;
200  using const_pointer = typename Container::const_pointer;
206  using reverse_iterator = std::reverse_iterator<iterator>;
208  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
209 
222  SlidingBuffer() = default;
224  SlidingBuffer(SlidingBuffer const&) = default;
226  SlidingBuffer(SlidingBuffer&&) noexcept(std::is_nothrow_move_constructible<container_type>::value) = default;
228  SlidingBuffer& operator=(SlidingBuffer const&) = default;
230  SlidingBuffer& operator=(SlidingBuffer &&) noexcept(std::is_nothrow_move_assignable<container_type>::value) = default;
232  virtual ~SlidingBuffer() = default;
233 
244  SlidingBuffer(size_type count) : storage_(count) {}
245 
246 protected:
247 
250  size_type idx_begin_{ 0u };
253  size_type idx_end_{ 0u };
255  bool full_{ false };
257  Container storage_{ };
258 
259 public:
270  auto pop_back() -> void
271  {
272  decrease_idx(idx_end_);
273  full_ = false;
274  }
275 
287  auto pop_front() -> void
288  {
289  increase_idx(idx_begin_);
290  full_ = false;
291  }
292 
306  auto push_back(const value_type& in) -> void
307  {
308  storage_[idx_end_] = in;
309 
310  increase_idx(idx_end_);
311  if (full_)
312  increase_idx(idx_begin_);
313  else if (idx_end_ == idx_begin_)
314  full_ = true;
315  }
316 
320  auto push_back(value_type&& in) -> void
321  {
322  storage_[idx_end_] = std::move(in);
323 
324  increase_idx(idx_end_);
325  if (full_)
326  increase_idx(idx_begin_);
327  else if (idx_end_ == idx_begin_)
328  full_ = true;
329  }
330 
344  auto push_front(const value_type& in) -> void
345  {
346  decrease_idx(idx_begin_);
347 
348  if (full_)
349  decrease_idx(idx_end_);
350  else if (idx_end_ == idx_begin_)
351  full_ = true;
352 
353  storage_[idx_begin_] = in;
354  }
355 
359  auto push_front(value_type&& in) -> void
360  {
361  decrease_idx(idx_begin_);
362 
363  if (full_)
364  decrease_idx(idx_end_);
365  else if (idx_end_ == idx_begin_)
366  full_ = true;
367 
368  storage_[idx_begin_] = std::move(in);
369  }
370 
381  auto operator[](size_type idx) noexcept -> reference
382  {
383  idx += idx_begin_;
384 
385  return (idx >= capacity()) ? storage_[idx - capacity()] : storage_[idx];
386  }
387 
391  auto operator[](size_type idx) const noexcept -> const_reference
392  {
393  idx += idx_begin_;
394 
395  return (idx >= capacity()) ? storage_[idx - capacity()] : storage_[idx];
396  }
397 
409  auto at(const size_type idx) noexcept(false) -> reference
410  {
411  auto const s = size();
412  if (idx >= s) {
413  throw std::out_of_range(gul14::cat("SlidingBuffer::", __func__,
414  ": idx (which is ", idx, ") >= this->size() (which is ", s, ")"));
415  }
416  return operator[](idx);
417  }
418 
422  auto at(const size_type idx) const noexcept(false) -> const_reference
423  {
424  auto const s = size();
425  if (idx >= s) {
426  throw std::out_of_range(gul14::cat("SlidingBuffer::", __func__,
427  ": idx (which is ", idx, ") >= this->size() (which is ", s, ")"));
428  }
429  return operator[](idx);
430  }
431 
438  auto front() noexcept -> reference
439  {
440  return storage_[idx_begin_];
441  }
442 
446  auto front() const noexcept -> const_reference
447  {
448  return storage_[idx_begin_];
449  }
450 
457  auto back() noexcept -> reference
458  {
459  if (idx_end_ == 0)
460  return storage_[capacity() - 1];
461  else
462  return storage_[idx_end_ - 1];
463  }
464 
468  auto back() const noexcept -> const_reference
469  {
470  if (idx_end_ == 0)
471  return storage_[capacity() - 1];
472  else
473  return storage_[idx_end_ - 1];
474  }
475 
483  auto size() const noexcept -> size_type
484  {
485  if (full_)
486  return capacity();
487 
488  if (idx_end_ >= idx_begin_)
489  return idx_end_ - idx_begin_;
490  else
491  return idx_end_ + capacity() - idx_begin_;
492  }
493 
501  auto constexpr capacity() const noexcept -> size_type
502  {
503  return (fixed_capacity > 0) ? fixed_capacity : storage_.size();
504  }
505 
514  auto filled() const noexcept -> bool
515  {
516  return full_;
517  }
518 
526  auto clear() -> void
527  {
528  full_ = false;
529  idx_begin_ = 0u;
530  idx_end_ = 0u;
531 
532  // Fill with new empty elements to possibly trigger RAII in the elements
533  std::fill(storage_.begin(), storage_.end(), value_type{});
534  }
535 
555  auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
556  {
557  static_assert(fixed_capacity == 0u,
558  "resize() only possible if the underlying container is resizable");
559  change_capacity(new_capacity, shrink_behavior);
560  }
561 
566  auto reserve(size_type size, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
567  {
568  static_assert(fixed_capacity == 0u,
569  "reserve() only possible if the underlying container is resizable");
570  change_capacity(size, shrink_behavior);
571  }
572 
578  auto empty() const noexcept -> bool
579  {
580  return (not full_) and (idx_begin_ == idx_end_);
581  }
582 
590  auto friend operator<< (std::ostream& s,
591  const SlidingBuffer<value_type, fixed_capacity, container_type>& buffer) -> std::ostream&
592  {
593  auto const size = buffer.size();
594  // We can not use range-for here, because of SlidingBufferExposed<>'s un-wrapped iterators
595  for (auto i = size_type{ 0 }; i < size; ++i)
596  s << buffer[i] << " ";
597  return s << '\n';
598  }
599 
640  template <typename BufferPointer>
642  {
643  protected:
645  size_type position_{ 0 };
646  private:
648  BufferPointer buffer_;
649 
650  public:
651  // Set of 5 member types that are needed by std::iterator_traits:
652 
654  using iterator_category = std::random_access_iterator_tag;
656  using value_type = ElementT;
658  using difference_type = std::ptrdiff_t;
660  using pointer = value_type*;
663 
670  explicit SlidingBufferIterator(BufferPointer buff, size_type num = 0) noexcept
671  : position_{ num }
672  , buffer_{ buff }
673  {
674  }
675 
677  auto operator++() noexcept -> SlidingBufferIterator&
678  {
679  ++position_;
680  return *this;
681  }
682 
684  auto operator++(int) noexcept -> SlidingBufferIterator
685  {
686  auto previous = *this;
687  ++(*this);
688  return previous;
689  }
690 
693  {
694  position_ += d;
695  return *this;
696  }
697 
699  friend auto
702  {
703  return SlidingBufferIterator{ it.buffer_, it.position_ + d };
704  }
705 
707  friend auto
710  {
711  return SlidingBufferIterator{ it.buffer_, it.position_ + d };
712  }
713 
715  auto operator--() noexcept -> SlidingBufferIterator&
716  {
717  --position_;
718  return *this;
719  }
720 
722  auto operator--(int) noexcept -> SlidingBufferIterator
723  {
724  auto previous = *this;
725  --(*this);
726  return previous;
727  }
728 
731  {
732  position_ -= d;
733  return *this;
734  }
735 
737  friend auto
740  {
741  return SlidingBufferIterator{ it.buffer_, it.position_ - d };
742  }
743 
745  friend auto
746  operator-(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
747  -> difference_type
748  {
749  return lhs.position_ - rhs.position_;
750  }
751 
753  auto operator*() const noexcept -> typename std::conditional_t<
754  std::is_const<std::remove_pointer_t<BufferPointer>>::value,
756  {
757  return (*buffer_)[position_];
758  }
759 
761  auto operator->() const noexcept -> typename std::conditional_t<
762  std::is_const<std::remove_pointer_t<BufferPointer>>::value,
764  {
765  return &(*buffer_)[position_];
766  }
767 
769  auto operator[](difference_type offs) noexcept -> typename std::conditional_t<
770  std::is_const<std::remove_pointer_t<BufferPointer>>::value,
772  {
773  return *(*this + offs);
774  }
775 
781  friend auto
782  operator==(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
783  -> bool
784  {
785  return lhs.position_ == rhs.position_;
786  }
787 
793  friend auto
794  operator!=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
795  -> bool
796  {
797  return not(lhs == rhs);
798  }
799 
803  friend auto
804  operator>(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
805  -> bool
806  {
807  return lhs.position_ > rhs.position_;
808  }
809 
811  friend auto
812  operator<(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
813  -> bool
814  {
815  return lhs.position_ < rhs.position_;
816  }
817 
822  friend auto
823  operator>=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
824  -> bool
825  {
826  return lhs.position_ >= rhs.position_;
827  }
828 
833  friend auto
834  operator<=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
835  -> bool
836  {
837  return lhs.position_ <= rhs.position_;
838  }
839  };
840 
846  auto begin() noexcept -> iterator
847  {
848  return iterator{ this, 0 };
849  }
850 
852  auto begin() const noexcept -> const_iterator
853  {
854  return const_iterator{ this, 0 };
855  }
856 
862  auto rbegin() noexcept -> reverse_iterator
863  {
864  return std::make_reverse_iterator(end());
865  }
866 
873  auto end() noexcept -> iterator
874  {
875  return iterator{ this, size() };
876  }
877 
879  auto end() const noexcept -> const_iterator
880  {
881  return const_iterator{ this, size() };
882  }
883 
891  auto rend() noexcept -> reverse_iterator
892  {
893  return std::make_reverse_iterator(begin());
894  }
895 
901  auto cbegin() const noexcept -> const_iterator
902  {
903  return const_iterator{ this, 0 };
904  }
905 
911  auto crbegin() const noexcept -> const_reverse_iterator
912  {
913  return std::make_reverse_iterator(cend());
914  }
915 
923  auto cend() const noexcept -> const_iterator
924  {
925  return const_iterator{ this, size() };
926  }
927 
935  auto crend() const noexcept -> const_reverse_iterator
936  {
937  return std::make_reverse_iterator(cbegin());
938  }
939 
940 private:
941  void decrease_idx(size_t &idx) noexcept
942  {
943  if (idx == 0)
944  idx = capacity() - 1;
945  else
946  --idx;
947  }
948 
949  void increase_idx(size_t &idx) noexcept
950  {
951  ++idx;
952 
953  if (idx >= capacity())
954  idx = 0;
955  }
956 
957 protected:
972  auto change_capacity(size_type new_capacity, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
973  {
974  auto const old_capacity = capacity();
975  auto const old_size = size();
976 
978  // No change
979  if (new_capacity == old_capacity)
980  return;
981 
983  // Vanishing
984  if (new_capacity == 0) {
985  storage_.resize(0);
986  idx_begin_ = 0;
987  idx_end_ = 0;
988  full_ = false;
989  return;
990  }
991 
992 
994  // Growing
995  if (new_capacity > old_capacity) {
996  // Make SlidingBuffer indices equal to those of the underlying container
997  std::rotate(storage_.begin(), storage_.begin() + idx_begin_, storage_.end());
998  storage_.resize(new_capacity);
999  idx_begin_ = 0;
1000  idx_end_ = old_size;
1001  full_ = false;
1002  return;
1003  }
1004 
1006  // Shrinking
1007  if (old_size < new_capacity) {
1008  // All data fits into new capacity, just move it there
1009  std::rotate(storage_.begin(), storage_.begin() + idx_begin_, storage_.end());
1010  storage_.resize(new_capacity);
1011  idx_begin_ = 0;
1012  idx_end_ = old_size;
1013  full_ = false;
1014  }
1015  else {
1016  auto new_front = idx_begin_;
1017  if (shrink_behavior == ShrinkBehavior::keep_back_elements)
1018  new_front = (idx_end_ + old_capacity - new_capacity) % old_capacity;
1019 
1020  std::rotate(storage_.begin(), storage_.begin() + new_front, storage_.end());
1021  storage_.resize(new_capacity);
1022  full_ = true;
1023  idx_begin_ = 0;
1024  idx_end_ = 0;
1025  }
1026  }
1027 };
1028 
1072 template<typename ElementT, std::size_t fixed_capacity = 0u,
1073  typename Container = typename std::conditional_t<(fixed_capacity >= 1u),
1074  std::array<ElementT, fixed_capacity>,
1075  std::vector<ElementT>>
1076  >
1078 public:
1080  using iterator = typename Container::iterator;
1082  using const_iterator = typename Container::const_iterator;
1084  using reverse_iterator = typename Container::reverse_iterator;
1086  using const_reverse_iterator = typename Container::const_reverse_iterator;
1087 
1088  // Inherit member types
1097 
1098  // Inherit constructors
1100 
1101  // Inherit members for access without "this->"
1107 
1121  auto begin() noexcept -> iterator
1122  {
1123  if (not full_ and (idx_end_ == 0 or idx_end_ >= idx_begin_))
1124  return storage_.begin() + idx_begin_;
1125 
1126  return storage_.begin();
1127  }
1128 
1130  auto begin() const noexcept -> const_iterator
1131  {
1132  return cbegin();
1133  }
1134 
1141  auto cbegin() const noexcept -> const_iterator
1142  {
1143  if (not full_ and (idx_end_ == 0 or idx_end_ >= idx_begin_))
1144  return storage_.cbegin() + idx_begin_;
1145 
1146  return storage_.cbegin();
1147  }
1148 
1166  auto end() noexcept -> iterator
1167  {
1168  if (full_ or idx_begin_ != 0)
1169  return storage_.end();
1170 
1171  return storage_.begin() + idx_end_;
1172  }
1173 
1175  auto end() const noexcept -> const_iterator
1176  {
1177  return cend();
1178  }
1179 
1186  auto cend() const noexcept -> const_iterator
1187  {
1188  if (full_ or idx_begin_ != 0)
1189  return storage_.cend();
1190 
1191  return storage_.cbegin() + idx_end_;
1192  }
1193 
1202  auto rbegin() noexcept -> reverse_iterator
1203  {
1204  return std::make_reverse_iterator(end());
1205  }
1206 
1215  auto crbegin() const noexcept -> const_reverse_iterator
1216  {
1217  return std::make_reverse_iterator(cend());
1218  }
1219 
1225  auto rend() noexcept -> reverse_iterator
1226  {
1227  return std::make_reverse_iterator(begin());
1228  }
1229 
1236  auto crend() const noexcept -> const_reverse_iterator
1237  {
1238  return std::make_reverse_iterator(cbegin());
1239  }
1240 
1260  auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
1261  {
1262  static_assert(fixed_capacity == 0u,
1263  "resize() only possible if the underlying container is resizable");
1264 
1265  // We handle just one special case here: A pure right aligned un-full buffer
1266  //
1267  // I.e. only push_front() (not push_back()) has been used until now, and
1268  // the buffer is not yet filled completely. Then the data will only occupy
1269  // the 'right hand side' of the underlying container.
1270  //
1271  // In order to fulfill begin()'s and end()'s guarantee to include only
1272  // filled elements we need to right-align the data in the new container.
1273 
1274  auto const old_capacity = capacity();
1275 
1276  auto const right_align =
1277  (shrink_behavior == ShrinkBehavior::keep_front_elements)
1278  and (new_capacity > 0)
1279  and (new_capacity != old_capacity)
1280  and (not full_)
1281  and (idx_end_ == 0)
1282  and (idx_begin_ != 0);
1283 
1284  if (not right_align)
1285  return this->change_capacity(new_capacity, shrink_behavior);
1286 
1288  // Growing
1289  if (new_capacity > old_capacity) {
1290  storage_.resize(new_capacity);
1291  std::move_backward(storage_.begin() + idx_begin_,
1292  storage_.begin() + old_capacity, storage_.end());
1293  idx_begin_ += new_capacity - old_capacity;
1294  return;
1295  }
1296 
1298  // Shrinking
1299  full_ = (this->size() >= new_capacity);
1300  auto const required_shift = std::min(old_capacity - new_capacity, idx_begin_);
1301  std::rotate(storage_.begin(), storage_.begin() + required_shift, storage_.end());
1302  idx_begin_ -= required_shift;
1303  storage_.resize(new_capacity);
1304  }
1305 
1310  auto reserve(size_type size, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
1311  {
1312  static_assert(fixed_capacity == 0u,
1313  "reserve() only possible if the underlying container is resizable");
1314  resize(size, shrink_behavior);
1315  }
1316 };
1317 
1319 
1320 } // namespace gul14
1321 
1322 #endif
1323 
1324 // vi:ts=4:sw=4:sts=4:et
Declaration of the overload set for cat() and of the associated class ConvertingStringView.
A variant of SlidingBuffer that exposes the underlying container through its iterator interface.
Definition: SlidingBuffer.h:1077
typename Container::reverse_iterator reverse_iterator
Iterator to an element in reversed container.
Definition: SlidingBuffer.h:1084
auto end() const noexcept -> const_iterator
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:1175
auto begin() noexcept -> iterator
Return an iterator to the first occupied element of the underlying container.
Definition: SlidingBuffer.h:1121
auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container.
Definition: SlidingBuffer.h:1260
auto cend() const noexcept -> const_iterator
Return a constant iterator to the element following the last element in the used space of the underly...
Definition: SlidingBuffer.h:1186
auto reserve(size_type size, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container (identical to resize()).
Definition: SlidingBuffer.h:1310
typename Container::const_iterator const_iterator
Iterator to a const element.
Definition: SlidingBuffer.h:1082
auto begin() const noexcept -> const_iterator
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:1130
auto cbegin() const noexcept -> const_iterator
Return a constant iterator to the first occupied element of the underlying container.
Definition: SlidingBuffer.h:1141
auto rbegin() noexcept -> reverse_iterator
Return a reverse iterator to the first used element of the reversed underlying container.
Definition: SlidingBuffer.h:1202
auto end() noexcept -> iterator
Return an iterator to the element following the last element in the used space of the underlying cont...
Definition: SlidingBuffer.h:1166
auto crend() const noexcept -> const_reverse_iterator
Return a constant iterator to the last element of the reversed underlying container.
Definition: SlidingBuffer.h:1236
auto rend() noexcept -> reverse_iterator
Return an iterator to the last element of the reversed underlying container.
Definition: SlidingBuffer.h:1225
typename Container::iterator iterator
Iterator to an element.
Definition: SlidingBuffer.h:1080
auto crbegin() const noexcept -> const_reverse_iterator
Return a constant reverse iterator to the first used element of the reversed underlying container.
Definition: SlidingBuffer.h:1215
typename Container::const_reverse_iterator const_reverse_iterator
Iterator to a const element in reversed container.
Definition: SlidingBuffer.h:1086
Iterator of the SlidingBuffer container.
Definition: SlidingBuffer.h:642
ElementT value_type
The type "pointed to" by the iterator.
Definition: SlidingBuffer.h:656
friend auto operator+(difference_type d, const SlidingBufferIterator &it) noexcept -> SlidingBufferIterator
Add an integer and an iterator.
Definition: SlidingBuffer.h:708
friend auto operator+(const SlidingBufferIterator &it, difference_type d) noexcept -> SlidingBufferIterator
Add an integer to an iterator.
Definition: SlidingBuffer.h:700
auto operator->() const noexcept -> typename std::conditional_t< std::is_const< std::remove_pointer_t< BufferPointer >>::value, const_pointer, pointer >
Access member of element pointed to by the iterator.
Definition: SlidingBuffer.h:761
auto operator++(int) noexcept -> SlidingBufferIterator
Post-increment iterator by one position.
Definition: SlidingBuffer.h:684
friend auto operator>=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> bool
Determine if the left iterator refers to position that is greater than or equal to than the right one...
Definition: SlidingBuffer.h:823
auto operator++() noexcept -> SlidingBufferIterator &
Pre-increment iterator by one position.
Definition: SlidingBuffer.h:677
auto operator--(int) noexcept -> SlidingBufferIterator
Post-decrement iterator by one position.
Definition: SlidingBuffer.h:722
std::ptrdiff_t difference_type
Distance between iterators is represented as this type.
Definition: SlidingBuffer.h:658
value_type & reference
This type represents a reference-to-value_type.
Definition: SlidingBuffer.h:662
friend auto operator>(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> bool
Determine if the left iterator refers to a greater position than the right one.
Definition: SlidingBuffer.h:804
auto operator+=(difference_type d) noexcept -> SlidingBufferIterator &
Increase iterator by a given number of positions.
Definition: SlidingBuffer.h:692
std::random_access_iterator_tag iterator_category
Defines the category of the iterator.
Definition: SlidingBuffer.h:654
auto operator[](difference_type offs) noexcept -> typename std::conditional_t< std::is_const< std::remove_pointer_t< BufferPointer >>::value, const_reference, reference >
Dereference the iterator at a certain index offset.
Definition: SlidingBuffer.h:769
auto operator--() noexcept -> SlidingBufferIterator &
Pre-decrement iterator by one position.
Definition: SlidingBuffer.h:715
friend auto operator-(const SlidingBufferIterator &it, difference_type d) noexcept -> SlidingBufferIterator
Subtract an integer from an iterator.
Definition: SlidingBuffer.h:738
SlidingBufferIterator(BufferPointer buff, size_type num=0) noexcept
Create an iterator pointing into a SlidingBuffer.
Definition: SlidingBuffer.h:670
value_type * pointer
This type represents a pointer-to-value_type.
Definition: SlidingBuffer.h:660
friend auto operator-(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> difference_type
Subtract two iterators.
Definition: SlidingBuffer.h:746
friend auto operator==(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> bool
Compare two iterators for equality.
Definition: SlidingBuffer.h:782
auto operator*() const noexcept -> typename std::conditional_t< std::is_const< std::remove_pointer_t< BufferPointer >>::value, const_reference, reference >
Access element pointed to by the iterator.
Definition: SlidingBuffer.h:753
auto operator-=(difference_type d) noexcept -> SlidingBufferIterator &
Decrease iterator by a given number of positions.
Definition: SlidingBuffer.h:730
friend auto operator!=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> bool
Compare two iterators for inequality.
Definition: SlidingBuffer.h:794
A circular data buffer of (semi-)fixed capacity to which elements can be added at the front or at the...
Definition: SlidingBuffer.h:181
auto push_front(const value_type &in) -> void
Insert one element at the front of the buffer; if it is full, an element at the back is dropped to ma...
Definition: SlidingBuffer.h:344
typename Container::size_type size_type
Unsigned integer type (usually std::size_t)
Definition: SlidingBuffer.h:190
auto filled() const noexcept -> bool
Return true if the buffer is completely filled with elements.
Definition: SlidingBuffer.h:514
auto cbegin() const noexcept -> const_iterator
Return a read-only iterator to the first element of the container.
Definition: SlidingBuffer.h:901
auto size() const noexcept -> size_type
Return the number of elements in the container, i.e.
Definition: SlidingBuffer.h:483
auto operator[](size_type idx) const noexcept -> const_reference
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:391
std::reverse_iterator< const_iterator > const_reverse_iterator
Iterator to a const element in reversed container.
Definition: SlidingBuffer.h:208
auto change_capacity(size_type new_capacity, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Change the underlying container's capacity.
Definition: SlidingBuffer.h:972
auto cend() const noexcept -> const_iterator
Return a read-only iterator to the element following the last element of the container.
Definition: SlidingBuffer.h:923
SlidingBuffer(SlidingBuffer &&) noexcept(std::is_nothrow_move_constructible< container_type >::value)=default
Default move constructor.
SlidingBuffer(SlidingBuffer const &)=default
Default copy constructor.
auto at(const size_type idx) noexcept(false) -> reference
Access an element in the buffer by index with bounds checking.
Definition: SlidingBuffer.h:409
auto pop_front() -> void
Remove the first element from the buffer.
Definition: SlidingBuffer.h:287
auto reserve(size_type size, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container (identical to resize()).
Definition: SlidingBuffer.h:566
auto crend() const noexcept -> const_reverse_iterator
Return a read-only iterator to the element following the last element of the reversed container.
Definition: SlidingBuffer.h:935
Container container_type
Type of the underlying container (e.g. std::array<value_type, ..>)
Definition: SlidingBuffer.h:186
auto push_back(value_type &&in) -> void
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:320
typename Container::const_reference const_reference
Reference to a constant element.
Definition: SlidingBuffer.h:196
auto end() noexcept -> iterator
Return an iterator to the element following the last element of the container.
Definition: SlidingBuffer.h:873
auto rbegin() noexcept -> reverse_iterator
Return an iterator to the first element of the reversed container.
Definition: SlidingBuffer.h:862
typename Container::const_pointer const_pointer
Pointer to a constant element.
Definition: SlidingBuffer.h:200
SlidingBuffer()=default
Construct an empty sliding buffer.
typename Container::difference_type difference_type
Signed integer type (usually std::ptrdiff_t)
Definition: SlidingBuffer.h:192
auto operator[](size_type idx) noexcept -> reference
Access an element in the buffer by index without bounds checking.
Definition: SlidingBuffer.h:381
std::reverse_iterator< iterator > reverse_iterator
Iterator to an element in reversed container.
Definition: SlidingBuffer.h:206
auto front() noexcept -> reference
Return the foremost element (the one with index 0).
Definition: SlidingBuffer.h:438
auto empty() const noexcept -> bool
Check if the buffer contains no elements, i.e.
Definition: SlidingBuffer.h:578
auto front() const noexcept -> const_reference
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:446
ElementT value_type
Type of the elements in the underlying container.
Definition: SlidingBuffer.h:188
auto clear() -> void
Empty the buffer.
Definition: SlidingBuffer.h:526
auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container.
Definition: SlidingBuffer.h:555
auto begin() const noexcept -> const_iterator
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:852
auto rend() noexcept -> reverse_iterator
Return an iterator to the element following the last element of the reversed container.
Definition: SlidingBuffer.h:891
constexpr auto capacity() const noexcept -> size_type
Return the maximum possible number of elements in the container.
Definition: SlidingBuffer.h:501
auto push_front(value_type &&in) -> void
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:359
typename Container::reference reference
Reference to an element.
Definition: SlidingBuffer.h:194
auto at(const size_type idx) const noexcept(false) -> const_reference
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:422
auto pop_back() -> void
Remove the last element from the buffer.
Definition: SlidingBuffer.h:270
auto crbegin() const noexcept -> const_reverse_iterator
Return a read-only iterator to the first element of the reversed container.
Definition: SlidingBuffer.h:911
auto back() const noexcept -> const_reference
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:468
auto begin() noexcept -> iterator
Return an iterator to the first element of the container.
Definition: SlidingBuffer.h:846
typename Container::pointer pointer
Pointer to an element.
Definition: SlidingBuffer.h:198
auto back() noexcept -> reference
Return the backmost element (the one with the highest valid index).
Definition: SlidingBuffer.h:457
auto end() const noexcept -> const_iterator
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: SlidingBuffer.h:879
auto push_back(const value_type &in) -> void
Insert one element at the end of the buffer; if it is full, an element at the front is dropped to mak...
Definition: SlidingBuffer.h:306
ShrinkBehavior
Determine how a SlidingBuffer handles decreases of its size.
Definition: SlidingBuffer.h:66
std::string cat()
Efficiently concatenate an arbitrary number of strings and numbers.
Definition: cat.h:97
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26