Enum class <-> string macro improved.

The macro generates code for two functions: EnumToString() and StringToEnum().

Notes:
1. this macro creates a scoped enumeration (enum class) which favors code
readability;

2. this implementation does not support assignment of values to enumerators
and also does not support multiple enumerators with the same value. The first
enumerator value is 0, the next is 1, and so on. Nevertheless, it is still
useful for many cases;

3. if an invalid string is passed to StringToEnum() the program will be
aborted and an error message describing the error will be displayed in the
standard output.
This commit is contained in:
Éder Ferreira Zulian
2015-05-11 12:46:21 +02:00
parent 48154a356d
commit 0fc640ad0d
4 changed files with 40 additions and 53 deletions

View File

@@ -88,43 +88,45 @@ double queryDoubleParameter(tinyxml2::XMLElement* node, std::string name);
void setUpDummy(tlm::tlm_generic_payload& payload, Bank& bank);
//
// BOOST_PP_STRINGIZE(text)
// text will be converted to a string literal.
//
// BOOST_PP_SEQ_ENUM(enumerators)
// This macro expands to a comma-separated list of the elements in
// enumerators.
//
// BOOST_PP_SEQ_FOR_EACH(macro, data, seq)
// This macro is a repetition construct. If seq is (a)(b)(c), it expands to
// the sequence: macro(r, data, a) macro(r, data, b) macro(r, data, c)
//
// Note: this implementation requires that the enumerators map to unique
// values.
//
// See also:
// http://www.boost.org/doc/libs/1_38_0/libs/preprocessor/doc/
// http://stackoverflow.com/questions/5093460/how-to-convert-an-enum-type-variable-to-a-string
//
#define X_DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem) \
#define DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem) \
case data::elem : return BOOST_PP_STRINGIZE(elem);
#define DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS(enumName, enumerators) \
enum class enumName { \
BOOST_PP_SEQ_ENUM(enumerators) \
}; \
\
inline const char* ToString(enumName v) \
{ \
switch (v) { \
BOOST_PP_SEQ_FOR_EACH( \
X_DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS_TOSTRING_CASE, \
enumName, \
enumerators \
) \
default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \
} \
#define DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS_TOENUM_IF(r, data, elem) \
if (BOOST_PP_SEQ_TAIL(data) == BOOST_PP_STRINGIZE(elem)) \
return BOOST_PP_SEQ_HEAD(data)::elem; else
#define DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS(enumName, enumerators) \
enum class enumName { \
BOOST_PP_SEQ_ENUM(enumerators) \
}; \
\
inline const char *EnumToString(enumName v) \
{ \
switch (v) { \
BOOST_PP_SEQ_FOR_EACH( \
DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS_TOSTRING_CASE, \
enumName, \
enumerators \
) \
default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \
} \
} \
\
inline enumName StringToEnum(std::string s) \
{ \
BOOST_PP_SEQ_FOR_EACH( \
DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS_TOENUM_IF, \
(enumName)(s), \
enumerators \
) \
{ \
SC_REPORT_FATAL("Configuration", \
("Invalid string \"" + s + "\" for conversion into enum \"" \
+ BOOST_PP_STRINGIZE(enumName) + "\"").c_str() \
); \
throw; \
} \
}
#endif /* UTILS_COMMON_H_ */

View File

@@ -57,21 +57,6 @@ EPowerDownMode string2PDNMode(string s)
}
}
StorageMode string2StorageMode(string s)
{
if (s == "NoStorage")
return StorageMode::NoStorage;
else if (s == "Store")
return StorageMode::Store;
else if (s == "ErrorModel")
return StorageMode::ErrorModel;
else
{
SC_REPORT_FATAL("Configuration", ("Unknown StorageMode: " + s).c_str());
throw;
}
}
void Configuration::setParameter(std::string name, std::string value)
{
if(name == "BankwiseLogic")
@@ -113,7 +98,7 @@ void Configuration::setParameter(std::string name, std::string value)
else if(name == "csvfile")
csvfile = value;
else if(name == "StorMo")
StorMode = string2StorageMode(value);
StorMode = StringToEnum(value);
else
{
SC_REPORT_FATAL("Configuration", ("Parameter " + name + " not defined in Configuration").c_str());

View File

@@ -14,7 +14,7 @@
#include "../../../common/Utils.h"
enum class EPowerDownMode{NoPowerDown, Staggered, TimeoutPDN, TimeoutSREF};
DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS(StorageMode, (NoStorage) (Store) (ErrorModel));
DEFINE_ENUM_CLASS_WITH_STRING_CONVERSIONS(StorageMode, (NoStorage)(Store)(ErrorModel));
struct Configuration
{

View File

@@ -61,7 +61,7 @@ struct Dram: sc_module
IFPOW( MemorySpecification memSpec(MemSpecParser::getMemSpecFromXML(Configuration::getInstance().memspecUri)) );
IFPOW( DRAMPower = new libDRAMPower( memSpec, 0 ) );
cout << "StorageMode = " << ToString(StorMode) << endl;
cout << "StorageMode: " << EnumToString(StorMode) << endl;
if(StorMode == StorageMode::ErrorModel)
{