Feedback on iterating over type-safe enums
        Posted  
        
            by Sumant
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Sumant
        
        
        
        Published on 2010-05-31T17:53:47Z
        Indexed on 
            2010/05/31
            18:13 UTC
        
        
        Read the original article
        Hit count: 421
        
In response to the earlier SO question "Enumerate over an enum in C++", I came up with the following reusable solution that uses type-safe enum idiom. I'm just curious to see the community feedback on my solution. This solution makes use of a static array, which is populated using type-safe enum objects before first use. Iteration over enums is then simply reduced to iteration over the array. I'm aware of the fact that this solution won't work if the enumerators are not strictly increasing.
template<typename def, typename inner = typename def::type>
class safe_enum : public def
{
  typedef typename def::type type;
  inner val;
  static safe_enum array[def::end - def::begin];
  static bool init;
  static void initialize()
  {
    if(!init) // use double checked locking in case of multi-threading.
    {
      unsigned int size = def::end - def::begin;
      for(unsigned int i = 0, j = def::begin; i < size; ++i, ++j)
        array[i] = static_cast<typename def::type>(j);
      init = true;
    }
  }
public:
  safe_enum(type v = def::begin) : val(v) {}
  inner underlying() const { return val; }
  static safe_enum * begin()
  {
    initialize();
    return array;
  }
  static safe_enum * end()
  {
    initialize();
    return array + (def::end - def::begin);
  }
  bool operator == (const safe_enum & s) const { return this->val == s.val; }
  bool operator != (const safe_enum & s) const { return this->val != s.val; }
  bool operator <  (const safe_enum & s) const { return this->val <  s.val; }
  bool operator <= (const safe_enum & s) const { return this->val <= s.val; }
  bool operator >  (const safe_enum & s) const { return this->val >  s.val; }
  bool operator >= (const safe_enum & s) const { return this->val >= s.val; }
};
template <typename def, typename inner>
safe_enum<def, inner> safe_enum<def, inner>::array[def::end - def::begin];
template <typename def, typename inner>
bool safe_enum<def, inner>::init = false;
struct color_def
{
  enum type
  {
      begin, red = begin, green, blue, end
  };
};
typedef safe_enum<color_def> color;
template <class Enum>
void f(Enum e)
{
  std::cout << static_cast<unsigned>(e.underlying()) << std::endl;
}
int main()
{
  std::for_each(color::begin(), color::end(), &f<color>);
  color c = color::red;
}
        © Stack Overflow or respective owner