Add util::cyclic_iterator
This commit is contained in:
parent
aae4fa238f
commit
6f6a263553
1 changed files with 97 additions and 0 deletions
97
libs/util/include/psemek/util/cyclic_iterator.hpp
Normal file
97
libs/util/include/psemek/util/cyclic_iterator.hpp
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/util/range.hpp>
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace psemek::util
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
struct cyclic_iterator
|
||||||
|
{
|
||||||
|
using traits = std::iterator_traits<Iterator>;
|
||||||
|
using value_type = typename traits::value_type;
|
||||||
|
using reference = typename traits::reference;
|
||||||
|
using pointer = typename traits::pointer;
|
||||||
|
using difference_type = typename traits::difference_type;
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
|
||||||
|
Iterator begin, end;
|
||||||
|
Iterator iter;
|
||||||
|
|
||||||
|
cyclic_iterator() = default;
|
||||||
|
cyclic_iterator(cyclic_iterator const &) = default;
|
||||||
|
|
||||||
|
cyclic_iterator(Iterator begin, Iterator end, Iterator iter)
|
||||||
|
: begin(begin)
|
||||||
|
, end(end)
|
||||||
|
, iter(iter)
|
||||||
|
{}
|
||||||
|
|
||||||
|
cyclic_iterator(Iterator begin, Iterator end)
|
||||||
|
: begin(begin)
|
||||||
|
, end(end)
|
||||||
|
, iter(begin)
|
||||||
|
{}
|
||||||
|
|
||||||
|
cyclic_iterator & operator = (cyclic_iterator const &) = default;
|
||||||
|
|
||||||
|
decltype(auto) operator *()
|
||||||
|
{
|
||||||
|
return *iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
cyclic_iterator & operator++()
|
||||||
|
{
|
||||||
|
if (++iter == end)
|
||||||
|
iter = begin;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
cyclic_iterator operator++(int)
|
||||||
|
{
|
||||||
|
auto copy = *this;
|
||||||
|
this->operator++();
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
cyclic_iterator & operator--()
|
||||||
|
{
|
||||||
|
if (iter == begin)
|
||||||
|
iter = end;
|
||||||
|
--iter;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
cyclic_iterator operator--(int)
|
||||||
|
{
|
||||||
|
auto copy = *this;
|
||||||
|
this->operator--();
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator == (cyclic_iterator const & it1, cyclic_iterator const & it2)
|
||||||
|
{
|
||||||
|
return it1.iter == it2.iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator != (cyclic_iterator const & it1, cyclic_iterator const & it2)
|
||||||
|
{
|
||||||
|
return it1.iter != it2.iter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
cyclic_iterator(Iterator, Iterator, Iterator) -> cyclic_iterator<Iterator>;
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
cyclic_iterator(Iterator, Iterator) -> cyclic_iterator<Iterator>;
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
auto make_cyclic_iterator(Container & container)
|
||||||
|
{
|
||||||
|
return cyclic_iterator{util::begin(container), util::end(container)};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue