determining enumeration type boundaries like with std::numeric_limits<T>::max() ?

1,786 views
Skip to first unread message

Peter Sommerlad

unread,
Sep 5, 2012, 7:32:43 AM9/5/12
to std-dis...@isocpp.org, accu-general General
Hi C++ experts,

is there a means to determine the boundaries of an enum type? Or even better, figure out, if a given integral value actually matches one of the defined enum constants in C++11?

Is there any need for such a facility? (I would say yes)

Is there any possibility for compilers to provide such a facility?

Thanks
Peter.
--
Prof. Peter Sommerlad

Institut für Software: Bessere Software - Einfach, Schneller!
HSR Hochschule für Technik Rapperswil
Oberseestr 10, Postfach 1475, CH-8640 Rapperswil

http://ifs.hsr.ch http://cute-test.com http://linticator.com http://includator.com
tel:+41 55 222 49 84 == mobile:+41 79 432 23 32
fax:+41 55 222 46 29 == mailto:peter.s...@hsr.ch





Ville Voutilainen

unread,
Sep 5, 2012, 7:35:25 AM9/5/12
to std-dis...@isocpp.org, accu-general General
On 5 September 2012 14:32, Peter Sommerlad <peter.s...@hsr.ch> wrote:
> Hi C++ experts,
> is there a means to determine the boundaries of an enum type? Or even better, figure out, if a given integral value actually matches one of the defined enum constants in C++11?

None that I'm currently aware of.

> Is there any need for such a facility? (I would say yes)

Sure.

> Is there any possibility for compilers to provide such a facility?

Do you want to support this particular enum case specifically, or
perhaps general compile-time
introspection?

Dean Michael Berris

unread,
Sep 5, 2012, 7:49:54 AM9/5/12
to std-dis...@isocpp.org, accu-general General
On Wed, Sep 5, 2012 at 9:35 PM, Ville Voutilainen
<ville.vo...@gmail.com> wrote:
>
> On 5 September 2012 14:32, Peter Sommerlad <peter.s...@hsr.ch> wrote:
> > Hi C++ experts,

I wouldn't call myself an expert, but...

> > is there a means to determine the boundaries of an enum type? Or even better, figure out, if a given integral value actually matches one of the defined enum constants in C++11?
>
> None that I'm currently aware of.
>
> > Is there any need for such a facility? (I would say yes)
>
> Sure.
>

+1

> > Is there any possibility for compilers to provide such a facility?
>
> Do you want to support this particular enum case specifically, or
> perhaps general compile-time
> introspection?
>

I am working on an update to N3340 which covers this case. Part of it
really is a special-casing for constexpr functions that would only
work at compile-time. Don't let this stop you from writing something
up though.

Cheers

--
Dean Michael Berris | Software Engineer
Google

James Dennett

unread,
Sep 5, 2012, 8:09:13 AM9/5/12
to accu-general, std-dis...@isocpp.org
On Wed, Sep 5, 2012 at 4:32 AM, Peter Sommerlad <peter.s...@hsr.ch> wrote:
> Hi C++ experts,
>
> is there a means to determine the boundaries of an enum type?

C++11 offers the trait
template <class T> struct underlying_type;
and then you can (of course) use numeric_limits to get the limits of that type.

> Or even better, figure out, if a given integral value actually matches one of the defined enum constants in C++11?

Sadly not. Use Google's protocol buffers instead of a plain old
enumeration if you'd like more metadata ;-)

> Is there any need for such a facility? (I would say yes)

It would make debug logging slightly cleaner... likely there are other uses.

> Is there any possibility for compilers to provide such a facility?

It would be reasonably straightforward to generate such code given the
enum's definition. If this were integrated into a compiler I'd hope
that it would do this lazily, as the effect on compile- and link-time
performance of doing it for every enum could be non-trivial.

-- James

Alberto Ganesh Barbati

unread,
Sep 5, 2012, 8:46:14 AM9/5/12
to std-dis...@isocpp.org

Il giorno 05/set/2012, alle ore 13:32, Peter Sommerlad <peter.s...@hsr.ch> ha scritto:

> Hi C++ experts,
>
> is there a means to determine the boundaries of an enum type? Or even better, figure out, if a given integral value actually matches one of the defined enum constants in C++11?

Currently, no.

> Is there any need for such a facility? (I would say yes)

Not really. I am yet to see a use case for that.

> Is there any possibility for compilers to provide such a facility?

First of all, enumerations are not "numbers", so it is a big stretch to specialize numeric_limits for them. A different traits could (and should) be used instead. Just my opinion.

Daniel Krügler has suggested a type trait to discover the underlying type of an enumeration. This would produce the correct result for fixed-type enumerations. In fact, for a fixed-type enum, all values of the underlying type are valid values, regardless of the enumerators. For non-fixed-type (aka C++03) enumerations, the question is a bit more tricky, but it still has to be noted that in general there may be valid values that do not correspond to any enumerator (see 7.2/7).

Ganesh

Daniel Krügler

unread,
Sep 5, 2012, 1:40:28 PM9/5/12
to std-dis...@isocpp.org
2012/9/5 Alberto Ganesh Barbati <alberto...@gmail.com>:
>
> Daniel Krügler has suggested a type trait to discover the underlying type of an enumeration.

Actually it was Beman who suggested it and it became accepted with:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2984.htm

My own suggestion was (some months ago?) to extend std::underlying_type to
be applicable to other types with an underlying type, e.g. for
wchar_t, char16_t,
and char32_t.

- Daniel

Vicente J. Botet Escriba

unread,
Sep 5, 2012, 10:58:30 PM9/5/12
to std-dis...@isocpp.org
Le 05/09/12 13:32, Peter Sommerlad a écrit :
Hi C++ experts,

is there a means to determine the boundaries of an enum type? Or even better, figure out, if a given integral value actually matches one of the defined enum constants in C++11?
I have tried to implement this kind of things in TBoost.Enums/Ordinal (not part of Boost) adding some traits that are, of course generated using the pre-processor magic. (See https://svn.boost.org/svn/boost/sandbox/enums/libs/enums/doc/html/index.html#boost.enums.users_guide.tutorial.ordinal).

This has a sense only for enumerations for which the enumeration literals don't share the same value.
Following the ADA naming for ordinal types the library manages with the following informations:

  • size: the number of elements in the enum type.
  • pos: the position relative of an element in the enum type.
  • val: the element in the enum type at a given position.
  • first: the first enumeration literal,
  • last: the last enumeration literal,
  • successor:  the enumeration literal following a given enumeration literal and
  • predecessor: the enumeration literal preceding a given enumeration literal,
In order to get these information we need to defines the following traits and functions:

namespace meta {
  template <typename Enum>
  struct size : integral_constant<size_t, S> {};
  template<typename EC, EC V1>
  struct pos : integral_constant<size_t, N1> {};
  template<typename EC, std::size_t I1>
  struct val {constexpr EC value};
}

These traits are generated by some macros the library provide but could and should be provided by the compiler.

The following traits and functions can be defined from the preceding ones

    namespace meta {
      template<typename EC, EC V> struct succ;
      template<typename EC, EC V> struct pred;
      template<typename EC> struct last;     
      template<typename EC> struct first;

    }
    template<typename EC> constexpr EC val(std::size_t);
    template<typename EC> constexpr std::size_t pos(EC);
    template<typename EC> constexpr std::size_t size();
    template<typename EC> constexpr EC succ(EC);
    template<typename EC> constexpr EC pred(EC);
    template<typename EC> constexpr EC last();
    template<typename EC> constexpr EC first();

In order to figure out if a given integral value actually matches one of the defined enum constants, an additional trait and a function could be added

  namespace meta {
    template<typename EC, std::size_t I>
    struct valid : integral_constant<bool, false> {};
    template<typename EC>
    struct valid<EC,I1> : integral_constant<bool, true> {};
    ...
    template<typename EC>
    struct valid<EC,IN> : integral_constant<bool, true> {};
  }
  template<typename EC>
  constexpr bool valid(typename underlying_type<EC>::type);
 
Is there any need for such a facility? (I would say yes)
When enums can be considered as ordinal types, they can be used for example as index of an array. As all the values are different we can think about a set of enums which can be implemented in an efficient way as a bitset. In addition we can see it as a range.


Is there any possibility for compilers to provide such a facility?
All enums with different values can be considered as ordinal types in a trivial way. For the others, a specific definition must be given to the size, pos and val meta-functions. I'm sure that once this is specified the compiler writers will be able to provide this information.

Best,
Vicente
Reply all
Reply to author
Forward
0 new messages