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