With a declaration such as:
enum DrawBoldMode : unsigned
{
DBM_NONE = 0,
DBM_ITEM = 1<<0, // bold just the nearest line
DBM_SECTION = 1<<1, // bold all lines in the same section
DBM_LINETYPE = 1<<2, // bold all lines of the same line type
DBM_POINTAGE = 1<<3, // bold all lines of the same line type
};
How can I derive the underlying type of DrawBoldMode (i.e. unsigned)?
The default underlying type of the enumeration elements is int. By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1. Enums are enumerated data type in C#.
Each enum type has a corresponding integral type called the underlying type of the enum type. This underlying type shall be able to represent all the enumerator values defined in the enumeration. If the enum_base is present, it explicitly declares the underlying type.
Enumerated (enum) types are data types that comprise a static, ordered set of values. They are equivalent to the enum types supported in a number of programming languages. An example of an enum type might be the days of the week, or a set of status values for a piece of data.
In C++ programming, enum or enumeration is a data type consisting of named values like elements, members, etc., that represent integral constants. It provides a way to define and group integral constants. It also makes the code easy to maintain and less complex.
std::underlying_type
is available in GCC 4.7, but until then you can get an approximate emulation with templates:
#include <tuple>
// This is a hack because GCC 4.6 does not support std::underlying_type yet.
// A specialization for each enum is preferred
namespace detail {
template <typename T, typename Acc, typename... In>
struct filter;
template <typename T, typename Acc>
struct filter<T, Acc> {
typedef typename std::tuple_element<0, Acc>::type type;
};
template <typename T, typename... Acc, typename Head, typename... Tail>
struct filter<T, std::tuple<Acc...>, Head, Tail...>
: std::conditional<sizeof(T) == sizeof(Head) && (T(-1) < T(0)) == (Head(-1) < Head(0))
, filter<T, std::tuple<Acc...,Head>, Tail...>
, filter<T, std::tuple<Acc...>, Tail...>
>::type {};
template <typename T, typename... In>
struct find_best_match : filter<T, std::tuple<>, In...> {};
}
namespace std {
template <typename E>
struct underlying_type : detail::find_best_match<E,
signed short,
unsigned short,
signed int,
unsigned int,
signed long,
unsigned long,
signed long long,
unsigned long long,
bool,
char,
signed char,
unsigned char,
wchar_t,
char16_t,
char32_t> {};
}
It doesn't give you the exact type, but it gives you one with the same size and signedness characteristics.
It should be available as std::underlying_type<DrawBoldMode>::type
. However, my compiler (GCC 4.6.1) doesn't seem to implement that.
I think it's impossible to implement it with templates, but I could be wrong about that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With