[C++0x] Emulation of scoped enums

classic Classic list List threaded Threaded
28 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[C++0x] Emulation of scoped enums

Beman Dawes
The improved type safety of the C++0x scoped enum feature is attractive,
so I'd like to start using it as it becomes available in compilers.

See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf 
for a description. Note that the committee changed the name from
strongly typed enums to scoped enums.

See the attached for a boost/detail header that provides macro wrappers
that use scoped enums if available, otherwise fall back on C++03
namespaces and unscoped enums. It lets a library write:

   BOOST_SCOPED_ENUM_START(algae) { green, red, cyan };
     BOOST_SCOPED_ENUM_END
   ...
   BOOST_SCOPED_ENUM(algae) sample( algae::red );
   void func(BOOST_SCOPED_ENUM(algae));

and then a user can write:

   sample = algae::green;
   func( algae::cyan );

Comments or suggestions appreciated,

--Beman


//  scoped_enum_emulation.hpp  ---------------------------------------------------------//

//  Copyright Beman Dawes, 2009

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

//  Generates C++0x scoped enums if the feature is present, otherwise emulates C++0x
//  scoped enums with C++03 namespaces and enums. The Boost.Config BOOST_NO_SCOPED_ENUMS
//  macro is used to detect feature support.
//
//  Caution: only the syntax is emulated; the semantics are not emulated and
//  the syntax emulation doesn't include being able to specify the underlying type.
//
//  See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf for a
//  description of the feature. Note that the committee changed the name from
//  strongly typed enums to scoped enums.  
//
//  Sample usage:
//
//     BOOST_SCOPED_ENUM_START(algae) { green, red, cyan }; BOOST_SCOPED_ENUM_END
//     ...
//     BOOST_SCOPED_ENUM(algae) sample( algae::red );
//     void foo( BOOST_SCOPED_ENUM(algae) color );
//     ...
//     sample = algae::green;
//     foo( algae::cyan );

#ifndef BOOST_SCOPED_ENUM_EMULATION_HPP
#define BOOST_SCOPED_ENUM_EMULATION_HPP

#include <boost/config.hpp>

#ifndef BOOST_NO_SCOPED_ENUMS

# define BOOST_SCOPED_ENUM_START(name) enum class name
# define BOOST_SCOPED_ENUM_END
# define BOOST_SCOPED_ENUM(name) name

#else

# define BOOST_SCOPED_ENUM_START(name) namespace name { enum enum_t
# define BOOST_SCOPED_ENUM_END }
# define BOOST_SCOPED_ENUM(name) name::enum_t

#endif

#endif  // BOOST_SCOPED_ENUM_EMULATION_HPP

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Kjell Elster

I like it, iff you change the implementation from

#ifndef BOOST_NO_SCOPED_ENUMS
...

to

#ifdef BOOST_NO_SCOPED_ENUMS

I do have a hard time with double negations.

Kjell E

> Date: Thu, 5 Mar 2009 10:37:12 -0500
> From: [hidden email]
> To: [hidden email]
> Subject: [boost] [C++0x] Emulation of scoped enums
>
> The improved type safety of the C++0x scoped enum feature is attractive,
> so I'd like to start using it as it becomes available in compilers.
>
> See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf 
> for a description. Note that the committee changed the name from
> strongly typed enums to scoped enums.
>
> See the attached for a boost/detail header that provides macro wrappers
> that use scoped enums if available, otherwise fall back on C++03
> namespaces and unscoped enums. It lets a library write:
>
>    BOOST_SCOPED_ENUM_START(algae) { green, red, cyan };
>      BOOST_SCOPED_ENUM_END
>    ...
>    BOOST_SCOPED_ENUM(algae) sample( algae::red );
>    void func(BOOST_SCOPED_ENUM(algae));
>
> and then a user can write:
>
>    sample = algae::green;
>    func( algae::cyan );
>
> Comments or suggestions appreciated,
>
> --Beman
>

_________________________________________________________________
Dela foton på ett smidigt sätt med Windows Live™ Photos.
http://www.microsoft.com/windows/windowslive/products/photos.aspx
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Phil Endecott-48
In reply to this post by Beman Dawes
Beman Dawes wrote:

> The improved type safety of the C++0x scoped enum feature is attractive,
> so I'd like to start using it as it becomes available in compilers.
>
> See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf 
> for a description. Note that the committee changed the name from
> strongly typed enums to scoped enums.
>
> See the attached for a boost/detail header that provides macro wrappers
> that use scoped enums if available, otherwise fall back on C++03
> namespaces and unscoped enums. It lets a library write:
>
>    BOOST_SCOPED_ENUM_START(algae) { green, red, cyan };
>      BOOST_SCOPED_ENUM_END
>    ...
>    BOOST_SCOPED_ENUM(algae) sample( algae::red );
>    void func(BOOST_SCOPED_ENUM(algae));
>
> and then a user can write:
>
>    sample = algae::green;
>    func( algae::cyan );

Good plan.  Thoughts:

- No need to make it a ::detail!

- The user needs to spell out the macro if they declare a variable; can
this be avoided?

- How about avoiding the _START/_END stuff with e.g.
   BOOST_SCOPED_ENUM_DECL(algae, green,red,cyan);
   (I had been under the impression that varargs macros were a gcc-ism,
but I've recently discovered that they're in c99; do non-gcc C++
compilers generally allow them?  I don't think we can get away with
allowing only up-to-N elements in this case.)

- I agree with Kjell about the double negative :-)


Phil.




_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Joel Falcou-2
Phil Endecott a écrit :
> - How about avoiding the _START/_END stuff with e.g.
>   BOOST_SCOPED_ENUM_DECL(algae, green,red,cyan);
>   (I had been under the impression that varargs macros were a gcc-ism,
> but I've recently discovered that they're in c99; do non-gcc C++
> compilers generally allow them?  I don't think we can get away with
> allowing only up-to-N elements in this case.)
>
Evenif variadic macro is not supported, Boost::Preprocessor sequence can :

BOOST_SCOPED_ENUM_DECL(algae, (green)(red)(cyan) );

or Boost::Preprocessor array

BOOST_SCOPED_ENUM_DECL(algae, (3,(green,red,cyan) );

--
___________________________________________
Joel Falcou - Assistant Professor
PARALL Team - LRI - Universite Paris Sud XI
Tel : (+33)1 69 15 66 35


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Beman Dawes
In reply to this post by Kjell Elster
On Thu, Mar 5, 2009 at 10:45 AM, Kjell Elster <[hidden email]> wrote:

>
> I like it, iff you change the implementation from
>
> #ifndef BOOST_NO_SCOPED_ENUMS
> ...
>
> to
>
> #ifdef BOOST_NO_SCOPED_ENUMS
>
> I do have a hard time with double negations.

Point take. Will change.

Thanks,

--Beman
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Beman Dawes
In reply to this post by Phil Endecott-48
On Thu, Mar 5, 2009 at 12:15 PM, Phil Endecott
<[hidden email]> wrote:

> Good plan.  Thoughts:
>
> - No need to make it a ::detail!
>
> - The user needs to spell out the macro if they declare a variable; can this
> be avoided?
>
> - How about avoiding the _START/_END stuff with e.g.
>  BOOST_SCOPED_ENUM_DECL(algae, green,red,cyan);
>  (I had been under the impression that varargs macros were a gcc-ism, but
> I've recently discovered that they're in c99; do non-gcc C++ compilers
> generally allow them?  I don't think we can get away with allowing only
> up-to-N elements in this case.)

Hum... I hadn't considered varargs macros. If I even knew they existed:-)

Let me try that on some non-gcc compilers. I'll report back.

Thanks,

--Beman
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Mathias Gaunard-2
In reply to this post by Phil Endecott-48
Phil Endecott wrote:

> - The user needs to spell out the macro if they declare a variable; can
> this be avoided?

I believe that if you use scoped enums, algae will be the name of the
enum, otherwise algae is going to be the name of the namespace the num
is in.
Which is why the macro is required.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Beman Dawes
In reply to this post by Beman Dawes
On Thu, Mar 5, 2009 at 12:44 PM, Beman Dawes <[hidden email]> wrote:

> On Thu, Mar 5, 2009 at 12:15 PM, Phil Endecott
>> - How about avoiding the _START/_END stuff with e.g.
>>  BOOST_SCOPED_ENUM_DECL(algae, green,red,cyan);
>>  (I had been under the impression that varargs macros were a gcc-ism, but
>> I've recently discovered that they're in c99; do non-gcc C++ compilers
>> generally allow them?  I don't think we can get away with allowing only
>> up-to-N elements in this case.)
>
> Hum... I hadn't considered varargs macros. If I even knew they existed:-)
>
> Let me try that on some non-gcc compilers. I'll report back.

It looks like Microsoft 2005 and later and at least some others
support varargs macros, so I'm investigating further.

--Beman
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Felipe Magno de Almeida
On Thu, Mar 5, 2009 at 7:11 PM, Beman Dawes <[hidden email]> wrote:

> On Thu, Mar 5, 2009 at 12:44 PM, Beman Dawes <[hidden email]> wrote:
>> On Thu, Mar 5, 2009 at 12:15 PM, Phil Endecott
>>> - How about avoiding the _START/_END stuff with e.g.
>>>  BOOST_SCOPED_ENUM_DECL(algae, green,red,cyan);
>>>  (I had been under the impression that varargs macros were a gcc-ism, but
>>> I've recently discovered that they're in c99; do non-gcc C++ compilers
>>> generally allow them?  I don't think we can get away with allowing only
>>> up-to-N elements in this case.)
>>
>> Hum... I hadn't considered varargs macros. If I even knew they existed:-)
>>
>> Let me try that on some non-gcc compilers. I'll report back.
>
> It looks like Microsoft 2005 and later and at least some others
> support varargs macros, so I'm investigating further.

I wouldn't. If you really want to use one macro only, I would use the
PP sequence
instead.

> --Beman


--
Felipe Magno de Almeida
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Matt Calabrese
>
> I wouldn't. If you really want to use one macro only, I would use the
> PP sequence
> instead.
>

I'm gonna be the rebel and say that I think how it's currently implemented
is [unfortunately] the most functional and most portable option, though I
guess there is no harm in supplying a couple of interfaces as long as it
doesn't make things too confusing for users. The problem with using a PP
sequence is that you are going to hit a hard limit of 256 elements, meaning
you have to at least support the current interface as an option otherwise
you rule out using the macro for enums with a large number of constants.
This also makes things frustrating for users if their enum starts below 256
in size and then over time approaches the limit. That means they would then
have to go back and switch from using preprocessor sequences to the original
style interface (or use a version of Boost.Preprocessor with higher limits).
As for using variadic macros, you need either a compiler that supports them
as an extension for C++, or an 0x compiler. While I agree that the current
interface is kind of ugly, I still think it's the best option available.


--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Felipe Magno de Almeida
On Thu, Mar 5, 2009 at 9:26 PM, Matt Calabrese <[hidden email]> wrote:
>>
>> I wouldn't. If you really want to use one macro only, I would use the
>> PP sequence
>> instead.
>>
>
> I'm gonna be the rebel and say that I think how it's currently implemented
> is [unfortunately] the most functional and most portable option,

Actually I agree with you too. I just meant that I think the PP sequence
would be better than using a vararg macro.
Though I didn't know that it has a hard limit of 256 elements.

[snip]

> While I agree that the current interface is kind of ugly,
> I still think it's the best option available.

I don't really mind the current interface. What I find uglier
is using a macro to use the enum type.

> --
> -Matt Calabrese

Regards,
--
Felipe Magno de Almeida
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Matt Calabrese
Another potential issue with using PP sequences or other preprocessor
containers is that if there is a comma in one of the initializers that isn't
surrounded by parethesis (i.e. because it refers to a template with multiple
arguments), then the user would have to provide additional parenthesis
around their expression. To people not used to the preprocessor, this is not
immediately apparent and only causes frustration because the errors produced
are far from easy to comprehend on first glance. The current interface
obviously avoids all of that.

--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Vicente Botet
In reply to this post by Matt Calabrese
----- Original Message -----
From: "Matt Calabrese" <[hidden email]>
To: <[hidden email]>
Sent: Friday, March 06, 2009 1:26 AM
Subject: Re: [boost] [C++0x] Emulation of scoped enums


>
>>
>> I wouldn't. If you really want to use one macro only, I would use the
>> PP sequence
>> instead.
>>
>
> I'm gonna be the rebel and say that I think how it's currently implemented
> is [unfortunately] the most functional and most portable option, though I
> guess there is no harm in supplying a couple of interfaces as long as it
> doesn't make things too confusing for users. The problem with using a PP
> sequence is that you are going to hit a hard limit of 256 elements, meaning
> you have to at least support the current interface as an option otherwise
> you rule out using the macro for enums with a large number of constants.
> This also makes things frustrating for users if their enum starts below 256
> in size and then over time approaches the limit. That means they would then
> have to go back and switch from using preprocessor sequences to the original
> style interface (or use a version of Boost.Preprocessor with higher limits).
> As for using variadic macros, you need either a compiler that supports them
> as an extension for C++, or an 0x compiler. While I agree that the current
> interface is kind of ugly, I still think it's the best option available.

I agree,

The _START _END version has a little inconvenient, but a lot of advanteges.

Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Vicente Botet
In reply to this post by Felipe Magno de Almeida
----- Original Message -----
From: "Felipe Magno de Almeida" <[hidden email]>
To: <[hidden email]>
Sent: Friday, March 06, 2009 1:42 AM
Subject: Re: [boost] [C++0x] Emulation of scoped enums


>
> On Thu, Mar 5, 2009 at 9:26 PM, Matt Calabrese <[hidden email]> wrote:

>> While I agree that the current interface is kind of ugly,
>> I still think it's the best option available.
>
> I don't really mind the current interface. What I find uglier
> is using a macro to use the enum type.

I don't think there is a better solution. You need to mask the fact that a enum type in C++0x is name scope and a type and can not be in C++03.

The initial proposal seems a good compromise to me.
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Daniel James
2009/3/6 vicente.botet <[hidden email]>:
>
> I don't think there is a better solution. You need to mask the fact that a enum type in C++0x is name scope and a type and can not be in C++03.

A class is a name scope and a type - isn't that why it's called 'enum class'?

    class algae {
    public:
        enum value {green, red, cyan};

        algae() {}
        algae(value v) : v_(v) {}

        // And any other required methods...
    private:
        value v_;
    };

    algae x = algae::red;
    algae y = red; // error...

This would also be closer to 'enum class' as it's strongly typed.

Beman's preprocessing syntax would have to change, as the closing
macro would have to know the name. The syntax using a preprocessor
sequence or varargs would be the same.

Daniel
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Vicente Botet
----- Original Message -----
From: "Daniel James" <[hidden email]>
To: <[hidden email]>
Sent: Friday, March 06, 2009 12:39 PM
Subject: Re: [boost] [C++0x] Emulation of scoped enums


>
> 2009/3/6 vicente.botet <[hidden email]>:
>>
>> I don't think there is a better solution. You need to mask the fact that a enum type in C++0x is name scope and a type and can not be in C++03.
>
> A class is a name scope and a type - isn't that why it's called 'enum class'?
>
>    class algae {
>    public:
>        enum value {green, red, cyan};
>
>        algae() {}
>        algae(value v) : v_(v) {}
>
>        // And any other required methods...
>    private:
>        value v_;
>    };
>
>    algae x = algae::red;
>    algae y = red; // error...
>
> This would also be closer to 'enum class' as it's strongly typed.
>
> Beman's preprocessing syntax would have to change, as the closing
> macro would have to know the name. The syntax using a preprocessor
> sequence or varargs would be the same.

Hi,

The generated code of the macro can generate this or what Beman proposed. In any case the _START, _END will be needed.

I like your solution because it allows to create a different type. I think that in addition it would be great to allows the storage type to be an integer type other that the enum value (emulation of the enum_base)

In order to recall as much as possible the C++0X syntax

enum class algae  {green, red, cyan };
enum class mycolors : unsigned char {green, red, cyan };

what about

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

   BOOST_GENERIC_ENUM_CLASS_START(algae, unsigned char) { green, red, cyan };
   BOOST_ENUM_CLASS_END

And use BOOST_ENUM_CLASS(algae)?

Best,
Vicente



Best,
Vicente

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Andrey Semashev-2
In reply to this post by Beman Dawes
Beman Dawes wrote:

> The improved type safety of the C++0x scoped enum feature is attractive,
> so I'd like to start using it as it becomes available in compilers.
>
> See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf 
> for a description. Note that the committee changed the name from
> strongly typed enums to scoped enums.
>
> See the attached for a boost/detail header that provides macro wrappers
> that use scoped enums if available, otherwise fall back on C++03
> namespaces and unscoped enums. It lets a library write:

Could this be rewritten to use structs instead of namespaces? This would
allow to declare enums nested in classes.
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Matt Calabrese
On Fri, Mar 6, 2009 at 1:08 PM, Andrey Semashev
<[hidden email]>wrote:

> Could this be rewritten to use structs instead of namespaces? This would
> allow to declare enums nested in classes.
>

Agreed. In retrospect, this is pretty important now that it's been noticed.

On Fri, Mar 6, 2009 at 6:39 AM, Daniel James <[hidden email]>
 wrote:

> A class is a name scope and a type - isn't that why it's called 'enum
> class'?
>
>    class algae {
>    public:
>        enum value {green, red, cyan};
>
>        algae() {}
>        algae(value v) : v_(v) {}
>
>        // And any other required methods...
>    private:
>        value v_;
>    };


I worry about an implementation like this because it opens up a bunch of
very subtle difference that could otherwise be avoided. For instance,
perhaps the simples problem is that now decltype( algae::green ) is not
equal to the "enum" type that is intended to be used (rather it is an actual
enum nested in that type).

One quick example of how this can show up as a problem in seemingly trivial
code is operator overloading. Imagine a very simple color enum with
enumerations "red = 1", "green = 2", "blue = 4", and let's say you decide to
overload operator | to combine colors. If you write the overload using the
type "color"... as long as at least one of your operands is not one of the
enumerated constants named directly. For instance, color( red ) | color(
blue ) works fine, however red | blue would not because the operator was
overloaded for the encapsulating type as opposed to the nested value type!

Another problem is that the type can no longer be referenced as a recognized
enum type to the compiler, so you can't, for instance, use it directly as
the type of a non-type template parameter (instead you would have to use,
continuing the example above, color::value, which wouldn't work for
compilers that actually support scoped enums).

In the interest of creating the least amount of subtle differences, I think
leaving the type as an actual enum type is going to be the best solution.

--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Daniel James
2009/3/6 Matt Calabrese <[hidden email]>:
>
> One quick example of how this can show up as a problem in seemingly trivial
> code is operator overloading. Imagine a very simple color enum with
> enumerations "red = 1", "green = 2", "blue = 4", and let's say you decide to
> overload operator | to combine colors. If you write the overload using the
> type "color"... as long as at least one of your operands is not one of the
> enumerated constants named directly. For instance, color( red ) | color(
> blue ) works fine, however red | blue would not because the operator was
> overloaded for the encapsulating type as opposed to the nested value type!

I would find occasionally writing 'algae(algae::red) | blue' less
inconvenient than having to write 'BOOST_SCOPED_ENUM(algae)' whenever
I wanted to use the type.

Another possibility is to have the values as static members of algae,
with type algae, which would fix your problem but would loose the nice
syntax for giving the enumerators values.

> Another problem is that the type can no longer be referenced as a recognized
> enum type to the compiler, so you can't, for instance, use it directly as
> the type of a non-type template parameter (instead you would have to use,
> continuing the example above, color::value, which wouldn't work for
> compilers that actually support scoped enums).

Not a problem, just always use the emulation.

> In the interest of creating the least amount of subtle differences, I think
> leaving the type as an actual enum type is going to be the best solution.

Versus the ADL differences and implicit casts in the original
solution? Which seem like more serious differences to me.

Daniel
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: [C++0x] Emulation of scoped enums

Matt Calabrese
On Sat, Mar 7, 2009 at 5:55 AM, Daniel James <[hidden email]>wrote:

> I would find occasionally writing 'algae(algae::red) | blue' less
> inconvenient than having to write 'BOOST_SCOPED_ENUM(algae)' whenever
> I wanted to use the type.


And the point is that this only further strays from how you use actual
enums. If we are trying to emulate enum functionality, why would we make it
so different to use. Post how you'd write your overloaded operators and how
the definition would work for both an underlying emulated scoped enum
implementation and an underlying native scoped enum implementation -- you're
going to have to be overly verbose otherwise it won't work for both
implementations. Another subtle issue is for you to show how you'd write a
switch statement using the enum -- now that you have a class-type, you can't
use instances of it as an argument to switch directly without first casting
your "enum" to an actual enum (or calling a named function a that returns
the same value for a native implementation and returns the underlying enum
value for an emulated one). There is also the template problem I pointed out
earlier. All of this means that with such an implementation you still have
to provide a way to get the actual underlying enum type or value if you want
to be able to use it in all of the ways an enum can be used. In the times
where you need the actual type, you would again have to use a macro or a
separate typedef also generated by the original macro invocation anyway,
which is what you didn't like about the first implementation to begin with.
If the main thing that bothers you is simply that in order to refer to the
type you have to use a macro, then just typedef it once and refer to it that
way.


> Another possibility is to have the values as static members of algae,
> with type algae, which would fix your problem but would loose the nice
> syntax for giving the enumerators values.


This is really starting to stray from enums now, and IMO needlessly so. How
would you call the macro in a way that resolves to a scoped enum on
compilers that support scoped enums without using preprocessor sequences or
variadic macros which have all of the pitfalls already mentioned earlier in
this thread? As well, for both implementers and users of the macro, it makes
it much more difficult to support the enum functionality of automatically
setting the enumerated constants' value to 1 greater than than the previous
constant, unless you plan on scrapping that functionality of enums entirely.


> > Another problem is that the type can no longer be referenced as a
> recognized
> > enum type to the compiler, so you can't, for instance, use it directly as
> > the type of a non-type template parameter (instead you would have to use,
> > continuing the example above, color::value, which wouldn't work for
> > compilers that actually support scoped enums).
>
> Not a problem, just always use the emulation.


I think this is the only option if that implementation is to be used, but I
thought the whole point was to make portable scoped enums that use the
native implementation when possible. With all of the different functionality
that this implementation implies and the fact that a scoped enum isn't even
used under the hood when available makes me question if it should even be
called SCOPED_ENUM at all if this route were taken.


> > In the interest of creating the least amount of subtle differences, I
> think
> > leaving the type as an actual enum type is going to be the best solution.
>
> Versus the ADL differences and implicit casts in the original
> solution? Which seem like more serious differences to me.


Actually, the struct solution suggested by Andrey gets rid of the ADL
differences so that is not a problem. Implicit conversion would be the one
remaining difference and all that a user needs to do to make that portable
is add a cast when converting to int and be conscious of everything they are
already familiar with from using regular enums.

--
-Matt Calabrese
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
12