Firstly thanks to Noah Roberts' answer which deserves as an upvote for being the inspiration to this answer.
Following on from his answer I extracted and refactored boost::mpl::for_each
and boost::mpl::range
to obtain what I believe is the minimal complete definition which satisfies the question's criteria. It has no longer has any dependancy on Boost and is used as such:
struct eat_fruit; // As Noah's answer
void eatAllFruit()
{
EnumIteration< Fruits, eApple, eTotal >::for_each( eat_fruit() );
}
My EnumIteration
struct is defined as below, and I welcome any comments or improvements. The only notable difference to the Boost version is that the range excludes the final enum value (i.e. eTotal
), unlike boost::mpl::range
which includes it.
template< typename ENUM, ENUM BEGIN, ENUM END >
struct EnumIteration
{
private:
template< ENUM N >
struct Iterator
{
static const ENUM value = N;
typedef Iterator< static_cast< ENUM >( N+1 ) > next;
operator ENUM() const { return static_cast< ENUM >( this->value ); }
};
template< typename T >
struct End
{ enum { value = false }; };
template<>
struct End< Iterator< END > >
{ enum { value = true }; };
template< bool done = true >
struct for_each_impl
{
template< typename Iterator, typename F >
static void execute( Iterator*, F ) {}
};
template<>
struct for_each_impl<false>
{
template< typename Iterator, typename F >
static void execute( Iterator*, F f )
{
f( typename Iterator() );
typedef typename Iterator::next next;
for_each_impl< End< next >::value >::execute( static_cast< next * >( 0 ), f );
}
};
public:
template< typename F >
static void for_each( F f )
{
typedef Iterator< BEGIN > first;
for_each_impl< End< first >::value >::execute( static_cast< first * >( 0 ), f );
}
};