forked from organicmaps/organicmaps-tmp
Add range_iterator.
This commit is contained in:
parent
6c4b711fb4
commit
a2b10e7042
4 changed files with 138 additions and 0 deletions
|
@ -51,6 +51,7 @@ HEADERS += \
|
|||
mutex.hpp \
|
||||
object_tracker.hpp \
|
||||
observer_list.hpp \
|
||||
range_iterator.hpp \
|
||||
regexp.hpp \
|
||||
rolling_hash.hpp \
|
||||
scope_guard.hpp \
|
||||
|
|
|
@ -24,6 +24,7 @@ SOURCES += \
|
|||
matrix_test.cpp \
|
||||
mem_trie_test.cpp \
|
||||
observer_list_test.cpp \
|
||||
range_iterator_test.cpp \
|
||||
regexp_test.cpp \
|
||||
rolling_hash_test.cpp \
|
||||
scope_guard_test.cpp \
|
||||
|
|
43
base/base_tests/range_iterator_test.cpp
Normal file
43
base/base_tests/range_iterator_test.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "base/range_iterator.hpp"
|
||||
|
||||
#include "std/vector.hpp"
|
||||
|
||||
UNIT_TEST(RangeIterator)
|
||||
{
|
||||
using namespace base;
|
||||
|
||||
{
|
||||
vector<int> result;
|
||||
for (auto const i : range(5))
|
||||
result.push_back(i);
|
||||
TEST_EQUAL(result, (vector<int>{0, 1, 2, 3, 4}), ());
|
||||
}
|
||||
|
||||
{
|
||||
vector<int> result;
|
||||
for (auto const i : range(2, 5))
|
||||
result.push_back(i);
|
||||
TEST_EQUAL(result, (vector<int>{2, 3, 4}), ());
|
||||
}
|
||||
|
||||
{
|
||||
vector<int> result;
|
||||
for (auto const i : reverse_range(5))
|
||||
result.push_back(i);
|
||||
TEST_EQUAL(result, (vector<int>{4, 3, 2, 1, 0}), ());
|
||||
}
|
||||
|
||||
{
|
||||
vector<int> result;
|
||||
for (auto const i : reverse_range(2, 5))
|
||||
result.push_back(i);
|
||||
TEST_EQUAL(result, (vector<int>{4, 3, 2}), ());
|
||||
}
|
||||
|
||||
{
|
||||
TEST_EQUAL(std::vector<int>(MakeRangeIterator(0), MakeRangeIterator(5)),
|
||||
(std::vector<int>{0, 1, 2, 3, 4}), ());
|
||||
}
|
||||
}
|
93
base/range_iterator.hpp
Normal file
93
base/range_iterator.hpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include "std/iterator.hpp"
|
||||
#include "std/type_traits.hpp"
|
||||
|
||||
namespace base
|
||||
{
|
||||
template <typename TCounter>
|
||||
struct RangeIterator
|
||||
{
|
||||
explicit RangeIterator(TCounter const current):
|
||||
m_current(current)
|
||||
{
|
||||
}
|
||||
|
||||
RangeIterator & operator++() { ++m_current; return *this; }
|
||||
RangeIterator & operator--() { --m_current; return *this; }
|
||||
|
||||
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 = typename std::remove_cv<TCounter>::type;
|
||||
using iterator_base = RangeIterator<value_type>;
|
||||
using iterator = typename std::conditional<forward,
|
||||
iterator_base,
|
||||
std::reverse_iterator<iterator_base>>::type;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, true> range(TCounter const to)
|
||||
{
|
||||
return {{}, to};
|
||||
}
|
||||
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, true> range(TCounter const from, TCounter const to)
|
||||
{
|
||||
return {from, to};
|
||||
}
|
||||
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, false> reverse_range(TCounter const to)
|
||||
{
|
||||
return {to, {}};
|
||||
}
|
||||
|
||||
template <typename TCounter>
|
||||
RangeWrapper<TCounter, false> reverse_range(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
Reference in a new issue