More C++ Idioms/Type Safe Enum

= Type Safe Enum =

Intent
Improve type-safety of native enum data type in C++.

Also Known As
Typed enums

Motivation
Enumerations in C++03 are not sufficiently type-safe and may lead to unintended errors. In spite of being a language-supported feature, enums also have code portability issues due to different ways in which different compilers handle the corner cases of enumerations. The problems surrounding enumerations can be categorized in 3 ways :


 * Implicit conversion to an integer
 * Inability to specify the underlying type (prior to c++11)
 * Scoping issues

C++03 enumerations are not devoid of type safety, however. In particular, direct assignment of one enumeration type to another is not permitted. Moreover, there is no implicit conversion from an integer value to an enumeration type. However, most unintended enumeration errors can be attributed to its ability to get automatically promoted to integers. For instance, consider the following valid C++03 program. Only a few compilers such as GNU g++ issue a warning to prevent unintended errors like below.

Other problems with C++03 enums are their inability to specify the underlying representation type to hold the values of enumerators. A side effect of this underspecification is that the sizes and the signedness of the underlying type vary from compiler to compiler, which leads to non-portable code. Finally, the scoping rules of C++03 may cause inconvenience. For instance, two enumerations in the same scope can not have enumerators with the same name.

Type safe enum idiom is a way to address these issues concerning C++03 enumerations. Note that enum class in C++11 eliminates the need of this idiom.

Solution and Sample Code
Type safe enum idiom wraps the actual enumerations in a class or a struct to provide strong type-safety.

In the above solution, the actual enumerations are wrapped inside color_def and shape_def structures. To obtain a safe enumeration type from the definitions, safe_enum template is used. safe_enum template makes use of the Parameterized Base Class idiom i.e., it inherits publicly from the def parameter inself. As a result, the enumerations defined in the definitions are available in the safe_enum instantiation.

safe_enum template also supports a way to specify the underlying type (inner) used to hold values of the enumerators. By default it is the same as the enumeration type in its definition. Using explicit underlying representation type as the second type parameter, the size of the safe_enum template instantiation can be controlled in a portable way.

safe_enum template prevents automatic promotion to integers because there is no conversion operator in it. Instead, it provides underlying function, which can be used to retrieve the value of the enumerator. Overloaded operators are also provided by the template to allow simple comparisons and total ordering of the type-safe enumerators.

Iterating over enumerations

In some cases where enumerations are all contiguous values, iteration over the entire set of enumeration is also possible. Strictly speaking, iteration is not a part of the idiom, but it is a useful enhancement. Following code shows the enhancements needed to add iteration capability. A static array of safe_enums is created for each instantiation of safe_enum class. The array is populated by the initialize function with the original enumeration values. Note that enumeration values are assumed to be contiguous in the initialize function. Once the array is initialized, iteration is simply traversal from beginning to the end of the static array. The begin and end functions return iterators to the beginning and (one past) the end of the array.

Related Idioms

 * Parameterized Base Class