Ich habe vor einiger Zeit einen Enum-Iterator für diese Fälle geschrieben
enum Foo {
A, B, C, Last
};
typedef litb::enum_iterator FooIterator;
int main() {
FooIterator b(A), e;
std::cout << std::distance(b, e) << " Werte:" << std::endl;
std::copy(b, e, std::ostream_iterator(std::cout, "\n"));
while(b != e) doIt(*b++);
}
Wenn Sie interessiert sind, hier ist der Code. Falls Sie möchten, können Sie ihn erweitern, um ein Random-Access-Iterator zu sein, indem Sie +
, <
, []
und ähnliches bereitstellen. Algorithmen wie std::distance
werden Ihnen danken, indem sie für den dann Random-Access-Iterator eine Zeitkomplexität von O(1)
bieten.
#include
namespace litb {
template
struct enum_iterator
: std::iterator {
enum_iterator():c(End) { }
enum_iterator(Enum c):c(c) { }
enum_iterator &operator=(Enum c) {
this->assign(c);
return *this;
}
enum_iterator &operator++() {
this->inc();
return *this;
}
enum_iterator operator++(int) {
enum_iterator cpy(*this);
this->inc();
return cpy;
}
enum_iterator &operator--() {
this->dec();
return *this;
}
enum_iterator operator--(int) {
enum_iterator cpy(*this);
this->dec();
return cpy;
}
Enum operator*() const {
assert(c != End && "nicht dereferenzierbar!");
return c;
}
bool equals(enum_iterator other) const {
return other.c == c;
}
private:
void assign(Enum c) {
assert(c >= Begin && c <= End);
this->c = c;
}
void inc() {
assert(c != End && "Über das Ende hinaus inkrementieren");
c = static_cast(c + 1);
}
void dec() {
assert(c != Begin && "Über den Anfang hinaus dekrementieren");
c = static_cast(c - 1);
}
private:
Enum c;
};
template
bool operator==(enum_iterator e1, enum_iterator e2) {
return e1.equals(e2);
}
template
bool operator!=(enum_iterator e1, enum_iterator e2) {
return !(e1 == e2);
}
} // litb