Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

EnumSpace

This file enables the use of a utility I like to call "EnumSpace". This utility is enums and namespaces 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:

  1. ENUMSPACE_CREATE
  2. ENUMSPACE_EXTEND
  3. 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:

  1. The name of the EnumSpace you would like to inherit.
  2. 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.

share|improve this question
    
Can you give an example of when this is useful? –  Loki Astari yesterday
    
@LokiAstari Haha... I actually did this mostly out of spite because there are about 7 questions on SO in which people answered to questions along the lines of "Can I inherit enums?" with either "No, you can't" or some verbose monstrosities. Of course, I found those questions because I was looking for this functionality myself. Trying to extend an enum to provide function status as return type (Success, File not found, etc.). –  user2962533 yesterday
    
It'll probably help if I say that the extension was necessary for class inheritance where the more basic classes provide common statuses/error types and as things go lower there are some more specific things. The "deeper" enum values don't need to ride upstream towards the base classes - the extension is simply there to help keep the common types while adding more onto them. –  user2962533 yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.