 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kai-Uwe Bux Guest
|
Posted: Mon Oct 24, 2005 12:19 am Post subject: enum_limits |
|
|
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
|
Posted: Mon Oct 24, 2005 8:54 am Post subject: Re: enum_limits |
|
|
"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
|
Posted: Mon Oct 24, 2005 4:37 pm Post subject: Re: enum_limits |
|
|
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
|
Posted: Mon Oct 24, 2005 4:43 pm Post subject: Re: enum_limits |
|
|
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
|
Posted: Mon Oct 24, 2005 10:58 pm Post subject: Re: enum_limits |
|
|
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
|
Posted: Wed Oct 26, 2005 1:11 pm Post subject: Re: enum_limits |
|
|
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, .
| 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 |
|
 |
|
|
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
|
|