Skip to content

Instantly share code, notes, and snippets.

@mtao
Created September 6, 2017 01:28
Show Gist options
  • Save mtao/02fbdb28b195691ecfb61787ffc06302 to your computer and use it in GitHub Desktop.
Save mtao/02fbdb28b195691ecfb61787ffc06302 to your computer and use it in GitHub Desktop.
#ifndef CYCLIC_LIST_HPP
#define CYCLIC_LIST_HPP
#include <list>
namespace detail {
template <typename Iterable>
struct cyclic_iterator {
public:
using iterable_type = Iterable;
using iterator_type = typename iterable_type::const_iterator;
using value_type = typename Iterable::value_type;
cyclic_iterator(const Iterable* ptr, iterator_type it): p(ptr), i(it) {}
cyclic_iterator& operator++() {
++i;
if(i == p->cend()) {
i = p->cbegin();
}
return *this;
}
cyclic_iterator& operator--() {
if(i == p->cbegin()) {
i = p->cend();
--i;
} else {
--i;
}
return *this;
}
const value_type operator*() const { return *i; }
private:
const Iterable* p = nullptr;
iterator_type i;
};
};
template <typename T>
struct cyclic_list: public std::list<T> {
public:
using cyclic_iterator_type = detail::cyclic_iterator<std::list<T>>;
using std::list<T>::begin;
using std::list<T>::end;
using std::list<T>::cbegin;
using std::list<T>::cend;
using std::list<T>::list;
cyclic_iterator_type cycbegin() const { return {this,cbegin()}; }
cyclic_iterator_type cycend() const { return {this,cend()}; }
};
#include <iterator>
#include <algorithm>
#include <numeric>
#include <iostream>
int main() {
std::list<int> D(10);
std::iota(D.begin(),D.end(), 0);
std::copy(D.begin(),D.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
cyclic_list<int> E(10);
std::iota(E.begin(),E.end(), 0);
auto cit = E.cycbegin();
for(int i = 0; i < 25; ++i) {
std::cout << *cit << " ";
++cit;
}
std::cout << std::endl;
for(int i = 0; i < 25; ++i) {
std::cout << *cit << " ";
--cit;
}
std::cout << std::endl;
}
#endif//CYCLIC_LIST_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment