Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
104
libs/base/range_iterator.hpp
Normal file
104
libs/base/range_iterator.hpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#pragma once
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace base
|
||||
{
|
||||
// RagneItrator allows to write for loops as follows:
|
||||
// for (auto const i : range(N))
|
||||
// ...
|
||||
// for (auto const i : range(M, N))
|
||||
// ...
|
||||
// And initialize stl containers like this:
|
||||
// vector<int> mySequence(MakeRangeIterator(0), MakeRangeIterator(10));
|
||||
template <typename TCounter>
|
||||
struct RangeIterator
|
||||
{
|
||||
explicit RangeIterator(TCounter const current) : m_current(current) {}
|
||||
RangeIterator & operator++()
|
||||
{
|
||||
++m_current;
|
||||
return *this;
|
||||
}
|
||||
RangeIterator operator++(int) { return RangeIterator(m_current++); }
|
||||
RangeIterator & operator--()
|
||||
{
|
||||
--m_current;
|
||||
return *this;
|
||||
}
|
||||
RangeIterator operator--(int) { return RangeIterator(m_current--); }
|
||||
bool operator==(RangeIterator const & it) const { return m_current == it.m_current; }
|
||||
bool operator!=(RangeIterator const & it) const { return !(*this == it); }
|
||||
|
||||
TCounter operator*() const { return m_current; }
|
||||
|
||||
TCounter m_current;
|
||||
};
|
||||
} // namespace base
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T>
|
||||
struct iterator_traits<base::RangeIterator<T>>
|
||||
{
|
||||
using difference_type = T;
|
||||
using value_type = T;
|
||||
using pointer = void;
|
||||
using reference = T;
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
namespace base
|
||||
{
|
||||
template <typename TCounter, bool forward>
|
||||
struct RangeWrapper
|
||||
{
|
||||
using value_type = std::remove_cv_t<TCounter>;
|
||||
using iterator_base = RangeIterator<value_type>;
|
||||
using iterator = std::conditional_t<forward, iterator_base, std::reverse_iterator<iterator_base>>;
|
||||
|
||||
RangeWrapper(TCounter const from, TCounter const to) : m_begin(from), m_end(to) {}
|
||||
|
||||
iterator begin() const { return iterator(iterator_base(m_begin)); }
|
||||
iterator end() const { return iterator(iterator_base(m_end)); }
|
||||
|
||||
value_type const m_begin;
|
||||
value_type const m_end;
|
||||
};
|
||||
|
||||
// Use this helper to iterate through 0 to `to'.
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, true> UpTo(TCounter const to)
|
||||
{
|
||||
return {{}, to};
|
||||
}
|
||||
|
||||
// Use this helper to iterate through `from' to `to'.
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, true> UpTo(TCounter const from, TCounter const to)
|
||||
{
|
||||
return {from, to};
|
||||
}
|
||||
|
||||
// Use this helper to iterate through `from' to 0.
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, false> DownTo(TCounter const from)
|
||||
{
|
||||
return {from, {}};
|
||||
}
|
||||
|
||||
// Use this helper to iterate through `from' to `to'.
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, false> DownTo(TCounter const from, TCounter const to)
|
||||
{
|
||||
return {to, from};
|
||||
}
|
||||
|
||||
template <typename TCounter>
|
||||
RangeIterator<TCounter> MakeRangeIterator(TCounter const counter)
|
||||
{
|
||||
return RangeIterator<TCounter>(counter);
|
||||
}
|
||||
} // namespace base
|
||||
Loading…
Add table
Add a link
Reference in a new issue