self_iterating_contianer.hpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #pragma once
  2. namespace stream { namespace detail {
  3. template <typename C, typename It = typename C::const_iterator>
  4. class self_iterating_container {
  5. private:
  6. std::ptrdiff_t offset{0};
  7. C container;
  8. It current;
  9. It end;
  10. public:
  11. self_iterating_container() = default;
  12. self_iterating_container(C const & container)
  13. : container(container), current(container.cbegin()),
  14. end(container.cend()) {}
  15. self_iterating_container(C && container)
  16. : container(std::move(container)), current(container.cbegin()),
  17. end(container.cend()) {}
  18. self_iterating_container(self_iterating_container const & other) {
  19. *this = other;
  20. }
  21. self_iterating_container(self_iterating_container && other) {
  22. *this = std::move(other);
  23. }
  24. self_iterating_container &
  25. operator=(self_iterating_container const & other) {
  26. offset = other.offset;
  27. container = other.container;
  28. setup();
  29. return *this;
  30. }
  31. self_iterating_container & operator=(self_iterating_container && other) {
  32. offset = other.offset;
  33. container = std::move(other.container);
  34. setup();
  35. return *this;
  36. }
  37. void operator++() {
  38. ++offset;
  39. ++current;
  40. }
  41. auto & operator*() const { return *current; }
  42. operator bool() const { return current != end; }
  43. private:
  44. void setup() {
  45. current = container.cbegin();
  46. end = container.cend();
  47. std::advance(current, offset);
  48. }
  49. };
  50. }}