エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

スマート列挙型その2

template<typename T, int N>
struct In
{
    static inline bool eval(T value, const T* values)
    {
        return (value == *values) || In<T, N - 1>::eval(value, values + 1);
    }
};

template<typename T>
struct In<T, 1>
{
    static inline bool eval(T value, const T* values)
    {
        return (value == *values);
    }
};

template<typename T>
class EnumValue
{
public:
    EnumValue(T value) : value_(value) {}
    template<int N>
    inline bool in(const T (&values)[N]) const
    {
        return In<T, N>::eval(value_, values);
    }
private:
    const T value_;
};

template<typename T>
EnumValue<T> enumValue(T value)
{
    return EnumValue<T>(value);
}

enum Kanto { Chiba, Gunma, Ibaraki, Kanagawa, 
                       Saitama, Tochigi, Tokyo };

void hantei(Kanto k)
{
    static const Kanto kita[]   = { Gunma, Ibaraki, Tochigi };
    static const Kanto minami[] = { Chiba, Kanagawa, Saitama, Tokyo };
    if(enumValue(k).in(kita))
    {
        std::cout << "北関東" << std::endl;
    }
    else if(enumValue(k).in(minami))
    {
        std::cout << "南関東" << std::endl;
    }
    else
    {
        std::cout << "どこだ?" << std::endl;
    }
}

配列を取るようにしてみました。In::evalが今ひとつ不格好な感じ。