template<typename E, E f, E...>
struct First
{
static const E value = f;
};
template<typename E, E first, E head, E...>
struct Advance
{
static void adv(E& v)
{
if(v == head)
v = first;
}
};
template<typename E, E first, E head, E next, E... tail>
struct Advance<E,first,head,next,tail...>
{
static void adv(E& v)
{
if(v == head)
v = next;
else
Advance<E,first,next,tail...>::adv(v);
}
};
template<typename E, E... values>
struct EnumValues
{
static void advance(E& v)
{
Advance<E, First<E, values...>::value, values...>::adv(v);
}
};
/// Test enum
enum class Fruit
{
apple,
banana,
orange,
pineapple,
lemon
};
/// Scalable way, C++11-ish
typedef EnumValues<Fruit,
Fruit::apple,
Fruit::banana,
Fruit::orange,
Fruit::pineapple,
Fruit::lemon
> Fruit_values11;
Fruit& operator++(Fruit& f)
{
Fruit_values11::advance(f);
return f;
}
#include <iostream>
std::ostream& operator<<(std::ostream& os, Fruit f)
{
switch(f)
{
case Fruit::apple: os << "Fruit::apple"; return os;
case Fruit::banana: os << "Fruit::banana"; return os;
case Fruit::orange: os << "Fruit::orange"; return os;
case Fruit::pineapple: os << "Fruit::pineapple"; return os;
case Fruit::lemon: os << "Fruit::lemon"; return os;
}
}
int main()
{
Fruit f = Fruit::banana;
std::cout << "f = " << f << ";\n";
std::cout << "++f = " << ++f << ";\n";
}
ICAgIHRlbXBsYXRlPHR5cGVuYW1lIEUsIEUgZiwgRS4uLj4KICAgIHN0cnVjdCBGaXJzdAogICAgewogICAgICAgIHN0YXRpYyBjb25zdCBFIHZhbHVlID0gZjsKICAgIH07CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEUsIEUgZmlyc3QsIEUgaGVhZCwgRS4uLj4KICAgIHN0cnVjdCBBZHZhbmNlCiAgICB7CiAgICAgICAgc3RhdGljIHZvaWQgYWR2KEUmIHYpCiAgICAgICAgewogICAgICAgICAgICBpZih2ID09IGhlYWQpCiAgICAgICAgICAgICAgICB2ID0gZmlyc3Q7CiAgICAgICAgfQogICAgfTsKICAgIAogICAgdGVtcGxhdGU8dHlwZW5hbWUgRSwgRSBmaXJzdCwgRSBoZWFkLCBFIG5leHQsIEUuLi4gdGFpbD4KICAgIHN0cnVjdCBBZHZhbmNlPEUsZmlyc3QsaGVhZCxuZXh0LHRhaWwuLi4+CiAgICB7CiAgICAgICAgc3RhdGljIHZvaWQgYWR2KEUmIHYpCiAgICAgICAgewogICAgICAgICAgICBpZih2ID09IGhlYWQpCiAgICAgICAgICAgICAgICB2ID0gbmV4dDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgQWR2YW5jZTxFLGZpcnN0LG5leHQsdGFpbC4uLj46OmFkdih2KTsKICAgICAgICB9CiAgICB9OwogICAgCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBFLCBFLi4uIHZhbHVlcz4KICAgIHN0cnVjdCBFbnVtVmFsdWVzCiAgICB7CiAgICAgICAgc3RhdGljIHZvaWQgYWR2YW5jZShFJiB2KQogICAgICAgIHsKICAgICAgICAgICAgQWR2YW5jZTxFLCBGaXJzdDxFLCB2YWx1ZXMuLi4+Ojp2YWx1ZSwgdmFsdWVzLi4uPjo6YWR2KHYpOwogICAgICAgIH0KICAgIH07CiAgICAKICAgIAogICAgLy8vIFRlc3QgZW51bQogICAgZW51bSBjbGFzcyBGcnVpdAogICAgewogICAgICAgIGFwcGxlLAogICAgICAgIGJhbmFuYSwKICAgICAgICBvcmFuZ2UsCiAgICAgICAgcGluZWFwcGxlLAogICAgICAgIGxlbW9uCiAgICB9OwogICAgCiAgICAvLy8gU2NhbGFibGUgd2F5LCBDKysxMS1pc2gKICAgIHR5cGVkZWYgRW51bVZhbHVlczxGcnVpdCwKICAgICAgICAgICAgRnJ1aXQ6OmFwcGxlLAogICAgICAgICAgICBGcnVpdDo6YmFuYW5hLAogICAgICAgICAgICBGcnVpdDo6b3JhbmdlLAogICAgICAgICAgICBGcnVpdDo6cGluZWFwcGxlLAogICAgICAgICAgICBGcnVpdDo6bGVtb24KICAgID4gRnJ1aXRfdmFsdWVzMTE7CgogICAgRnJ1aXQmIG9wZXJhdG9yKysoRnJ1aXQmIGYpCiAgICB7CiAgICAgICAgRnJ1aXRfdmFsdWVzMTE6OmFkdmFuY2UoZik7CiAgICAgICAgcmV0dXJuIGY7CiAgICB9CgogICAgCiAgICAjaW5jbHVkZSA8aW9zdHJlYW0+CiAgICBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvcywgRnJ1aXQgZikKICAgIHsKICAgICAgICBzd2l0Y2goZikKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgRnJ1aXQ6OmFwcGxlOiBvcyA8PCAiRnJ1aXQ6OmFwcGxlIjsgcmV0dXJuIG9zOwogICAgICAgICAgICBjYXNlIEZydWl0OjpiYW5hbmE6IG9zIDw8ICJGcnVpdDo6YmFuYW5hIjsgcmV0dXJuIG9zOwogICAgICAgICAgICBjYXNlIEZydWl0OjpvcmFuZ2U6IG9zIDw8ICJGcnVpdDo6b3JhbmdlIjsgcmV0dXJuIG9zOwogICAgICAgICAgICBjYXNlIEZydWl0OjpwaW5lYXBwbGU6IG9zIDw8ICJGcnVpdDo6cGluZWFwcGxlIjsgcmV0dXJuIG9zOwogICAgICAgICAgICBjYXNlIEZydWl0OjpsZW1vbjogb3MgPDwgIkZydWl0OjpsZW1vbiI7IHJldHVybiBvczsKICAgICAgICB9CiAgICB9CiAgICAKICAgIGludCBtYWluKCkKICAgIHsKICAgICAgICBGcnVpdCBmID0gRnJ1aXQ6OmJhbmFuYTsKICAgICAgICBzdGQ6OmNvdXQgPDwgImYgPSAiIDw8IGYgPDwgIjtcbiI7CiAgICAgICAgc3RkOjpjb3V0IDw8ICIrK2YgPSAiIDw8ICsrZiA8PCAiO1xuIjsKICAgIH0=