Boost logo

Boost :

Subject: [boost] [enums] Interest in an alternative emulation of scoped enums classes
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2011-02-27 15:45:51


Hi,

I have been working in an alternative implementation of the Beman's Scoped
enums macros
(http://boost.2283326.n4.nabble.com/template/NamlServlet.jtp?macro=new_topic&node=2600599)
Daniel James proposed.

The macros are very similar

BOOST_ENUM_CLASS_START(algae, uint8) {
  green, red, cyan
} BOOST_ENUM_CLASS_END(algae, uint8)

algae sample( algae::red );
void func(algae);

The major advantages are:

* No need to use a macro to name the type in most of the cases
* The type is not implicitly convertible to the underlying type neither to
bool and so it is closer the intended goal of strongly enums.
* Allows to state explicitly the underlying type

The major liabilities are:

* In some context we can not use the enum class. This is the case of switch
statements and template parameters. In order to get the native enum value a
free function enums::get_value allows to workaround that in a portable way.

    algae v;
    ...
    switch (boost::enums::get_value(v))
    {
    case algae ::green: return("EnumClass::Default");
    case algae ::red: return("EnumClass::Enum1");
    case algae ::cyan :
    }

* the emulation is not an enum, that is is_enum(algae)::value is false

The user can use

  is_enum<enum_type<EC>::type>

or the library could provide an is_enum nested on the enums namespace.

  enums::is_enum<EC>

or we can specialize boost::is_enum<EC>

For template parameters the meta-function enum_type gives the type of the
native enum used by the emulation.

  template <enums::enum_type<algae>::type V>
  struct ex;

* Use in union
The emulation providing constructors (which is optional) can not be used in
unions if the compiler doesn't allows class with constructors in unions.

* default value
There is no portable way to manage with standard *implicit* default values
if the enum class emulation can not define constructors.
I have found an explicit way that allows to assign the default value. Use
default_value<EC>().
This function will be equivalent to EC() if enum class is supported by the
compiler.

    algae e(enums::default_value<algae>());

* Explicit conversion from int
There is no portable way to manage with standard *explicit* conversion of
ints if the enum class emulation can not define constructors. I have found
an explicit way that allows to manage with explicit conversion using a
function convert_to<EC>(v) instead of the Constructor. This function will be
equivalent to EC(v) if enum class is supported

  algae e(convert_to<algae>(1));

There is not too much documentation yet. You can find the code and some test
in the sandbox https://svn.boost.org/svn/boost/sandbox/enums

I could provide alternative macros for users considering a better approach
necessary

* PP Sequence Syntax
BOOST_ENUM_CLASS(EnumClass, Underlying,
     ( (Enum0) (0) )
     ( (Enum1) )
     ( (Enum2) )
   );

PP Variadic Syntax
BOOST_ENUM_CLASS(EnumClass, Underlying,
     (Enum0) (0),
     Enum1,
     Enum2
   );

With the macros the meta-functions and the functions we can write portable
code using strongly scoped enums. Is there any interest for this in Boost?

Comments or suggestions appreciated,
Vicente

P.S. the convert_to function is the one of Boost.Conversion.

-- 
View this message in context: http://boost.2283326.n4.nabble.com/enums-Interest-in-an-alternative-emulation-of-scoped-enums-classes-tp3327113p3327113.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

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