EnumSpace
This file enables the use of a utility I like to call "EnumSpace". This utility is enum
s and namespace
s combined together in order to create an entity that acts like an enum
that is able to inherit and extend an already existing one.
It provides three macros for that purpose:
ENUMSPACE_CREATE
ENUMSPACE_EXTEND
ENUMSPACE_END
ENUMSPACE_CREATE
should be used to create a new, independent EnumSpace
. It receives the name you would like to give your EnumSpace
as an argument.
ENUMSPACE_EXTEND
should be used to extend an already existing EnumSpace
. It receives two arguments:
- The name of the
EnumSpace
you would like to inherit. - The name of the new
EnumSpace
.
ENUMSPACE_END
should be used like a closing bracket to each of the above.
Usage example:
#include ".../enumspace.hpp"
ENUMSPACE_CREATE( First ) ONE ENUMSPACE_END
ENUMSPACE_EXTEND( First, Second ) TWO, THREE, FOUR ENUMSPACE_END
ENUMSPACE_EXTEND( Second, Third ) FIVE, SIX, SEVEN ENUMSPACE_END
ENUMSPACE_EXTEND( Third, Fourth ) EIGHT, NINE, TEN ENUMSPACE_END
int main()
{
std::cout
<< Fourth::ONE
<< Fourth::TWO
<< Fourth::THREE
<< Fourth::FOUR
<< Fourth::FIVE
<< Fourth::SIX
<< Fourth::SEVEN
<< Fourth::EIGHT
<< Fourth::NINE
<< Fourth::TEN;
}
Output:
0 2 3 4 6 7 8 10 11 12
You probably noticed the inconsistency. The ability to stitch EnumSpaces
comes with a price: it is impossible to retain a straight streak of numbers automatically.
[ONE = 0, _last( = 1)]
[_first = _last = 1, 2, 3, 4, _last( = 5)]
[_first = _last = 5, 6, 7, 8, _last( = 9)]
[_first = _last = 9, 10, 11, 12, _last( = 13)]
You CAN manually declare the first element you add to be "first" (-> the previous inherited namespace`s "last"):
ENUMSPACE_CREATE( First ) ONE ENUMSPACE_END
ENUMSPACE_EXTEND( First, Second ) TWO = _first, THREE, FOUR ENUMSPACE_END
ENUMSPACE_EXTEND( Second, Third ) FIVE = _first, SIX, SEVEN ENUMSPACE_END
ENUMSPACE_EXTEND( Third, Fourth ) EIGHT = _first, NINE, TEN ENUMSPACE_END
Which will result in:
[ONE = 0, _last( = 1)] V V V
[_first = _last = 1, |1, 2, 3,| _last( = 4)]
[_first = _last = 4, |4, 5, 6,| _last( = 7)]
[_first = _last = 7, |7, 8, 9,| _last( = 10)]
Or in clear output:
0 1 2 3 4 5 6 7 8 9
Please note that, even though the macro seems to work OK, it relies on behavior I'm not quite sure is defined.
The macro adds a _first
and _last
elements to any EnumSpace
created to facilitate the "stitch" between them.
Now, what would happen when you extend the EnumSpace
more than once? There would be more than one _last
for the new _first
to pick from...
The macro seems to work just fine, and my guess is this happens because whenever the macro asks for the previous EnumSpace
's _last
, it receives the one in the closest scope, which is the latest inherited EnumSpace
's. It's rather ambiguous, however, and your compiler might scream at you. Consider yourself warned.
One last note: You'll probably want to prefix your values with something when using this macro so that you can filter the namespaces names that get inherited along out of auto completion.
#define ENUMSPACE_CREATE(EnumSpaceName) \
namespace EnumSpaceName {\
enum {
#define ENUMSPACE_EXTEND(EnumSpace, NewEnumSpaceName) \
namespace NewEnumSpaceName {\
using namespace EnumSpace;\
enum { _first = EnumSpace::_last,
#define ENUMSPACE_END \
, _last }; }
Will this work? I mean, I tested this. As you can tell by the output provided. But, if something is fundamentally wrong with this, please let me know.