
Le 02/09/12 21:30, Roland Bock a écrit :
Hi,
In a lot of projects in the company I work for we use Ice middleware which allows to define nice interfaces for services. The IDL also allows to define enums, but I cannot set specific values for the enum items. We also need to store some of these values in databases. We use int to represent the enumerations.
Since we might feel the need to add more items to an enum or delete an unused one, we cannot just cast enum to int and vice versa when writing to or reading from the database. We need methods that translate enum to int and back in a stable way that won't change for an individual enum item, even if its position in the enum changes.
I found a way to do this, which provides enum<->int and enum<->string. It is used like this:
typedef enum { Alpha, Beta, Gamma, Delta, Epsilon } Greek;
CREATE_CONVERTER_METHODS(Greek, (Alpha, 5), (Beta, 3), (Gamma, 7), (Delta, 1), (Epsilon, 6));
std::cout << GreekToString(IntToGreek(1)) << std::endl; std::cout << GreekToString(IntToGreek(6)) << std::endl; std::cout << GreekToInt(Alpha) << std::endl; std::cout << GreekToString(Alpha) << std::endl; std::cout << IntToGreek(17) << std::endl;
------
$ ./a.out Delta Epsilon 5 Alpha terminate called after throwing an instance of 'std::invalid_argument' what(): unexpected Greek value
I've had to manage with these kind of problems very often when working with 3pp libraries or 3pp tools.
My questions are:
a) Is this something that might be interesting for others as well?
(Or does boost even offer something like that already?) I don't think so. The closest could be TBoost.Enums in the sandbox, but
I managed defining a specific opaque type, let me say MyGreek, and defining implicit conversions from these types. Your example could be written as std::cout << string(MyGreek(1)) << std::endl; std::cout << string(MyGreek(6)) << std::endl; std::cout << MyGreek(Alpha) << std::endl; std::cout << MyGreek::Alpha << std::endl; // using nested literal std::cout << string(MyGreek(Alpha)) << std::endl; std::cout << string(MyGreek::Alpha) << std::endl; // using nested literal std::cout << MyGreek(17) << std::endl; If think this interface corresponds more to how C++ conversions work (IMO of course). this library generates the enum and don't do the mapping.
b) I'd really like to be able to write this instead:
CREATE_CONVERTER_METHODS(Greek, Alpha = 5, Beta = 3, Gamma = 7, Delta = 1, Epsilon = 6);
Obviously, if I could use the preprocessor to translate
Alpha = 5 -> (Alpha, 5)
I'd be done. But I have no idea how to do that. Any suggestions?
I don't this this is possible with the pre processor. Best, Vicente