Reputation: 28241
I have a bunch of enum
types, like this:
enum Color {COLOR_RED = 0, COLOR_GREEN = 1, COLOR_BLUE = 2, COLOR_NUM};
enum Direction {DIRECTION_FORWARD, DIRECTION_BACKWARD, DIRECTION_NUM};
enum Choice {CHOICE_THIS, CHOICE_THAT, CHOICE_NUM}; // i've just made it up
In many places in my code I would like to do a loop over all possible values; I would like it to look like this:
for (Color c = COLOR_RED; c != COLOR_NUM; ++c)
{
...
}
For that, I define operator++
together with Color
:
enum Color {COLOR_RED = 0, COLOR_GREEN = 1, COLOR_BLUE = 2, COLOR_NUM};
inline Color& operator++(Color& c)
{
c = static_cast<Color>(c + 1);
return c;
}
I also define postfix operator++
for people that are used to coding loops with i++
instead of ++i
:
inline Color operator++(Color& c, int)
{
Color r = c;
c = static_cast<Color>(c + 1);
return r;
}
I would like to know how to use templates to have the compiler generate these operators without me having to write too much boring code. I have just found boost::unit_steppable
that supposedly generates the postfix operator++
from the prefix one, but it does only half the work: I still have to provide the prefix operator++
myself.
The following works but is too "powerful" in my opinion:
template <class T> T operator++(T x)
{
return static_cast<T>(x + 1);
}
I would like to have the operators defined only for selected enum
s.
Upvotes: 0
Views: 508
Reputation: 56863
The following should get you started, extend as needed:
#include <type_traits>
enum Foo { RED, GREEN, BLUE, SIZE };
template< typename T > struct my_enum_is_unit_steppable { enum { value = false }; };
// for each type you want the operator(s) to be enabled, do this:
template<> struct my_enum_is_unit_steppable< Foo > { enum { value = true }; };
// protect the operators with enable_if
template< typename T >
typename std::enable_if< my_enum_is_unit_steppable< T >::value, T >::type
operator++( T value )
{
return T( value + 1 );
}
int main()
{
for( Foo foo = RED; foo != SIZE; ++foo ) {}
}
Of course, this uses C++11's std::enable_if
, but Boost has C++03-versions available.
Upvotes: 2