#pragma once namespace stream { namespace detail { template class self_iterating_container { private: std::ptrdiff_t offset{0}; C container; It current; It end; public: self_iterating_container() = default; self_iterating_container(C const & container) : container(container), current(container.cbegin()), end(container.cend()) {} self_iterating_container(C && container) : container(std::move(container)), current(container.cbegin()), end(container.cend()) {} self_iterating_container(self_iterating_container const & other) { *this = other; } self_iterating_container(self_iterating_container && other) { *this = std::move(other); } self_iterating_container & operator=(self_iterating_container const & other) { offset = other.offset; container = other.container; setup(); return *this; } self_iterating_container & operator=(self_iterating_container && other) { offset = other.offset; container = std::move(other.container); setup(); return *this; } void operator++() { ++offset; ++current; } auto& operator*() const { return *current; } operator bool() const { return current != end; } private: void setup() { current = container.cbegin(); end = container.cend(); std::advance(current, offset); } }; }}