first draft of counting range-based-for-loops
This commit is contained in:
parent
e2b1eebe46
commit
39318cf12b
2 changed files with 118 additions and 0 deletions
97
iterators/counting_iterator.hpp
Normal file
97
iterators/counting_iterator.hpp
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
"for(auto x : counted(v)) { ... x.value ... x.index ... }"
|
||||||
|
x.value is a reference to the element in the container (so you can change it's value), x.index is what it is.
|
||||||
|
Container should havae forward iterators.
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
This headers is purely a handy tool for the "for(auto x : counter(v))"-syntax. Using it explicitly with iterators is not recommended!
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
There is no const version of it. Doing "for(const auto x : counted(v))" doesn't make it impossible to change x (so the element in the container can be modified).
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
// A reference is a struct, yuk...
|
||||||
|
// Maybe a proxy is better
|
||||||
|
template <typename T, typename Integer>
|
||||||
|
struct counting_pair{
|
||||||
|
private:
|
||||||
|
typedef counting_pair self;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T& value;
|
||||||
|
Integer index;
|
||||||
|
|
||||||
|
counting_pair(T& v, Integer i) : value(v), index(i) {}
|
||||||
|
counting_pair(const self& copy) : value(copy.value), index(copy.index) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// It's only forward for the moment
|
||||||
|
template <typename Iterator, typename Integer>
|
||||||
|
struct counting_iterator : public std::iterator<std::forward_iterator_tag, counting_pair<typename std::iterator_traits<Iterator>::value_type, Integer>> {
|
||||||
|
private:
|
||||||
|
typedef counting_iterator self;
|
||||||
|
typedef counting_pair<typename std::iterator_traits<Iterator>::value_type, Integer> value_type;
|
||||||
|
|
||||||
|
Iterator it;
|
||||||
|
Integer count;
|
||||||
|
|
||||||
|
public:
|
||||||
|
counting_iterator(Iterator it) : it(it), count(0) {}
|
||||||
|
counting_iterator(const self& copy) : it(copy.it), count(copy.count) {}
|
||||||
|
|
||||||
|
self& operator++(){
|
||||||
|
++it;
|
||||||
|
++count;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
self operator++(int){
|
||||||
|
self copy(*this);
|
||||||
|
++*this;
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const self& rhs){
|
||||||
|
return it == rhs.it;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const self& rhs){
|
||||||
|
return it != rhs.it;
|
||||||
|
}
|
||||||
|
|
||||||
|
typename self::value_type operator*() {
|
||||||
|
return counting_pair<typename std::iterator_traits<Iterator>::value_type, Integer>(*it, count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Container, typename Integer>
|
||||||
|
struct counting_container {
|
||||||
|
private:
|
||||||
|
typedef counting_container self;
|
||||||
|
typedef typename Container::iterator backing_iterator;
|
||||||
|
Container* backing_container;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef counting_iterator<backing_iterator, Integer> iterator;
|
||||||
|
|
||||||
|
counting_container(Container& v) : backing_container(std::addressof(v)) {}
|
||||||
|
counting_container(const self& x) : backing_container(x.backing_container) {}
|
||||||
|
|
||||||
|
iterator begin() {
|
||||||
|
return iterator(backing_container->begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() {
|
||||||
|
return iterator(backing_container->end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Integer = int, typename Container>
|
||||||
|
counting_container<Container, Integer> counted(Container& c){
|
||||||
|
return counting_container<Container, Integer>(c);
|
||||||
|
}
|
||||||
|
|
21
iterators/main.cpp
Normal file
21
iterators/main.cpp
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#include "counting_iterator.hpp"
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
std::vector<int> v{1,3,37,1337,7};
|
||||||
|
|
||||||
|
for(auto x : counted(v)){
|
||||||
|
std::cout << "v[" << x.index << "] = " << x.value << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto x : counted(v)){
|
||||||
|
x.value *= x.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto x : counted(v)){
|
||||||
|
std::cout << "v[" << x.index << "] = " << x.value << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in a new issue