The Artima Developer Community
Sponsored Link

Heron-Centric: Ruminations of a Language Designer
Typesafe Enums in C++
by Christopher Diggins
June 17, 2005
Summary
Recently Maksym Motornyy proposed on the Boost mailing list, a macro library for typesafe enums. This is not the first time someone has suggested macros for enhancing macros. I wish to demonstrate that you don't have to resort to macros for typesafe enums.

Advertisement

C++ enums are well-known to be not-typesafe. They look like type declarations, but are in fact simply integer constants. Their existance in C++ is vestigial, and they should not be used. On the other hand true enumerated types are themselves very useful. Here is a technique for implementing true enumerations in C++:

template<typename T, int N>
struct enumerator {
  const static int value = N;
  typedef enumerator<T, N + 1> next;
};

struct weekday
{
  // self typedef
  typedef weekday self;

  // 'ctors
  template<int N>
  weekday(const enumerator<self, N>& x) : value(N) { }
  weekday(const self& x) : value(x.value) { }

  // enumerations
  typedef enumerator<self, 0> mon;
  typedef mon::next tue;
  typedef tue::next wed;
  typedef wed::next thu;
  typedef thu::next fri;
  typedef fri::next sat;
  typedef sat::next sun;
  typedef sun::next end_day;

  // operators
  self& operator++(int) { ++value; return *this; }
  self& operator--(int) { --value; return *this; }
  self operator++() { self tmp = *this; ++value; return tmp; }
  self operator--() { self tmp = *this; --value; return tmp; }
  friend bool operator==(const weekday& x, const weekday& y) { return x.value == y.value; }
  friend bool operator!=(const weekday& x, const weekday& y) { return x.value != y.value; }
  operator int() const { return value; }

  // static functions
  static mon begin() { return mon(); }
  static end_day end() { return end_day(); }

  // fields
  int value;
};

void weekday_reaction(const weekday& x) {
  switch (x)
  {
    case (weekday::mon::value) :
      std::cout << "doh! monday" << std::endl;
      break;
    case (weekday::tue::value) :
      std::cout << "doh! tuesday" << std::endl;
      break;
    case (weekday::wed::value) :
      std::cout << "doh! hump-day" << std::endl;
      break;
    case (weekday::thu::value) :
      std::cout << "woohoo! day before friday" << std::endl;
      break;
    case (weekday::fri::value) :
      std::cout << "woohoo! friday" << std::endl;
      break;
    case (weekday::sat::value) :
      std::cout << "woohoo! saturday" << std::endl;
      break;
    case (weekday::sun::value) :
      std::cout << "doh! church!" << std::endl;
      break;
    default:
      std::cout << "whatcha talkin' 'bout willis?" << std::endl;
      break;
  }
}


int main()
{
  weekday_reaction(weekday::sat());
  // weekday_reaction(42); does not compile
  weekday_reaction(weekday::end());

  for (weekday wd = weekday::begin(); wd != weekday::end(); wd++) {
    weekday_reaction(wd);
  }

  system("pause");
  return 0;
}

Talk Back!

Have an opinion? Readers have already posted 7 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Christopher Diggins adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O'Reilly. Christopher can be reached through his home page at www.cdiggins.com.

This weblog entry is Copyright © 2005 Christopher Diggins. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us