Mi 25 Januar 2017
By vjp
In other .
tags: cpp
Loop over all the members of an enumeration.
#include <iterator>
// Inspired from http://codereview.stackexchange.com/a/57699
template < typename T , T ... args >
struct EnumIterAll
: public std :: iterator <
std :: input_iterator_tag , // iterator_category
T , // value_type
std :: ptrdiff_t , // difference_type
const T * , // pointer
const T & // reference
>
{
static constexpr T values [] = { args ...};
static constexpr std :: size_t size = sizeof ...( args );
int pos ;
// true = beginning
// false = end
EnumIterAll ( bool isBegin )
: pos ( isBegin ? 0 : size )
{ }
const T & operator * () const {
return values [ pos ];
}
EnumIterAll & operator ++ () {
++ pos ;
return * this ;
}
EnumIterAll operator ++ ( int ) {
EnumIterAll r ( * this );
this -> operator ++ ();
return r ;
}
bool operator == ( EnumIterAll const & rhs ) {
return pos == rhs . pos ;
}
bool operator != ( EnumIterAll const & rhs ) {
return pos != rhs . pos ;
}
};
template < typename T , T ... args >
constexpr T EnumIterAll < T , args ... >:: values [];
template < typename T , T ... args >
struct EnumRange
{
static EnumIterAll < T , args ... > begin () {
return EnumIterAll < T , args ... > ( true );
}
static EnumIterAll < T , args ... > end () {
return EnumIterAll < T , args ... > ( false );
}
};
enum class MyEnum { A = 111 , B = 222 , C = 333 };
using MyEnumIter = EnumIterAll < MyEnum , MyEnum :: A , MyEnum :: B , MyEnum :: C > ;
using MyEnumRange = EnumRange < MyEnum , MyEnum :: A , MyEnum :: B , MyEnum :: C > ;
#include <iostream>
int main ()
{
// for loop using iterator
for ( MyEnumIter i ( true ); i != MyEnumIter ( false ); ++ i ) {
std :: cout << static_cast < int > ( * i ) << std :: endl ;
}
// for loop using range
for ( auto e : MyEnumRange ()) {
std :: cout << static_cast < int > ( e ) << std :: endl ;
}
}
This is not a perfect solution, because there is not check in MyEnumRange that all members of the enumeration have been listed as template arguments.
In some cases, it can be an advantage, for example if the enumeration contains error-omly members:
enum class MyEnum {
A = 111 ,
B = 222 ,
C = 333 ,
Undefined
};
using MyEnumValidRange = EnumRange < MyEnum , MyEnum :: A , MyEnum :: B , MyEnum :: C > ;
Not enough?
Some crazy template meta-programming is always tempting, but what is even crazier? Stateful template meta-programming !
Maybe something inspired from this: , but adapted to enum .
References
This blog is about building a hardware and software platform based on the Xilinx Spartan-6 LX9
to demonstrate FPGA live reconfiguration , i.e., changing the FPGA configuration while the FPGA is "running". The goal is to implement self-adapting configurations (e.g., softcore) able to balance silicon usage according to the current task at runtime.
Static pages generated by Pelican , comments system by Isso , and hosted on a Raspberry Pi .
If you want to write me, vjp at gmx dot fr. Atom and RSS feeds.