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:
@@ -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_ */
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user