C++: enum range-based for loop

Loop over all the members of an enumeration.

#include <iterator>

// Inspired from http://codereview.stackexchange.com/a/57699

template<typename T, T... args>
struct EnumIterAll
    : public std::iterator<
                            std::input_iterator_tag, // iterator_category
                            T,                       // value_type
                            std::ptrdiff_t,          // difference_type
                            const T*,                // pointer
                            const T&                 // reference
      >
{
    static constexpr T values[] = {args...};
    static constexpr std::size_t size = sizeof...(args);
    int pos;

    // true = beginning
    // false = end
    EnumIterAll(bool isBegin)
        : pos(isBegin ? 0 : size)
    { }

    const T& operator*() const {
        return values[pos];
    }

    EnumIterAll& operator++() {
        ++pos;
        return *this;
    }

    EnumIterAll operator++(int) {
        EnumIterAll r(*this);
        this->operator++();
        return r;
    }

    bool operator==(EnumIterAll const& rhs) {
        return pos == rhs.pos;
    }

    bool operator!=(EnumIterAll const& rhs) {
        return pos != rhs.pos;
    }
};
template<typename T, T... args>
constexpr T EnumIterAll<T, args...>::values[];


template<typename T, T... args>
struct EnumRange
{
    static EnumIterAll<T, args...> begin() {
        return EnumIterAll<T, args...>(true);
    }

    static EnumIterAll<T, args...> end() {
        return EnumIterAll<T, args...>(false);
    }
};

enum class MyEnum { A = 111, B = 222, C = 333 };
using MyEnumIter = EnumIterAll<MyEnum, MyEnum::A, MyEnum::B, MyEnum::C>;
using MyEnumRange = EnumRange<MyEnum, MyEnum::A, MyEnum::B, MyEnum::C>;

#include <iostream>
int main()
{
    // for loop using iterator
    for(MyEnumIter i(true); i != MyEnumIter(false); ++i) {
        std::cout << static_cast<int>(*i) << std::endl;
    }

    // for loop using range
    for(auto e : MyEnumRange()) {
        std::cout << static_cast<int>(e) << std::endl;
    }
}

This is not a perfect solution, because there is not check in MyEnumRange that all members of the enumeration have been listed as template arguments.

In some cases, it can be an advantage, for example if the enumeration contains error-omly members:

enum class MyEnum {
    A = 111,
    B = 222,
    C = 333,
    Undefined
};
using MyEnumValidRange = EnumRange<MyEnum, MyEnum::A, MyEnum::B, MyEnum::C>;

Not enough?

Some crazy template meta-programming is always tempting, but what is even crazier? Stateful template meta-programming!

Maybe something inspired from this: [1], but adapted to enum.