diff --git a/codegen/facelift/templates/Enum.template.h b/codegen/facelift/templates/Enum.template.h index 87216979..2a7eafb6 100644 --- a/codegen/facelift/templates/Enum.template.h +++ b/codegen/facelift/templates/Enum.template.h @@ -74,37 +74,20 @@ template<> inline const std::initializer_list<{{enum.fullyQualifiedCppType}}>& v return values; } -template <> inline QString enumToString(const {{enum.fullyQualifiedCppType}}& v) -{ - const char* s = "Invalid"; - switch(v) { - {% for member in enum.members %} - case {{enum.fullyQualifiedCppType}}::{{member}}: - s = "{{member}}"; - break; - {% endfor %} - default: - break; - } - return s; -} -} +} // end namespace facelift - -inline void assignFromString(const QString &s, {{enum.fullyQualifiedCppType}}& v) +inline void fromString(const QString& string, {{enum.fullyQualifiedCppType}}& value) { - {% for member in enum.members %} - if (s == "{{member}}") - v = {{enum.fullyQualifiedCppType}}::{{member}}; - else - {% endfor %} - ::facelift::onAssignFromStringError(s); + auto valuePointer = facelift::Enum::fromString<{{enum.fullyQualifiedCppType}}>(string); + if(!valuePointer) { + facelift::Enum::fromStringError(string); + } + value = *valuePointer; } - -inline QTextStream &operator <<(QTextStream &outStream, const {{enum.fullyQualifiedCppType}}& f) +inline QTextStream &operator <<(QTextStream& outStream, const {{enum.fullyQualifiedCppType}}& value) { - outStream << facelift::enumToString(f); + outStream << facelift::Enum::toString(value); return outStream; } diff --git a/src/model/FaceliftCommon.h b/src/model/FaceliftCommon.h index 783be8e8..cae32304 100644 --- a/src/model/FaceliftCommon.h +++ b/src/model/FaceliftCommon.h @@ -66,15 +66,6 @@ inline const std::initializer_list &validValues() return l; } - -template -QString enumToString(const Type &v) -{ - Q_UNUSED(v); - static_assert(!std::is_enum::value, "Missing specialization of enumToString() template"); - return ""; -} - #ifdef QT_DEBUG #define faceliftSeriousError qFatal #else diff --git a/src/model/FaceliftEnum.cpp b/src/model/FaceliftEnum.cpp index fcbf5d2c..375500fa 100644 --- a/src/model/FaceliftEnum.cpp +++ b/src/model/FaceliftEnum.cpp @@ -32,10 +32,15 @@ #include namespace facelift { + +namespace Enum { -void onAssignFromStringError(const QString &s) +void fromStringError(const QString &string) { - qFatal("No enum value matching string %s", qPrintable(s)); + qFatal("No enum value matching string %s", qPrintable(string)); } -} + +} // end namespace Enum + +} // end namespace facelift diff --git a/src/model/FaceliftEnum.h b/src/model/FaceliftEnum.h index 3d86f899..d3b7cc9a 100644 --- a/src/model/FaceliftEnum.h +++ b/src/model/FaceliftEnum.h @@ -31,11 +31,41 @@ #pragma once #include "FaceliftCommon.h" -#include -#include +#include +#include +#include +#include +#include namespace facelift { -void onAssignFromStringError(const QString &s); +namespace Enum { +void fromStringError(const QString &string); + +// Returns the string that is used as the name of the given enumeration value, +// or an empty string if value is not defined +template::Value, T>* = nullptr> +QString toString(T value) +{ + return QMetaEnum::fromType().valueToKey(static_cast(value)); +} + +// Returns the enumaration value of the given enumeration key, or nullptr if key is not defined. +// TODO change std::unique_ptr to std::optional when it will be possible +template +std::unique_ptr fromString(const QString &string) +{ + QByteArray byteArray = string.toLocal8Bit(); + bool ok {}; + int value = QMetaEnum::fromType().keyToValue(byteArray.data(), &ok); + + T result = static_cast(value); + + return ok ? std::make_unique(result) : nullptr; } + + +} // end namespace Enum + +} // end namespace facelift diff --git a/src/model/StringConversionHandler.h b/src/model/StringConversionHandler.h index 9e68f93a..23fc061b 100644 --- a/src/model/StringConversionHandler.h +++ b/src/model/StringConversionHandler.h @@ -37,18 +37,17 @@ #include #include #include "FaceliftCommon.h" +#include "FaceliftEnum.h" namespace facelift { class InterfaceBase; class StructureBase; -template +template struct StringConversionHandler { - typedef Type QMLType; - - static QString toString(const Type &v) + static QString toString(const T &v) { QString s; QTextStream(&s) << v; @@ -65,47 +64,46 @@ struct StringConversionHandler } }; -QString qObjectToString(const QObject *o); +QString qObjectToString(const QObject *object); -template -struct StringConversionHandler::value>::type> +template +struct StringConversionHandler::value>> { - static QString toString(const Type *o) + static QString toString(const T *object) { - return qObjectToString(o); + return qObjectToString(object); } }; -template -struct StringConversionHandler::value>::type> +template +struct StringConversionHandler::value>> { - static QString toString(const Type &v) + static QString toString(const T &value) { - return v.toString(); + return value.toString(); } }; - -template -struct StringConversionHandler::value>::type> +template +struct StringConversionHandler::Value, T>> { - static QString toString(const Type &v) + static QString toString(T value) { - return facelift::enumToString(v); + return Enum::toString(value); } }; -template -struct StringConversionHandler > +template +struct StringConversionHandler > { - static QString toString(const QList &v) + static QString toString(const QList &v) { QString s; QTextStream str(&s); str << "[ "; for (const auto &element : v) { - str << StringConversionHandler::toString(element); + str << StringConversionHandler::toString(element); str << ", "; } str << "]"; @@ -113,10 +111,10 @@ struct StringConversionHandler > } }; -template -struct StringConversionHandler > +template +struct StringConversionHandler > { - static QString toString(const QMap &map) + static QString toString(const QMap &map) { QString s; QTextStream str(&s); @@ -124,7 +122,7 @@ struct StringConversionHandler > for (auto i = map.constBegin(); i != map.constEnd(); ++i) { str << StringConversionHandler::toString(i.key()); str << ":"; - str << StringConversionHandler::toString(i.value()); + str << StringConversionHandler::toString(i.value()); str << ", "; } str << "]"; @@ -132,10 +130,11 @@ struct StringConversionHandler > } }; -template -inline QString toString(const Type &v) +template +inline QString toString(const T &v) { - return StringConversionHandler::toString(v); + return StringConversionHandler::toString(v); } + }