C++11 initializer lists can be used to initialize vectors and arrays with argument passing to constructors.
I have a piece of code below
I like your problem. Long ago, this kind of thing used to be handled with X macros http://www.drdobbs.com/the-new-c-x-macros/184401387
I'm a c++11 newb, but after some fiddling around I've got some kind of solution (g++ 4.8.4):
enum class Symbols { FOO, BAR, BAZ, First=FOO, Last=BAZ };
I kept your Size() but added some other boilerplate to make the initialization, lower down, easier to read.
template< typename E > constexpr size_t Size() { return (size_t)(E::Last) - (size_t)(E::First) + 1; }
template< typename E > constexpr size_t as_sizet( E s ) { return (size_t)s; }
template< typename E > constexpr E operator++( E& s, int ) { return (E)(1 + (size_t)s); }
template< typename E > constexpr bool operator<=( E& a, E& b ) { return (size_t)a < (size_t)b; }
There are two bits of magic here:
Like so:
template< typename E, typename EARR >
constexpr EARR& init_array( EARR& zArr, E sym = E::First, E junk = E::Last )
{
return sym <= E::Last ? init_array( zArr, sym++, zArr[ as_sizet( sym ) ] = sym ) : zArr;
}
In the end, it comes together with:
Like so:
typedef Symbols SymbolArr[ Size() ];
static SymbolArr symbolArr;
SymbolArr& symbolArrRef = init_array(symbolArr);
Edit:
The junk parameter in the recursive initialization function can be removed using:
template< typename E > constexpr E next( E& s ) { return (E)(1 + (size_t)s); }
template< typename E, typename EARR >
constexpr EARR& init_array( EARR& zArr, E sym = E::First )
{
return sym <= E::Last ? init_array( zArr, next( zArr[ as_sizet( sym ) ] = sym ) ) : zArr;
}