
    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";
    }