Program Listing for File enumerate.hpp¶
↰ Return to documentation for file (include/util/enumerate.hpp)
#ifndef THAT_THIS_UTIL_DATA_ENUMERATE_HEADER_IS_ALREADY_INCLUDED
#define THAT_THIS_UTIL_DATA_ENUMERATE_HEADER_IS_ALREADY_INCLUDED
#include <cstddef>
#include <iterator>
#include <utility>
namespace util {
template <class Container>
struct enumerate_range {
static constexpr bool Const = std::is_const_v<Container>;
class iterator {
public:
using size_type = typename Container::size_type;
using value_type = typename Container::value_type;
using pointer = typename std::conditional_t<Const, const value_type*, value_type*>;
using reference = typename std::conditional_t<Const, const value_type&, value_type&>;
using container_iterator =
typename std::conditional_t<Const, typename Container::const_iterator,
typename Container::iterator>;
struct pair {
size_type pos;
reference ref;
};
iterator(container_iterator iterator);
auto operator!=(const iterator& other) -> bool;
auto operator++() -> iterator&;
auto operator*() const -> pair;
private:
container_iterator it;
size_type pos = 0;
};
using container_reference = Container&;
explicit enumerate_range(container_reference container);
auto begin() -> iterator;
auto end() -> iterator;
private:
container_reference container;
};
template <class Container>
auto enumerate(Container& container) -> enumerate_range<Container> {
return enumerate_range<Container>(container);
}
template <class Container>
enumerate_range<Container>::enumerate_range(container_reference container) : container(container) {}
template <class Container>
auto enumerate_range<Container>::begin() -> iterator {
return iterator(container.begin());
}
template <class Container>
auto enumerate_range<Container>::end() -> iterator {
return iterator(container.end());
}
template <class Container>
enumerate_range<Container>::iterator::iterator(container_iterator iterator)
: it(iterator), pos(0) {}
template <class Container>
auto enumerate_range<Container>::iterator::operator!=(const iterator& other) -> bool {
return it != other.it;
}
template <class Container>
auto enumerate_range<Container>::iterator::operator++() -> iterator& {
it++;
pos++;
return *this;
}
template <class Container>
auto enumerate_range<Container>::iterator::operator*() const -> pair {
return pair{pos, *it};
}
} // namespace util
#endif // THAT_THIS_UTIL_DATA_ENUMERATE_HEADER_IS_ALREADY_INCLUDED