-
Notifications
You must be signed in to change notification settings - Fork 20
Add QMetaEnum usage for autogenerated code #317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,10 +32,14 @@ | |
| #include <QDebug> | ||
|
|
||
| namespace facelift { | ||
|
|
||
| namespace Enum { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In facelift, namespaces are used to group entities which belong together into a layer. A upper-level layer (such as "facelift") should not have any dependency to a lower layer (such as "facelift::ipc"). Your change is breaking that rule.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, but coding standards/guidelines in facelift, also community page, etc. are EMPTY. This means that you cannot expect any coding standards from anyone. Also separate namespace for utility makes sense and is a common practice in the software world, especially when you do not want to create a class/struct with all static methods.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
in this case namespace is used for its straight purpose - name scope.
please suggest a better name
it's not needed at the moment
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually StringConversionHandler is not needed at all |
||
|
|
||
| void onAssignFromStringError(const QString &s) | ||
| void raiseFatalError(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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,11 +31,40 @@ | |
| #pragma once | ||
|
|
||
| #include "FaceliftCommon.h" | ||
| #include <QObject> | ||
| #include <QTextStream> | ||
| #include <type_traits> | ||
| #include <memory> | ||
| #include <QString> | ||
| #include <QMetaEnum> | ||
| #include <QByteArray> | ||
|
|
||
| namespace facelift { | ||
|
|
||
| void onAssignFromStringError(const QString &s); | ||
| namespace Enum { | ||
|
kunichik marked this conversation as resolved.
|
||
|
|
||
| void raiseFatalError(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<class T, std::enable_if_t<QtPrivate::IsQEnumHelper<T>::Value, T>* = nullptr> | ||
| QString toString(T value) | ||
| { | ||
| return QMetaEnum::fromType<T>().valueToKey(static_cast<int>(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<typename T> | ||
| std::unique_ptr<T> fromString(const QString &string) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are causing some data to be allocated on the heap, which is definitely not needed to convert a string to an enum.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I considered that, only std::optional should be here. |
||
| { | ||
| QByteArray byteArray = string.toLocal8Bit(); | ||
| bool ok = false; | ||
| int value = QMetaEnum::fromType<T>().keyToValue(byteArray.data(), &ok); | ||
|
|
||
| T result = static_cast<T>(value); | ||
|
|
||
| return ok ? std::make_unique<T>(result) : nullptr; | ||
| } | ||
|
|
||
|
|
||
| } // end namespace Enum | ||
| } // end namespace facelift | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,18 +37,17 @@ | |
| #include <QList> | ||
| #include <type_traits> | ||
| #include "FaceliftCommon.h" | ||
| #include "FaceliftEnum.h" | ||
|
|
||
| namespace facelift { | ||
|
|
||
| class InterfaceBase; | ||
| class StructureBase; | ||
|
|
||
| template<typename Type, typename Enable = void> | ||
| template<typename T, typename Enable = void> | ||
| struct StringConversionHandler | ||
| { | ||
| typedef Type QMLType; | ||
|
|
||
| static QString toString(const Type &v) | ||
| static QString toString(const T &v) | ||
| { | ||
| QString s; | ||
| QTextStream(&s) << v; | ||
|
|
@@ -65,77 +64,77 @@ struct StringConversionHandler<QVariant> | |
| } | ||
| }; | ||
|
|
||
| QString qObjectToString(const QObject *o); | ||
| QString qObjectToString(const QObject *object); | ||
|
|
||
| template<typename Type> | ||
| struct StringConversionHandler<Type *, typename std::enable_if<std::is_base_of<InterfaceBase, Type>::value>::type> | ||
| template<typename T> | ||
| struct StringConversionHandler<T*, std::enable_if_t<std::is_base_of<InterfaceBase, T>::value>> | ||
| { | ||
| static QString toString(const Type *o) | ||
| static QString toString(const T *object) | ||
| { | ||
| return qObjectToString(o); | ||
| return qObjectToString(object); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
| template<typename Type> | ||
| struct StringConversionHandler<Type, typename std::enable_if<std::is_base_of<StructureBase, Type>::value>::type> | ||
| template<typename T> | ||
| struct StringConversionHandler<T, std::enable_if_t<std::is_base_of<StructureBase, T>::value>> | ||
| { | ||
| static QString toString(const Type &v) | ||
| static QString toString(const T &value) | ||
| { | ||
| return v.toString(); | ||
| return value.toString(); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
| template<typename Type> | ||
| struct StringConversionHandler<Type, typename std::enable_if<std::is_enum<Type>::value>::type> | ||
| template<typename T> | ||
| struct StringConversionHandler<T, std::enable_if_t<QtPrivate::IsQEnumHelper<T>::Value, T>> | ||
| { | ||
| static QString toString(const Type &v) | ||
| static QString toString(T value) | ||
| { | ||
| return facelift::enumToString(v); | ||
| return Enum::toString(value); | ||
| } | ||
| }; | ||
|
|
||
| template<typename ElementType> | ||
| struct StringConversionHandler<QList<ElementType> > | ||
| template<typename T> | ||
| struct StringConversionHandler<QList<T> > | ||
| { | ||
| static QString toString(const QList<ElementType> &v) | ||
| static QString toString(const QList<T> &v) | ||
| { | ||
| QString s; | ||
| QTextStream str(&s); | ||
| str << "[ "; | ||
| for (const auto &element : v) { | ||
| str << StringConversionHandler<ElementType>::toString(element); | ||
| str << StringConversionHandler<T>::toString(element); | ||
| str << ", "; | ||
| } | ||
| str << "]"; | ||
| return s; | ||
| } | ||
| }; | ||
|
|
||
| template<typename ElementType> | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you changing those names ??
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know the reason, why changed names, but I like the new version more. It follows general practices in software, in templates, so it should be easier to read for experienced user.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes it's not related to the current changes, but |
||
| struct StringConversionHandler<QMap<QString, ElementType> > | ||
| template<typename T> | ||
| struct StringConversionHandler<QMap<QString, T> > | ||
| { | ||
| static QString toString(const QMap<QString, ElementType> &map) | ||
| static QString toString(const QMap<QString, T> &map) | ||
| { | ||
| QString s; | ||
| QTextStream str(&s); | ||
| str << "[ "; | ||
| for (auto i = map.constBegin(); i != map.constEnd(); ++i) { | ||
| str << StringConversionHandler<QString>::toString(i.key()); | ||
| str << ":"; | ||
| str << StringConversionHandler<ElementType>::toString(i.value()); | ||
| str << StringConversionHandler<T>::toString(i.value()); | ||
| str << ", "; | ||
| } | ||
| str << "]"; | ||
| return s; | ||
| } | ||
| }; | ||
|
|
||
| template<typename Type> | ||
| inline QString toString(const Type &v) | ||
| template<typename T> | ||
| inline QString toString(const T &v) | ||
| { | ||
| return StringConversionHandler<Type>::toString(v); | ||
| return StringConversionHandler<T>::toString(v); | ||
| } | ||
|
|
||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.