C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

enum_limits

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Kai-Uwe Bux
Guest





PostPosted: Mon Oct 24, 2005 12:19 am    Post subject: enum_limits Reply with quote



Hi folks,


I had posted this problem already in comp.lang.c++; and I got many useful
suggestions as to how to work around the problem. However, it just keeps
eating time slices in my brain: is it possible to implement the following
template:

template < typename EnumType >
struct enum_limits {

typedef EnumType enum_type;

static enum_type const first = // some magic here;
static enum_type const last = // some more magic;

}; // enum_limits

The semantics ought to be such that, given an enumeration type

enum xxx { A, B, C, D };

the expression

enum_limits<xxx>::last

shall evaluate to D at compile time.


As I said, thanks to the help from comp.lang.c++, I know now plenty of ways
to achive similar effects by doing stuff like

enum xxx = { A, first=A, B, C, D, last=D };

or

struct xxx {

enum dummy { A, B, C, D };
static dummy first = A;
static dummy last = D;

};

and so on. So, I guess, I am asking this strictly for my peace of mind.


Best

Kai-Uwe Bux

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Joe Gottman
Guest





PostPosted: Mon Oct 24, 2005 8:54 am    Post subject: Re: enum_limits Reply with quote




"Kai-Uwe Bux" <jkherciueh (AT) gmx (DOT) net> wrote

Quote:
Hi folks,


I had posted this problem already in comp.lang.c++; and I got many useful
suggestions as to how to work around the problem. However, it just keeps
eating time slices in my brain: is it possible to implement the following
template:

template < typename EnumType
struct enum_limits {

typedef EnumType enum_type;

static enum_type const first = // some magic here;
static enum_type const last = // some more magic;

}; // enum_limits

The semantics ought to be such that, given an enumeration type

enum xxx { A, B, C, D };

the expression

enum_limits
shall evaluate to D at compile time.



This would be nice, but there are several reasons why it might be
problematic.

1) The underlying type, and therefore the ordering, of the enum elements
is implementation defined. For instance, consider this example (taken from
[url]http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1579.pdf):[/url]
enum E {E1 = 1, E2 = 2, EBig = 0xFFFFFFF0U};

Depending on the compiler, E might or might not have a signed type as the
underlying type so EBig might or might not be greater than E1. So the
values of enum_limits<E>::first and enum_limits<E>::last would also be
implementation defined.

2) Enums are often used to define bit-flags:
enum file_flags = {readable = 1, writable=2, executable=4};
In this case, the user would expect a file_flags variable to accept values
from 0 to 8, but enum_limits<file_flags> would say that first equals 1 and
last equals 4.

Joe Gottman

2)


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Larry
Guest





PostPosted: Mon Oct 24, 2005 4:37 pm    Post subject: Re: enum_limits Reply with quote



Sorry if this appears twice. My firefox news is apparently not
getting through.

On 10/23/2005 07:19 PM, Kai-Uwe Bux wrote:
[snip]

Quote:
eating time slices in my brain: is it possible to implement the following
template:

template < typename EnumType
struct enum_limits {

[snip]

Quote:
}; // enum_limits

The semantics ought to be such that, given an enumeration type

enum xxx { A, B, C, D };

the expression

enum_limits
shall evaluate to D at compile time.


I haven't looked closely, but the range_all.zip in the
'Template Metaprogramming' subdirectory of:

http://boost-consulting.com/vault/

*could* be relevant. IIRC, it requires specialization of

boost::mpl::aux::integral_rank<xxx>

something like:

template<> struct integral_rank<xx> : integral_rank<unsigned>
{
typedef unsigned diff_type;
static diff_type const min_limit=A;
static diff_type const max_limit=D;
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Tony Delroy
Guest





PostPosted: Mon Oct 24, 2005 4:43 pm    Post subject: Re: enum_limits Reply with quote

Hi Kai-Uwe,

It's impossible. C++ templates allow you to effectively ask questions
like "tell me about identifier X", or even "tell me if there's an
identifier X", but you simply can't ask "list the identifiers <in some
scope>". This includes your enum: there's no way for a template to
enumerate a previously-unknown enum's identifiers, or indeed find out
anything about the internal structure of the enum (except sizeof).

There's a chance that you could find a run-time method to query debug
information in your executable to reveal the enum values, but it won't
be particularly portable, and I'll leave you to assess the potential
utility.

Though it's pretty pathetic in comparison to what you really want, for
the sake of general discussion a workaround could be built using
variadic macros (given a suitable compiler extension). As Joe points
out, this is unlikely to be useful unless the values are in an expected
order, and of known significance. For example, g++ allows:

#include <iostream>

#define ENUM(IDN, X, ...)
enum IDN { X, IDN##_begin_ = X, __VA_ARGS__,
IDN##_end_, IDN##_last_ = IDN##_end_ - 1 }

int main()
{
ENUM(XXX, A, B, C, D);

std::cout << XXX_begin_ << ' ' << XXX_end_ << std::endl;
}

Ugly, hey? I wouldn't want to use it....

In conclusion, you'll have to wait for general compile-time
introspection to be added to the language, or use a preprocessor
offering such power (e.g. OpenC++).

Tony


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Larry Evans
Guest





PostPosted: Mon Oct 24, 2005 10:58 pm    Post subject: Re: enum_limits Reply with quote

On 10/23/2005 07:19 PM, Kai-Uwe Bux wrote:
[snip]
Quote:
eating time slices in my brain: is it possible to implement the following
template:

template < typename EnumType
struct enum_limits {
[snip]
}; // enum_limits

The semantics ought to be such that, given an enumeration type

enum xxx { A, B, C, D };

the expression

enum_limits
shall evaluate to D at compile time.

I haven't looked closely, but the range_all.zip in the
'Template Metaprogramming' subdirectory of:

http://boost-consulting.com/vault/

*could* be relevant. IIRC, it requires specialization of

boost::mpl::aux::integral_rank<xxx>

something like:

template<> struct integral_rank<xx> : integral_rank<unsigned>
{
typedef unsigned diff_type;
static diff_type const min_limit=A;
static diff_type const max_limit=D;
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ben Hutchings
Guest





PostPosted: Wed Oct 26, 2005 1:11 pm    Post subject: Re: enum_limits Reply with quote

Joe Gottman <jgottman (AT) carolina (DOT) rr.com> wrote:
<snip>
Quote:
This would be nice, but there are several reasons why it might be
problematic.

1) The underlying type, and therefore the ordering, of the enum elements
is implementation defined. For instance, consider this example (taken from
[url]http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1579.pdf):[/url]
enum E {E1 = 1, E2 = 2, EBig = 0xFFFFFFF0U};

Depending on the compiler, E might or might not have a signed type as the
underlying type so EBig might or might not be greater than E1. So the
values of enum_limits<E>::first and enum_limits<E>::last would also be
implementation defined.

I believe the paper is in error in its description of the
implementation-defined behaviour of this enumeration. The standard
says (in 7.2/4-5):

"Following the closing brace of an enum-specifier, each enumerator
has the type of its enumeration. ... If an initializer is
specified for an enumerator, the initializing value has the same
type as the expression. ... The underlying type of an enumeration
is an integral type that can represent all the enumerator values
defined in the enumeration. ... [T]he underlying type shall not be
larger than int unless the value of an enumerator cannot fit in an
int or unsigned int."

It's not explicit in the standard that enumerated types undergo
integral promotion in exactly the same way as their underlying integer
types, though that's the only reasonable interpretation I can see
of 7.2/8.

Therefore if int and unsigned int both have 32-bit value
representations the underlying type for this enumeration *must* be
unsigned int, and the implementations listed in the paper that do not
agree with the behaviour of EDG and GCC are in error. (This may be
due to reusing code from a C front-end, which should have somewhat
different behaviour.)

Quote:
2) Enums are often used to define bit-flags:
enum file_flags = {readable = 1, writable=2, executable=4};
In this case, the user would expect a file_flags variable to accept values
from 0 to 8,

I assume you mean 0 to 7 - or in another notation: [0, Cool.

Quote:
but enum_limits<file_flags> would say that first equals 1 and
last equals 4.

The standard agrees with the user in this case (7.2/6).

--
Ben Hutchings
Having problems with C++ templates? Your questions may be answered by
<http://womble.decadentplace.org.uk/c++/template-faq.html>.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.