tags:

views:

362

answers:

2

Ideally I would like a following examples to work, but I guess some of it is not implementable in C++.

{
  typedef StrongEnum<Red=0, Green=1, Blue=2> Color; // not a C++ syntax
  Color c = Color::Red;  // static const 
  Color d;  //error: default constructor is private 
  Color d = c;
  Color e = Color::OfInt(5); // ifdef DEBUG - Runtime error: Enum out of range 

  int sum = 0;

  // I do have these macros, but separate for each enum - FOREACH_COLOR(c)
  FOREACH_ENUM (Color c) { 
    sum += c.ToInt ();
  }

  ArrayMap<Color, string> map;  // Internally this is const size array, possible
  map [Color::Red] = "red";     // because Color have static const Limit = 3 inisde. 

  // Advanced: EnumPair does bitpacking.
  // currently I implement it manually for every pair of Enum's I need.
  typedef EnumPair <door=Color, window=Color> ColorPair; // I guess I can't get this, can I?
  ColorPair pair (door = Color::Red, window = Color::Green); // I guess I can't give the labels here or one line above, can I?
  Color w = pair.window;
  Color w = pair.window ();
}

I use them a lot and currently I I write each one from the scratch. I am aware that a complete generic solution is a dream, so I welcome any partial solutions. Maybe somebody created a library or a code generator?

Update 1:

This and this questions are related. I'm investigating which issues can be solved with them.

A: 

I also loathe the actual implementation of enums in C++.

  • Automatic conversions to integral types
  • No value checking: a loose range checking is performed to see if the value fit in the integral type chosen to store it
  • Serialization: serialized as int is painful > you have to keep old values even if not used any longer and you have to add new values at the end only
  • No iteration possible, you need to redefine the operators

I ended up rolling my own template to try and automate, but it's not completely satisfying at the moment (especially because it requires template specialization for each enum, and so cannot be used for enums nested in a class / struct :/)

Anyway, the idea I used was:

  • A static map to store the values and their 'serialization value' (which in my case is a simple string because I don't value space so much and prefer readability)
  • A class to wrap, which simply holds an iterator in the map, 'end' representing a not-initialized/invalid value.

For the moment I used the 'true' enum, but from what you said I might think of having static instances... though it puts yet another burden on the enum writer...

Matthieu M.
+1  A: 

This is what I figured out:

#include <cstdio>
#include <string>
#include <map>

namespace Color
{
    typedef enum
    {
     Red = 0,
     Green = 1,
     Blue = 2
    } Color;

    Color colors[] = {Red, Green, Blue}; // same order as above,
                             //to preserve index.

    //int colors_len = sizeof(colors)/sizeof(Color);
    // (if you want to check for valid values)

    static inline Color OfInt(int value)
    {
     // if(value >= colors_len) do error thing;
     return colors[value];
    }
}

int main()
{
    Color::Color c = Color::Red;

    printf("%d,", c);

    c = Color::OfInt(1);

    printf("%d,", c);

    c = Color::Blue;

    printf("%d\n", c);

    std::map<Color::Color, std::string> map;

    map[Color::Red] = "red";

    return 0;
}

Atleast it has some of the behaviour you wanted. Does this lack something that you need?

It compiles with g++ 4.3.3, and seems to work ok.

I did the namespace thing to put the enums under a different scope. (so that Red's not taken etc.) Maybe you can dissect it into something you could use? :)

If you want Color::Color outside that namespace, you could do:

typedef Color::Color ColorEnum;

But the name Color is unfortunately occupied by the namespace.

pbos
I think he wants something that can automate this process (ex: for color, seasons, etc).
n1ck
I haven't used macros in a way that could expand to that. I'd go with using the solution above, writing them manually.If he needed to he could write a script in python or something that would create that file quickly, but I'm not sure if that's worth it.
pbos