Boost logo

Boost :

Subject: Re: [boost] Enum Conversion
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2012-09-02 16:46:21


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?

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).

> (Or
> does boost even offer something like that already?)
I don't think so. The closest could be TBoost.Enums in the sandbox, but
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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk