HOME PROJECTS SOFTWARE HARDWARE OTHER FACTS LINKS

After reading the abstract about a generic wrapper for C enums for boost, I knew I had to start using such concept in my own library ocfc. However the following points were missing in the proposal:

I therefore decided to craft my own version of smart_enum to take account of the above points. The resulting source is available here taken out of ocfc library.

So now how do you use my basic_enum class? Let's start with a simple enum. In your header you declare your enum as follows:

DECLARE_ENUM(my_enum, LEFT = 0, TOP = 2, RIGHT = 3, BOTTOM = 5)

Then in your code implementation you include the following:

IMPLEMENT_ENUM(my_enum, ENUM_ITEM(LEFT) ENUM_ITEM(TOP), ENUM_ITEM(RIGHT), ENUM_ITEM(BOTTOM) )

I know that compared with boost implementation you need to declare AND implement your enum but the benefit outweights this downside. Now here what you can do for instance to initialize a variable of type my_enum.

my_enum __initialize_with_enum = my_enum::BOTTOM; my_enum __initialize_with_string = _T("BOTTOM"); my_enum __initialize_with_integer = 5;

Comparison and increment operators are of course present as you would expect:

my_enum __e; // initialized with first value ++__e; __e--; __e = __e + 2; // an exception will be thrown if enum becomes out of range if (__e == my_enum::LEFT) std_out << _T("__e = ") << __e.str()

As you see from the code above that to get the enum value as a string is as simple as calling str() member function on the enum instance. To iterate over each enum value simply write the following:

for (my_enum::const_iterator __i = my_enum::begin(); __i != my_enum::end(); ++__i) std_out << __i->str() << _T(" = ") << __i->value();

Ok let's now associate an extra value with each enum as in this next example.

template<class _E> struct my_enum_item { // common section for any "enum_item" typedef typename _E::type enum_type; enum_type m_eValue; LPCTSTR m_szValue; inline enum_type value() const NO_THROW { return m_eValue; } inline LPCTSTR str() const NO_THROW { return m_szValue; } // now I will include an action string LPCTSTR m_szAction; inline LPCTSTR action() const NO_THROW { return m_szAction; } }; template<class _C> _C action_to_my_enum(const string& __sAction) { _C __ret; while (__sAction.compare(__ret->action()) != 0) ++__ret; return __ret; } DECLARE_ENUM_EX(my_enum, my_enum_item, GREEN = 0, AMBER, RED)

I've also included a function to convert from an action string to an enum instance to show what can be done. In your source code, the implementation will be as follow:

IMPLEMENT_ENUM(my_enum, ENUM_ITEM(GREEN, _T("go")), ENUM_ITEM(AMBER, _T("slow down")), ENUM_ITEM(RED, _T("stop")), )

Your new enum can be used in the same way as the more simple enum. For instance:

for (my_enum::const_iterator __i = my_enum::begin(); __i != my_enum::end(); ++__i) std_out << _T("when traffic light changes to ") << __i->str() << _T(" you must ") << __i->action();

That's it. If you want to expand the usage of basic_enum look at the flags<> template that I built upon it.