Collection of C++ snippets
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

97 lines
2.5 KiB

/*
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);
}