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);
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.
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