patterncppMinor
Smart enum templates
Viewed 0 times
smarttemplatesenum
Problem
Here is some code I wrote 10 years ago. I'm now reviewing it and there are a lot of things I don't like.
There is possibility for weird behaviour if the template is attempted to be used with a type that I didn't intend. Also I don't like the big macros for
Any suggestions are welcome; I do have C++11 access now (although I didn't when first writing this of course).
The goal of
The purpose I use
The code for
```
#ifndef H_SMART_ENUM
#define H_SMART_ENUM
#include
#include
#include
#include
//------------------------------------
There is possibility for weird behaviour if the template is attempted to be used with a type that I didn't intend. Also I don't like the big macros for
DECLARE and DEFINE; and weird compile errors can occur if it is not used in just the right way.Any suggestions are welcome; I do have C++11 access now (although I didn't when first writing this of course).
The goal of
SmartEnum is to:- Provide a bijection (unique two-way mapping) between an
enumtype and a string.
- Provide a bijection between each
enumitem and a string
- Provide a description string for the
enum.
- Convert an
enumvalue to an integral value
- Convert an integral value to an
enumvalue,throwing if no validenumvalue exists. This must be the inverse of the previous conversion
The purpose I use
SmartEnum for is that I read and write a configuration file in human-readable format, and in the file the enums are referred to by name; and the enum items can also be referred to by name. I include enums in this scheme via the following function:// Convert to builtin and/or enum automatically!
template T to_any(std::string const &s)
{
// Blank string goes to zero. (Config2XML relies on this)
long v = 0;
if (!s.empty())
v = to_integral_type(s, -1); // does what it sounds like
#pragma option push -w-8008 // compiler complains about condition always false/true
#pragma option push -w-8066
if (enum_properties::is_enum)
return to_enum(v);
else
return static_cast(v);
#pragma option pop
#pragma option pop
}
// this is needed as the previous function barfs if instantiated with std::string
template<> inline std::string to_any(std::string const &s)
{ return s; }The code for
SmartEnum:```
#ifndef H_SMART_ENUM
#define H_SMART_ENUM
#include
#include
#include
#include
//------------------------------------
Solution
Since you have access to a C++11 compiler, you should use the standard type trait
Now, you don't have any mean to know whether
std::is_enum in the default version of your template instead of just writing is_enum = false. Also, it should be constexpr:template struct enum_properties
{
static constexpr bool is_enum = std::is_enum::value;
// ...
};Now, you don't have any mean to know whether
T is a simple enum or a "smart" one though. The name is_enum was confusing, and since there is already such a trait in the standard, your class should reflect its behaviour. Now, we want another mean to differenciate simple enums from smart ones. I propose to add another constant in enum_properties, along the lines of std::numeric_limits::is_specialized. This constant would tell whether enum_properties is specialized for a given type, and the name is less ambiguous than the previous one.template struct enum_properties
{
static constexpr bool is_enum = std::is_enum::value;
static constexpr bool is_specialized = false;
// ...
};
#define DECLARE_SMART_ENUM(E) \
template<> struct enum_properties { \
static constexpr bool is_enum = std::is_enum::value; \
static constexpr bool is_specialized = true; \
/* ... */ \
};Code Snippets
template<typename T> struct enum_properties
{
static constexpr bool is_enum = std::is_enum<T>::value;
// ...
};template<typename T> struct enum_properties
{
static constexpr bool is_enum = std::is_enum<T>::value;
static constexpr bool is_specialized = false;
// ...
};
#define DECLARE_SMART_ENUM(E) \
template<> struct enum_properties<E> { \
static constexpr bool is_enum = std::is_enum<E>::value; \
static constexpr bool is_specialized = true; \
/* ... */ \
};Context
StackExchange Code Review Q#54124, answer score: 7
Revisions (0)
No revisions yet.