template<typename T, bool UseID = false, bool Counting = false, typename CountType = int, bool UseMutex = false>
struct mira::ExtensibleEnum< T, UseID, Counting, CountType, UseMutex >
ExtensibleEnum is a base for derived classes that can be extensible 'replacements' for enum types.
Like an enum, the user can define a number of discrete named values in the derived class. An instance can only be assigned one of these defined values. The main advantage compared to an actual enum, however, is extensibility: The set of valid values can easily be extended by further subclassing and defining new named values in the subclass (see example below).
Optionally each value can be assigned an additional string ID, which can e.g. be used to refer to them outside of code (such as in a config file). String IDs are arbitrary and not checked for uniqueness! Use of namespaces or similar mechanism is recommended to keep IDs useful with extensibility.
ExtensibleEnum can optionally use an internal counter to enumerate values in the base enum class and all its derivations with internal indices, in that case the total number of existing values can be queried (possibly enhanced to also allow iteration over values in the future). If a counter is to be used, further choices to make are the numeric type of the counter and whether to use a mutex to lock the counter against parallel access. All of these options are exposed as template parameters (with default values). A concrete enum subclass is implemented by deriving from a specific template instantiation (i.e. the choice is made by specifying base class template parameters/omitting them to use defaults).
- Template Parameters
-
T | The subclass name, used in CRTP |
UseID | Whether to use a string id (default = false) |
Counting | bool parameter specifying whether to use an internal integral counter (default = false) |
CountType | Type name for the integral counter type (default = int, ignored if Counting is false) |
UseMutex | Whether to lock the counter against parallel access, (default = false, ignored if Counting is false) |
Macros MIRA_EXTENSIBLE_ENUM_DECLARE(EnumName, BaseClass, Values...) and MIRA_EXTENSIBLE_ENUM_DEFINE(EnumName, Values...) are provided for convenience and should be used.
Usage sample code:
class A
{
public:
ModeValueA, ModeValueB)
void setMode(Mode mode)
{
mMode = mode;
}
protected:
virtual void processData(...)
{
if (mMode == ModeValueA)
...
else
...
}
protected:
Mode mMode;
};
(in .C):
class B : public A
{
public:
ModeValueC)
protected:
virtual void processData(...)
{
if (mMode == ModeValueC)
...
else
A::processInput();
}
};
(in .C):
- Note
- for using a multi-parameter template for the base class macro parameter, it must be enclosed in parentheses (otherwise the commas will confuse the macro):
ModeValueA, ModeValueB)
For defining the IDs with each value (with UseID = true), provide them in
\code
ValueA, ValueB)
....
if (readIDFromExternalSource() == ValueA.id())
....