mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: implement an enumerating iterator
In the printing-template code, we loop through a vector and then determine the index of the current element by searching the vector. This irks me. Since looping over a collection with an index is a rather common theme, implement an enumerating iterator that can be used as in: for (auto [idx, item]: enumerated_range(v)) { ... } For now, use it for the above vexing case. Convert other iterations of this theme later. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
94641c510f
commit
cea171ffd4
2 changed files with 56 additions and 2 deletions
53
core/range.h
53
core/range.h
|
@ -3,6 +3,9 @@
|
|||
#ifndef RANGE_H
|
||||
#define RANGE_H
|
||||
|
||||
#include <utility> // for std::pair
|
||||
#include <vector> // we need a declaration of std::begin() and std::end()
|
||||
|
||||
// Move a range in a vector to a different position.
|
||||
// The parameters are given according to the usual STL-semantics:
|
||||
// v: a container with STL-like random access iterator via std::begin(...)
|
||||
|
@ -29,4 +32,54 @@ void move_in_range(Range &v, int rangeBegin, int rangeEnd, int destination)
|
|||
std::rotate(it + destination, it + rangeBegin, it + rangeEnd);
|
||||
}
|
||||
|
||||
// A rudimentary adaptor for looping over ranges with an index:
|
||||
// for (auto [idx, item]: enumerated_range(v)) ...
|
||||
// The index is a signed integer, since this is what we use more often.
|
||||
template <typename Range>
|
||||
class enumerated_range
|
||||
{
|
||||
Range &base;
|
||||
public:
|
||||
using base_iterator = decltype(std::begin(std::declval<Range>()));
|
||||
class iterator {
|
||||
int idx;
|
||||
base_iterator it;
|
||||
public:
|
||||
std::pair<int, decltype(*it)> operator*() const
|
||||
{
|
||||
return { idx, *it };
|
||||
}
|
||||
iterator &operator++()
|
||||
{
|
||||
++idx;
|
||||
++it;
|
||||
return *this;
|
||||
}
|
||||
iterator(int idx, base_iterator it) : idx(idx), it(it)
|
||||
{
|
||||
}
|
||||
bool operator==(const iterator &it2) const
|
||||
{
|
||||
return it == it2.it;
|
||||
}
|
||||
bool operator!=(const iterator &it2) const
|
||||
{
|
||||
return it != it2.it;
|
||||
}
|
||||
};
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(0, std::begin(base));
|
||||
}
|
||||
iterator end()
|
||||
{
|
||||
return iterator(-1, std::end(base));
|
||||
}
|
||||
|
||||
enumerated_range(Range &base) : base(base)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue