#ifndef ITER_CYCLE_H_ #define ITER_CYCLE_H_ #include "internal/iterbase.hpp" #include #include #include namespace iter { namespace impl { template class Cycler; } template impl::Cycler cycle(Container&&); template impl::Cycler> cycle(std::initializer_list); } template class iter::impl::Cycler { private: friend Cycler iter::cycle(Container&&); template friend Cycler> iter::cycle(std::initializer_list); Container container; Cycler(Container&& in_container) : container(std::forward(in_container)) {} public: Cycler(Cycler&&) = default; class Iterator : public std::iterator> { private: iterator_type sub_iter; iterator_type begin; iterator_type end; public: Iterator( const iterator_type& iter, iterator_type&& in_end) : sub_iter{iter}, begin{iter}, end{std::move(in_end)} {} iterator_deref operator*() { return *this->sub_iter; } iterator_arrow operator->() { return apply_arrow(this->sub_iter); } Iterator& operator++() { ++this->sub_iter; // reset to beginning upon reaching the end if (!(this->sub_iter != this->end)) { this->sub_iter = this->begin; } return *this; } Iterator operator++(int) { auto ret = *this; ++*this; return ret; } bool operator!=(const Iterator& other) const { return this->sub_iter != other.sub_iter; } bool operator==(const Iterator& other) const { return !(*this != other); } }; Iterator begin() { return {std::begin(this->container), std::end(this->container)}; } Iterator end() { return {std::end(this->container), std::end(this->container)}; } }; template iter::impl::Cycler iter::cycle(Container&& container) { return {std::forward(container)}; } template iter::impl::Cycler> iter::cycle( std::initializer_list il) { return {std::move(il)}; } #endif