General Utility Library for C++14  2.8
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 #include "gul14/cat.h"
31 #include "gul14/internal.h"
32 
33 namespace gul14 {
34 
59 enum class ShrinkBehavior { keep_front_elements, keep_back_elements };
60 
169 template<typename ElementT, std::size_t fixed_capacity = 0u,
170  typename Container = typename std::conditional_t<(fixed_capacity >= 1u),
171  std::array<ElementT, fixed_capacity>,
172  std::vector<ElementT>>
173  >
175 public:
176  template <typename>
177  class SlidingBufferIterator;
179  using container_type = Container;
181  using value_type = ElementT;
183  using size_type = typename Container::size_type;
185  using difference_type = typename Container::difference_type;
187  using reference = typename Container::reference;
189  using const_reference = typename Container::const_reference;
191  using pointer = typename Container::pointer;
193  using const_pointer = typename Container::const_pointer;
199  using reverse_iterator = std::reverse_iterator<iterator>;
201  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
202 
215  SlidingBuffer() = default;
217  SlidingBuffer(SlidingBuffer const&) = default;
219  SlidingBuffer(SlidingBuffer&&) noexcept(std::is_nothrow_move_constructible<container_type>::value) = default;
221  SlidingBuffer& operator=(SlidingBuffer const&) = default;
223  SlidingBuffer& operator=(SlidingBuffer &&) noexcept(std::is_nothrow_move_assignable<container_type>::value) = default;
225  virtual ~SlidingBuffer() = default;
226 
237  SlidingBuffer(size_type count) : storage_(count) {}
238 
239 protected:
240 
243  size_type idx_begin_{ 0u };
246  size_type idx_end_{ 0u };
248  bool full_{ false };
250  Container storage_{ };
251 
252 public:
263  auto pop_back() -> void
264  {
265  decrease_idx(idx_end_);
266  full_ = false;
267  }
268 
280  auto pop_front() -> void
281  {
282  increase_idx(idx_begin_);
283  full_ = false;
284  }
285 
299  auto push_back(const value_type& in) -> void
300  {
301  storage_[idx_end_] = in;
302 
303  increase_idx(idx_end_);
304  if (full_)
305  increase_idx(idx_begin_);
306  else if (idx_end_ == idx_begin_)
307  full_ = true;
308  }
309 
313  auto push_back(value_type&& in) -> void
314  {
315  storage_[idx_end_] = std::move(in);
316 
317  increase_idx(idx_end_);
318  if (full_)
319  increase_idx(idx_begin_);
320  else if (idx_end_ == idx_begin_)
321  full_ = true;
322  }
323 
337  auto push_front(const value_type& in) -> void
338  {
339  decrease_idx(idx_begin_);
340 
341  if (full_)
342  decrease_idx(idx_end_);
343  else if (idx_end_ == idx_begin_)
344  full_ = true;
345 
346  storage_[idx_begin_] = in;
347  }
348 
352  auto push_front(value_type&& in) -> void
353  {
354  decrease_idx(idx_begin_);
355 
356  if (full_)
357  decrease_idx(idx_end_);
358  else if (idx_end_ == idx_begin_)
359  full_ = true;
360 
361  storage_[idx_begin_] = std::move(in);
362  }
363 
374  auto operator[](size_type idx) noexcept -> reference
375  {
376  idx += idx_begin_;
377 
378  return (idx >= capacity()) ? storage_[idx - capacity()] : storage_[idx];
379  }
380 
384  auto operator[](size_type idx) const noexcept -> const_reference
385  {
386  idx += idx_begin_;
387 
388  return (idx >= capacity()) ? storage_[idx - capacity()] : storage_[idx];
389  }
390 
402  auto at(const size_type idx) noexcept(false) -> reference
403  {
404  auto const s = size();
405  if (idx >= s) {
406  throw std::out_of_range(gul14::cat("SlidingBuffer::", __func__,
407  ": idx (which is ", idx, ") >= this->size() (which is ", s, ")"));
408  }
409  return operator[](idx);
410  }
411 
415  auto at(const size_type idx) const noexcept(false) -> const_reference
416  {
417  auto const s = size();
418  if (idx >= s) {
419  throw std::out_of_range(gul14::cat("SlidingBuffer::", __func__,
420  ": idx (which is ", idx, ") >= this->size() (which is ", s, ")"));
421  }
422  return operator[](idx);
423  }
424 
431  auto front() noexcept -> reference
432  {
433  return storage_[idx_begin_];
434  }
435 
439  auto front() const noexcept -> const_reference
440  {
441  return storage_[idx_begin_];
442  }
443 
450  auto back() noexcept -> reference
451  {
452  if (idx_end_ == 0)
453  return storage_[capacity() - 1];
454  else
455  return storage_[idx_end_ - 1];
456  }
457 
461  auto back() const noexcept -> const_reference
462  {
463  if (idx_end_ == 0)
464  return storage_[capacity() - 1];
465  else
466  return storage_[idx_end_ - 1];
467  }
468 
476  auto size() const noexcept -> size_type
477  {
478  if (full_)
479  return capacity();
480 
481  if (idx_end_ >= idx_begin_)
482  return idx_end_ - idx_begin_;
483  else
484  return idx_end_ + capacity() - idx_begin_;
485  }
486 
494  auto constexpr capacity() const noexcept -> size_type
495  {
496  return (fixed_capacity > 0) ? fixed_capacity : storage_.size();
497  }
498 
507  auto filled() const noexcept -> bool
508  {
509  return full_;
510  }
511 
519  auto clear() -> void
520  {
521  full_ = false;
522  idx_begin_ = 0u;
523  idx_end_ = 0u;
524 
525  // Fill with new empty elements to possibly trigger RAII in the elements
526  std::fill(storage_.begin(), storage_.end(), value_type{});
527  }
528 
548  auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
549  {
550  static_assert(fixed_capacity == 0u,
551  "resize() only possible if the underlying container is resizable");
552  change_capacity(new_capacity, shrink_behavior);
553  }
554 
559  auto reserve(size_type size, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
560  {
561  static_assert(fixed_capacity == 0u,
562  "reserve() only possible if the underlying container is resizable");
563  change_capacity(size, shrink_behavior);
564  }
565 
571  auto empty() const noexcept -> bool
572  {
573  return (not full_) and (idx_begin_ == idx_end_);
574  }
575 
583  auto friend operator<< (std::ostream& s,
584  const SlidingBuffer<value_type, fixed_capacity, container_type>& buffer) -> std::ostream&
585  {
586  auto const size = buffer.size();
587  // We can not use range-for here, because of SlidingBufferExposed<>'s un-wrapped iterators
588  for (auto i = size_type{ 0 }; i < size; ++i)
589  s << buffer[i] << " ";
590  return s << '\n';
591  }
592 
633  template <typename BufferPointer>
635  {
636  protected:
638  size_type position_{ 0 };
639  private:
641  BufferPointer buffer_;
642 
643  public:
644  // Set of 5 member types that are needed by std::iterator_traits:
645 
647  using iterator_category = std::random_access_iterator_tag;
649  using value_type = ElementT;
651  using difference_type = std::ptrdiff_t;
653  using pointer = value_type*;
656 
663  explicit SlidingBufferIterator(BufferPointer buff, size_type num = 0) noexcept
664  : position_{ num }
665  , buffer_{ buff }
666  {
667  }
668 
670  auto operator++() noexcept -> SlidingBufferIterator&
671  {
672  ++position_;
673  return *this;
674  }
675 
677  auto operator++(int) noexcept -> SlidingBufferIterator
678  {
679  auto previous = *this;
680  ++(*this);
681  return previous;
682  }
683 
686  {
687  position_ += d;
688  return *this;
689  }
690 
692  friend auto
695  {
696  return SlidingBufferIterator{ it.buffer_, it.position_ + d };
697  }
698 
700  friend auto
703  {
704  return SlidingBufferIterator{ it.buffer_, it.position_ + d };
705  }
706 
708  auto operator--() noexcept -> SlidingBufferIterator&
709  {
710  --position_;
711  return *this;
712  }
713 
715  auto operator--(int) noexcept -> SlidingBufferIterator
716  {
717  auto previous = *this;
718  --(*this);
719  return previous;
720  }
721 
724  {
725  position_ -= d;
726  return *this;
727  }
728 
730  friend auto
733  {
734  return SlidingBufferIterator{ it.buffer_, it.position_ - d };
735  }
736 
738  friend auto
739  operator-(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
740  -> difference_type
741  {
742  return lhs.position_ - rhs.position_;
743  }
744 
746  auto operator*() const noexcept -> typename std::conditional_t<
747  std::is_const<std::remove_pointer_t<BufferPointer>>::value,
749  {
750  return (*buffer_)[position_];
751  }
752 
754  auto operator->() const noexcept -> typename std::conditional_t<
755  std::is_const<std::remove_pointer_t<BufferPointer>>::value,
757  {
758  return &(*buffer_)[position_];
759  }
760 
762  auto operator[](difference_type offs) noexcept -> typename std::conditional_t<
763  std::is_const<std::remove_pointer_t<BufferPointer>>::value,
765  {
766  return *(*this + offs);
767  }
768 
774  friend auto
775  operator==(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
776  -> bool
777  {
778  return lhs.position_ == rhs.position_;
779  }
780 
786  friend auto
787  operator!=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
788  -> bool
789  {
790  return not(lhs == rhs);
791  }
792 
796  friend auto
797  operator>(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
798  -> bool
799  {
800  return lhs.position_ > rhs.position_;
801  }
802 
804  friend auto
805  operator<(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
806  -> bool
807  {
808  return lhs.position_ < rhs.position_;
809  }
810 
815  friend auto
816  operator>=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
817  -> bool
818  {
819  return lhs.position_ >= rhs.position_;
820  }
821 
826  friend auto
827  operator<=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept
828  -> bool
829  {
830  return lhs.position_ <= rhs.position_;
831  }
832  };
833 
839  auto begin() noexcept -> iterator
840  {
841  return iterator{ this, 0 };
842  }
843 
845  auto begin() const noexcept -> const_iterator
846  {
847  return const_iterator{ this, 0 };
848  }
849 
855  auto rbegin() noexcept -> reverse_iterator
856  {
857  return std::make_reverse_iterator(end());
858  }
859 
866  auto end() noexcept -> iterator
867  {
868  return iterator{ this, size() };
869  }
870 
872  auto end() const noexcept -> const_iterator
873  {
874  return const_iterator{ this, size() };
875  }
876 
884  auto rend() noexcept -> reverse_iterator
885  {
886  return std::make_reverse_iterator(begin());
887  }
888 
894  auto cbegin() const noexcept -> const_iterator
895  {
896  return const_iterator{ this, 0 };
897  }
898 
904  auto crbegin() const noexcept -> const_reverse_iterator
905  {
906  return std::make_reverse_iterator(cend());
907  }
908 
916  auto cend() const noexcept -> const_iterator
917  {
918  return const_iterator{ this, size() };
919  }
920 
928  auto crend() const noexcept -> const_reverse_iterator
929  {
930  return std::make_reverse_iterator(cbegin());
931  }
932 
933 private:
934  void decrease_idx(size_t &idx) noexcept
935  {
936  if (idx == 0)
937  idx = capacity() - 1;
938  else
939  --idx;
940  }
941 
942  void increase_idx(size_t &idx) noexcept
943  {
944  ++idx;
945 
946  if (idx >= capacity())
947  idx = 0;
948  }
949 
950 protected:
965  auto change_capacity(size_type new_capacity, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
966  {
967  auto const old_capacity = capacity();
968  auto const old_size = size();
969 
971  // No change
972  if (new_capacity == old_capacity)
973  return;
974 
976  // Vanishing
977  if (new_capacity == 0) {
978  storage_.resize(0);
979  idx_begin_ = 0;
980  idx_end_ = 0;
981  full_ = false;
982  return;
983  }
984 
985 
987  // Growing
988  if (new_capacity > old_capacity) {
989  // Make SlidingBuffer indices equal to those of the underlying container
990  std::rotate(storage_.begin(), storage_.begin() + idx_begin_, storage_.end());
991  storage_.resize(new_capacity);
992  idx_begin_ = 0;
993  idx_end_ = old_size;
994  full_ = false;
995  return;
996  }
997 
999  // Shrinking
1000  if (old_size < new_capacity) {
1001  // All data fits into new capacity, just move it there
1002  std::rotate(storage_.begin(), storage_.begin() + idx_begin_, storage_.end());
1003  storage_.resize(new_capacity);
1004  idx_begin_ = 0;
1005  idx_end_ = old_size;
1006  full_ = false;
1007  }
1008  else {
1009  auto new_front = idx_begin_;
1010  if (shrink_behavior == ShrinkBehavior::keep_back_elements)
1011  new_front = (idx_end_ + old_capacity - new_capacity) % old_capacity;
1012 
1013  std::rotate(storage_.begin(), storage_.begin() + new_front, storage_.end());
1014  storage_.resize(new_capacity);
1015  full_ = true;
1016  idx_begin_ = 0;
1017  idx_end_ = 0;
1018  }
1019  }
1020 };
1021 
1065 template<typename ElementT, std::size_t fixed_capacity = 0u,
1066  typename Container = typename std::conditional_t<(fixed_capacity >= 1u),
1067  std::array<ElementT, fixed_capacity>,
1068  std::vector<ElementT>>
1069  >
1071 public:
1073  using iterator = typename Container::iterator;
1075  using const_iterator = typename Container::const_iterator;
1077  using reverse_iterator = typename Container::reverse_iterator;
1079  using const_reverse_iterator = typename Container::const_reverse_iterator;
1080 
1081  // Inherit member types
1090 
1091  // Inherit constructors
1093 
1094  // Inherit members for access without "this->"
1100 
1114  auto begin() noexcept -> iterator
1115  {
1116  if (not full_ and (idx_end_ == 0 or idx_end_ >= idx_begin_))
1117  return storage_.begin() + idx_begin_;
1118 
1119  return storage_.begin();
1120  }
1121 
1123  auto begin() const noexcept -> const_iterator
1124  {
1125  return cbegin();
1126  }
1127 
1134  auto cbegin() const noexcept -> const_iterator
1135  {
1136  if (not full_ and (idx_end_ == 0 or idx_end_ >= idx_begin_))
1137  return storage_.cbegin() + idx_begin_;
1138 
1139  return storage_.cbegin();
1140  }
1141 
1159  auto end() noexcept -> iterator
1160  {
1161  if (full_ or idx_begin_ != 0)
1162  return storage_.end();
1163 
1164  return storage_.begin() + idx_end_;
1165  }
1166 
1168  auto end() const noexcept -> const_iterator
1169  {
1170  return cend();
1171  }
1172 
1179  auto cend() const noexcept -> const_iterator
1180  {
1181  if (full_ or idx_begin_ != 0)
1182  return storage_.cend();
1183 
1184  return storage_.cbegin() + idx_end_;
1185  }
1186 
1195  auto rbegin() noexcept -> reverse_iterator
1196  {
1197  return std::make_reverse_iterator(end());
1198  }
1199 
1208  auto crbegin() const noexcept -> const_reverse_iterator
1209  {
1210  return std::make_reverse_iterator(cend());
1211  }
1212 
1218  auto rend() noexcept -> reverse_iterator
1219  {
1220  return std::make_reverse_iterator(begin());
1221  }
1222 
1229  auto crend() const noexcept -> const_reverse_iterator
1230  {
1231  return std::make_reverse_iterator(cbegin());
1232  }
1233 
1253  auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
1254  {
1255  static_assert(fixed_capacity == 0u,
1256  "resize() only possible if the underlying container is resizable");
1257 
1258  // We handle just one special case here: A pure right aligned un-full buffer
1259  //
1260  // I.e. only push_front() (not push_back()) has been used until now, and
1261  // the buffer is not yet filled completely. Then the data will only occupy
1262  // the 'right hand side' of the underlying container.
1263  //
1264  // In order to fulfill begin()'s and end()'s guarantee to include only
1265  // filled elements we need to right-align the data in the new container.
1266 
1267  auto const old_capacity = capacity();
1268 
1269  auto const right_align =
1270  (shrink_behavior == ShrinkBehavior::keep_front_elements)
1271  and (new_capacity > 0)
1272  and (new_capacity != old_capacity)
1273  and (not full_)
1274  and (idx_end_ == 0)
1275  and (idx_begin_ != 0);
1276 
1277  if (not right_align)
1278  return this->change_capacity(new_capacity, shrink_behavior);
1279 
1281  // Growing
1282  if (new_capacity > old_capacity) {
1283  storage_.resize(new_capacity);
1284  std::move_backward(storage_.begin() + idx_begin_,
1285  storage_.begin() + old_capacity, storage_.end());
1286  idx_begin_ += new_capacity - old_capacity;
1287  return;
1288  }
1289 
1291  // Shrinking
1292  full_ = (this->size() >= new_capacity);
1293  auto const required_shift = std::min(old_capacity - new_capacity, idx_begin_);
1294  std::rotate(storage_.begin(), storage_.begin() + required_shift, storage_.end());
1295  idx_begin_ -= required_shift;
1296  storage_.resize(new_capacity);
1297  }
1298 
1303  auto reserve(size_type size, ShrinkBehavior shrink_behavior = ShrinkBehavior::keep_front_elements) -> void
1304  {
1305  static_assert(fixed_capacity == 0u,
1306  "reserve() only possible if the underlying container is resizable");
1307  resize(size, shrink_behavior);
1308  }
1309 };
1310 
1311 } // namespace gul14
1312 
1313 #endif
1314 
1315 // 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:1070
typename Container::reverse_iterator reverse_iterator
Iterator to an element in reversed container.
Definition: SlidingBuffer.h:1077
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:1168
auto begin() noexcept -> iterator
Return an iterator to the first occupied element of the underlying container.
Definition: SlidingBuffer.h:1114
auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container.
Definition: SlidingBuffer.h:1253
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:1179
auto reserve(size_type size, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container (identical to resize()).
Definition: SlidingBuffer.h:1303
typename Container::const_iterator const_iterator
Iterator to a const element.
Definition: SlidingBuffer.h:1075
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:1123
auto cbegin() const noexcept -> const_iterator
Return a constant iterator to the first occupied element of the underlying container.
Definition: SlidingBuffer.h:1134
auto rbegin() noexcept -> reverse_iterator
Return a reverse iterator to the first used element of the reversed underlying container.
Definition: SlidingBuffer.h:1195
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:1159
auto crend() const noexcept -> const_reverse_iterator
Return a constant iterator to the last element of the reversed underlying container.
Definition: SlidingBuffer.h:1229
auto rend() noexcept -> reverse_iterator
Return an iterator to the last element of the reversed underlying container.
Definition: SlidingBuffer.h:1218
typename Container::iterator iterator
Iterator to an element.
Definition: SlidingBuffer.h:1073
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:1208
typename Container::const_reverse_iterator const_reverse_iterator
Iterator to a const element in reversed container.
Definition: SlidingBuffer.h:1079
Iterator of the SlidingBuffer container.
Definition: SlidingBuffer.h:635
ElementT value_type
The type "pointed to" by the iterator.
Definition: SlidingBuffer.h:649
friend auto operator+(difference_type d, const SlidingBufferIterator &it) noexcept -> SlidingBufferIterator
Add an integer and an iterator.
Definition: SlidingBuffer.h:701
friend auto operator+(const SlidingBufferIterator &it, difference_type d) noexcept -> SlidingBufferIterator
Add an integer to an iterator.
Definition: SlidingBuffer.h:693
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:754
auto operator++(int) noexcept -> SlidingBufferIterator
Post-increment iterator by one position.
Definition: SlidingBuffer.h:677
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:816
auto operator++() noexcept -> SlidingBufferIterator &
Pre-increment iterator by one position.
Definition: SlidingBuffer.h:670
auto operator--(int) noexcept -> SlidingBufferIterator
Post-decrement iterator by one position.
Definition: SlidingBuffer.h:715
std::ptrdiff_t difference_type
Distance between iterators is represented as this type.
Definition: SlidingBuffer.h:651
value_type & reference
This type represents a reference-to-value_type.
Definition: SlidingBuffer.h:655
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:797
auto operator+=(difference_type d) noexcept -> SlidingBufferIterator &
Increase iterator by a given number of positions.
Definition: SlidingBuffer.h:685
std::random_access_iterator_tag iterator_category
Defines the category of the iterator.
Definition: SlidingBuffer.h:647
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:762
auto operator--() noexcept -> SlidingBufferIterator &
Pre-decrement iterator by one position.
Definition: SlidingBuffer.h:708
friend auto operator-(const SlidingBufferIterator &it, difference_type d) noexcept -> SlidingBufferIterator
Subtract an integer from an iterator.
Definition: SlidingBuffer.h:731
SlidingBufferIterator(BufferPointer buff, size_type num=0) noexcept
Create an iterator pointing into a SlidingBuffer.
Definition: SlidingBuffer.h:663
value_type * pointer
This type represents a pointer-to-value_type.
Definition: SlidingBuffer.h:653
friend auto operator-(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> difference_type
Subtract two iterators.
Definition: SlidingBuffer.h:739
friend auto operator==(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> bool
Compare two iterators for equality.
Definition: SlidingBuffer.h:775
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:746
auto operator-=(difference_type d) noexcept -> SlidingBufferIterator &
Decrease iterator by a given number of positions.
Definition: SlidingBuffer.h:723
friend auto operator!=(const SlidingBufferIterator &lhs, const SlidingBufferIterator &rhs) noexcept -> bool
Compare two iterators for inequality.
Definition: SlidingBuffer.h:787
A circular data buffer of (semi-)fixed capacity to which elements can be added at the front or at the...
Definition: SlidingBuffer.h:174
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:337
typename Container::size_type size_type
Unsigned integer type (usually std::size_t)
Definition: SlidingBuffer.h:183
auto filled() const noexcept -> bool
Return true if the buffer is completely filled with elements.
Definition: SlidingBuffer.h:507
auto cbegin() const noexcept -> const_iterator
Return a read-only iterator to the first element of the container.
Definition: SlidingBuffer.h:894
auto size() const noexcept -> size_type
Return the number of elements in the container, i.e.
Definition: SlidingBuffer.h:476
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:384
std::reverse_iterator< const_iterator > const_reverse_iterator
Iterator to a const element in reversed container.
Definition: SlidingBuffer.h:201
auto change_capacity(size_type new_capacity, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Change the underlying container's capacity.
Definition: SlidingBuffer.h:965
auto cend() const noexcept -> const_iterator
Return a read-only iterator to the element following the last element of the container.
Definition: SlidingBuffer.h:916
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:402
auto pop_front() -> void
Remove the first element from the buffer.
Definition: SlidingBuffer.h:280
auto reserve(size_type size, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container (identical to resize()).
Definition: SlidingBuffer.h:559
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:928
Container container_type
Type of the underlying container (e.g. std::array<value_type, ..>)
Definition: SlidingBuffer.h:179
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:313
typename Container::const_reference const_reference
Reference to a constant element.
Definition: SlidingBuffer.h:189
auto end() noexcept -> iterator
Return an iterator to the element following the last element of the container.
Definition: SlidingBuffer.h:866
auto rbegin() noexcept -> reverse_iterator
Return an iterator to the first element of the reversed container.
Definition: SlidingBuffer.h:855
typename Container::const_pointer const_pointer
Pointer to a constant element.
Definition: SlidingBuffer.h:193
SlidingBuffer()=default
Construct an empty sliding buffer.
typename Container::difference_type difference_type
Signed integer type (usually std::ptrdiff_t)
Definition: SlidingBuffer.h:185
auto operator[](size_type idx) noexcept -> reference
Access an element in the buffer by index without bounds checking.
Definition: SlidingBuffer.h:374
std::reverse_iterator< iterator > reverse_iterator
Iterator to an element in reversed container.
Definition: SlidingBuffer.h:199
auto front() noexcept -> reference
Return the foremost element (the one with index 0).
Definition: SlidingBuffer.h:431
auto empty() const noexcept -> bool
Check if the buffer contains no elements, i.e.
Definition: SlidingBuffer.h:571
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:439
ElementT value_type
Type of the elements in the underlying container.
Definition: SlidingBuffer.h:181
auto clear() -> void
Empty the buffer.
Definition: SlidingBuffer.h:519
auto resize(size_type new_capacity, ShrinkBehavior shrink_behavior=ShrinkBehavior::keep_front_elements) -> void
Resize the container.
Definition: SlidingBuffer.h:548
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:845
auto rend() noexcept -> reverse_iterator
Return an iterator to the element following the last element of the reversed container.
Definition: SlidingBuffer.h:884
constexpr auto capacity() const noexcept -> size_type
Return the maximum possible number of elements in the container.
Definition: SlidingBuffer.h:494
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:352
typename Container::reference reference
Reference to an element.
Definition: SlidingBuffer.h:187
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:415
auto pop_back() -> void
Remove the last element from the buffer.
Definition: SlidingBuffer.h:263
auto crbegin() const noexcept -> const_reverse_iterator
Return a read-only iterator to the first element of the reversed container.
Definition: SlidingBuffer.h:904
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:461
auto begin() noexcept -> iterator
Return an iterator to the first element of the container.
Definition: SlidingBuffer.h:839
typename Container::pointer pointer
Pointer to an element.
Definition: SlidingBuffer.h:191
auto back() noexcept -> reference
Return the backmost element (the one with the highest valid index).
Definition: SlidingBuffer.h:450
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:872
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:299
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
ShrinkBehavior
Determine how a SlidingBuffer handles decreases of its size.
Definition: SlidingBuffer.h:59
std::string cat()
Efficiently concatenate an arbitrary number of strings and numbers.
Definition: cat.h:90