template<typename E, E first, E head>
void advanceEnum(E& v)
{
if(v == head)
v = first;
}
template<typename E, E first, E head, E next, E... tail>
void advanceEnum(E& v)
{
if(v == head)
v = next;
else
advanceEnum<E,first,next,tail...>(v);
}
template<typename E, E first, E... values>
struct EnumValues
{
static void advance(E& v)
{
advanceEnum<E, first, first, values...>(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";
std::cout << "++f = " << ++f << ";\n";
std::cout << "++f = " << ++f << ";\n";
std::cout << "++f = " << ++f << ";\n";
std::cout << "++f = " << ++f << ";\n";
}
CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBFLCBFIGZpcnN0LCBFIGhlYWQ+CiAgICB2b2lkIGFkdmFuY2VFbnVtKEUmIHYpCiAgICB7CiAgICAgICAgaWYodiA9PSBoZWFkKQogICAgICAgICAgICB2ID0gZmlyc3Q7CiAgICB9CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgRSwgRSBmaXJzdCwgRSBoZWFkLCBFIG5leHQsIEUuLi4gdGFpbD4KICAgIHZvaWQgYWR2YW5jZUVudW0oRSYgdikKICAgIHsKICAgICAgICBpZih2ID09IGhlYWQpCiAgICAgICAgICAgIHYgPSBuZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgYWR2YW5jZUVudW08RSxmaXJzdCxuZXh0LHRhaWwuLi4+KHYpOwogICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEUsIEUgZmlyc3QsIEUuLi4gdmFsdWVzPgogICAgc3RydWN0IEVudW1WYWx1ZXMKICAgIHsKICAgICAgICBzdGF0aWMgdm9pZCBhZHZhbmNlKEUmIHYpCiAgICAgICAgewogICAgICAgICAgICBhZHZhbmNlRW51bTxFLCBmaXJzdCwgZmlyc3QsIHZhbHVlcy4uLj4odik7CiAgICAgICAgfQogICAgfTsKCgoKICAgIC8vLyBUZXN0IGVudW0KICAgIGVudW0gY2xhc3MgRnJ1aXQKICAgIHsKICAgICAgICBhcHBsZSwKICAgICAgICBiYW5hbmEsCiAgICAgICAgb3JhbmdlLAogICAgICAgIHBpbmVhcHBsZSwKICAgICAgICBsZW1vbgogICAgfTsKCgoKICAgIC8vLyBTY2FsYWJsZSB3YXksIEMrKzExLWlzaAogICAgdHlwZWRlZiBFbnVtVmFsdWVzPEZydWl0LAogICAgICAgICAgICBGcnVpdDo6YXBwbGUsCiAgICAgICAgICAgIEZydWl0OjpiYW5hbmEsCiAgICAgICAgICAgIEZydWl0OjpvcmFuZ2UsCiAgICAgICAgICAgIEZydWl0OjpwaW5lYXBwbGUsCiAgICAgICAgICAgIEZydWl0OjpsZW1vbgogICAgPiBGcnVpdF92YWx1ZXMxMTsKICAgIAogICAgRnJ1aXQmIG9wZXJhdG9yKysoRnJ1aXQmIGYpCiAgICB7CiAgICAgICAgRnJ1aXRfdmFsdWVzMTE6OmFkdmFuY2UoZik7CiAgICAgICAgcmV0dXJuIGY7CiAgICB9CgoKICAgICNpbmNsdWRlIDxpb3N0cmVhbT4KICAgIHN0ZDo6b3N0cmVhbSYgb3BlcmF0b3I8PChzdGQ6Om9zdHJlYW0mIG9zLCBGcnVpdCBmKQogICAgewogICAgICAgIHN3aXRjaChmKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBGcnVpdDo6YXBwbGU6IG9zIDw8ICJGcnVpdDo6YXBwbGUiOyByZXR1cm4gb3M7CiAgICAgICAgICAgIGNhc2UgRnJ1aXQ6OmJhbmFuYTogb3MgPDwgIkZydWl0OjpiYW5hbmEiOyByZXR1cm4gb3M7CiAgICAgICAgICAgIGNhc2UgRnJ1aXQ6Om9yYW5nZTogb3MgPDwgIkZydWl0OjpvcmFuZ2UiOyByZXR1cm4gb3M7CiAgICAgICAgICAgIGNhc2UgRnJ1aXQ6OnBpbmVhcHBsZTogb3MgPDwgIkZydWl0OjpwaW5lYXBwbGUiOyByZXR1cm4gb3M7CiAgICAgICAgICAgIGNhc2UgRnJ1aXQ6OmxlbW9uOiBvcyA8PCAiRnJ1aXQ6OmxlbW9uIjsgcmV0dXJuIG9zOwogICAgICAgIH0KICAgIH0KICAgIAogICAgaW50IG1haW4oKQogICAgewogICAgICAgIEZydWl0IGYgPSBGcnVpdDo6YmFuYW5hOwogICAgICAgIHN0ZDo6Y291dCA8PCAiZiA9ICIgPDwgZiA8PCAiO1xuIjsKICAgICAgICBzdGQ6OmNvdXQgPDwgIisrZiA9ICIgPDwgKytmIDw8ICI7XG4iOwogICAgICAgIHN0ZDo6Y291dCA8PCAiKytmID0gIiA8PCArK2YgPDwgIjtcbiI7CiAgICAgICAgc3RkOjpjb3V0IDw8ICIrK2YgPSAiIDw8ICsrZiA8PCAiO1xuIjsKICAgICAgICBzdGQ6OmNvdXQgPDwgIisrZiA9ICIgPDwgKytmIDw8ICI7XG4iOwogICAgICAgIHN0ZDo6Y291dCA8PCAiKytmID0gIiA8PCArK2YgPDwgIjtcbiI7CiAgICB9