$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Enum Conversion
From: Roland Bock (rbock_at_[hidden])
Date: 2012-09-02 17:06:48
On 2012-09-02 22:17, Lorenzo Caminiti wrote:
> On Sun, Sep 2, 2012 at 12:30 PM, Roland Bock <rbock_at_[hidden]> wrote:
>> 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
>>
>>
>> My questions are:
>>
>> a) Is this something that might be interesting for others as well? (Or
>> does boost even offer something like that already?)
>> 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?
> There's no way you can strip the = symbol with the pp. You can only do:
>
> Alpha = 5 -> (Alpha =, 5)
>
> And that is assuming the number cannot be negative and you don't want
> to use the + sign, otherwise you can only do:
>
> Alpha = -5 -> (Alpha = -, 5)
> Alpha = +5 -> (Alpha = +, 5)
>
> Depending on the code generated by the macro, this *might* be enough:
>
> Alpha = 5 -> (Alpha =, 5)
>
> That is if the name Alpha can always be use in a context where and
> assignment is allowed Alpha =. This includes function parameters with
> defaults, variable declarations, expressions, etc. You could even use
> a type that has an assignment operation from int and returns itself
> when assigned in an expression... For example:
>
> #include <iostream>
>
> struct enum_type
> {
>     public: struct identity {};
>     public: enum_type ( int const& value ) : value_(value) {}
>     public: int operator= ( int const& value ) { return value_ = value; }
>     public: int operator= ( identity const& ) { return value_; }
>     private: int value_;
> };
>
> int main ( void )
> {
>     enum_type Alpha = 5;
>     std::cout << (Alpha = enum_type::identity()) << std::endl;
>     Alpha = 10;
>     std::cout << (Alpha = enum_type::identity()) << std::endl;
>     return 0;
> }
>
> Note that Alpha is always used as "Alpha =". You can look at the code
> generated by your macros, see where you use the token Alpha, and
> (creatively) ask yourself if you can replace that with Alpha =
> everywhere maybe via some specially defined operator=. I used tricks
> like these in Boost.Contract to deal with the = trailing the old-of
> variable names.
>
> HTH,
> --Lorenzo
>
> _______________________________________________
> Unsubscribe & other changes: http://listarchives.boost.org/mailman/listinfo.cgi/boost
Thanks! That gives me something to think about :-)