Skip to content

Commit 8597edf

Browse files
Oleksandr KunichikOleksandr Kunichik
authored andcommitted
add QMetaEnum usage for autogenerated code
1 parent 8f4d2e9 commit 8597edf

File tree

5 files changed

+78
-70
lines changed

5 files changed

+78
-70
lines changed

codegen/facelift/templates/Enum.template.h

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,37 +74,20 @@ template<> inline const std::initializer_list<{{enum.fullyQualifiedCppType}}>& v
7474
return values;
7575
}
7676

77-
template <> inline QString enumToString(const {{enum.fullyQualifiedCppType}}& v)
78-
{
79-
const char* s = "Invalid";
80-
switch(v) {
81-
{% for member in enum.members %}
82-
case {{enum.fullyQualifiedCppType}}::{{member}}:
83-
s = "{{member}}";
84-
break;
85-
{% endfor %}
86-
default:
87-
break;
88-
}
89-
return s;
90-
}
9177

92-
}
78+
} // end namespace facelift
9379

94-
95-
inline void assignFromString(const QString &s, {{enum.fullyQualifiedCppType}}& v)
80+
inline void fromString(const QString& string, {{enum.fullyQualifiedCppType}}& value)
9681
{
97-
{% for member in enum.members %}
98-
if (s == "{{member}}")
99-
v = {{enum.fullyQualifiedCppType}}::{{member}};
100-
else
101-
{% endfor %}
102-
::facelift::onAssignFromStringError(s);
82+
auto valuePointer = facelift::Enum::fromString<{{enum.fullyQualifiedCppType}}>(string);
83+
if(!valuePointer) {
84+
facelift::Enum::fromStringError(string);
85+
}
86+
value = *valuePointer;
10387
}
10488

105-
106-
inline QTextStream &operator <<(QTextStream &outStream, const {{enum.fullyQualifiedCppType}}& f)
89+
inline QTextStream &operator <<(QTextStream& outStream, const {{enum.fullyQualifiedCppType}}& value)
10790
{
108-
outStream << facelift::enumToString(f);
91+
outStream << facelift::Enum::toString(value);
10992
return outStream;
11093
}

src/model/FaceliftCommon.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,6 @@ inline const std::initializer_list<Type> &validValues()
6666
return l;
6767
}
6868

69-
70-
template<typename Type>
71-
QString enumToString(const Type &v)
72-
{
73-
Q_UNUSED(v);
74-
static_assert(!std::is_enum<Type>::value, "Missing specialization of enumToString() template");
75-
return "";
76-
}
77-
7869
#ifdef QT_DEBUG
7970
#define faceliftSeriousError qFatal
8071
#else

src/model/FaceliftEnum.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,15 @@
3232
#include <QDebug>
3333

3434
namespace facelift {
35+
36+
namespace Enum {
3537

36-
void onAssignFromStringError(const QString &s)
38+
void fromStringError(const QString &string)
3739
{
38-
qFatal("No enum value matching string %s", qPrintable(s));
40+
qFatal("No enum value matching string %s", qPrintable(string));
3941
}
4042

41-
}
43+
44+
} // end namespace Enum
45+
46+
} // end namespace facelift

src/model/FaceliftEnum.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,41 @@
3131
#pragma once
3232

3333
#include "FaceliftCommon.h"
34-
#include <QObject>
35-
#include <QTextStream>
34+
#include <type_traits>
35+
#include <memory>
36+
#include <QString>
37+
#include <QMetaEnum>
38+
#include <QByteArray>
3639

3740
namespace facelift {
3841

39-
void onAssignFromStringError(const QString &s);
42+
namespace Enum {
4043

44+
void fromStringError(const QString &string);
45+
46+
// Returns the string that is used as the name of the given enumeration value,
47+
// or an empty string if value is not defined
48+
template<class T, std::enable_if_t<QtPrivate::IsQEnumHelper<T>::Value, T>* = nullptr>
49+
QString toString(T value)
50+
{
51+
return QMetaEnum::fromType<T>().valueToKey(static_cast<int>(value));
52+
}
53+
54+
// Returns the enumaration value of the given enumeration key, or nullptr if key is not defined.
55+
// TODO change std::unique_ptr to std::optional when it will be possible
56+
template<typename T>
57+
std::unique_ptr<T> fromString(const QString &string)
58+
{
59+
QByteArray byteArray = string.toLocal8Bit();
60+
bool ok {};
61+
int value = QMetaEnum::fromType<T>().keyToValue(byteArray.data(), &ok);
62+
63+
T result = static_cast<T>(value);
64+
65+
return ok ? std::make_unique<T>(result) : nullptr;
4166
}
67+
68+
69+
} // end namespace Enum
70+
71+
} // end namespace facelift

src/model/StringConversionHandler.h

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,17 @@
3737
#include <QList>
3838
#include <type_traits>
3939
#include "FaceliftCommon.h"
40+
#include "FaceliftEnum.h"
4041

4142
namespace facelift {
4243

4344
class InterfaceBase;
4445
class StructureBase;
4546

46-
template<typename Type, typename Enable = void>
47+
template<typename T, typename Enable = void>
4748
struct StringConversionHandler
4849
{
49-
typedef Type QMLType;
50-
51-
static QString toString(const Type &v)
50+
static QString toString(const T &v)
5251
{
5352
QString s;
5453
QTextStream(&s) << v;
@@ -65,77 +64,77 @@ struct StringConversionHandler<QVariant>
6564
}
6665
};
6766

68-
QString qObjectToString(const QObject *o);
67+
QString qObjectToString(const QObject *object);
6968

70-
template<typename Type>
71-
struct StringConversionHandler<Type *, typename std::enable_if<std::is_base_of<InterfaceBase, Type>::value>::type>
69+
template<typename T>
70+
struct StringConversionHandler<T*, std::enable_if_t<std::is_base_of<InterfaceBase, T>::value>>
7271
{
73-
static QString toString(const Type *o)
72+
static QString toString(const T *object)
7473
{
75-
return qObjectToString(o);
74+
return qObjectToString(object);
7675
}
7776
};
7877

7978

80-
template<typename Type>
81-
struct StringConversionHandler<Type, typename std::enable_if<std::is_base_of<StructureBase, Type>::value>::type>
79+
template<typename T>
80+
struct StringConversionHandler<T, std::enable_if_t<std::is_base_of<StructureBase, T>::value>>
8281
{
83-
static QString toString(const Type &v)
82+
static QString toString(const T &value)
8483
{
85-
return v.toString();
84+
return value.toString();
8685
}
8786
};
8887

89-
90-
template<typename Type>
91-
struct StringConversionHandler<Type, typename std::enable_if<std::is_enum<Type>::value>::type>
88+
template<typename T>
89+
struct StringConversionHandler<T, std::enable_if_t<QtPrivate::IsQEnumHelper<T>::Value, T>>
9290
{
93-
static QString toString(const Type &v)
91+
static QString toString(T value)
9492
{
95-
return facelift::enumToString(v);
93+
return Enum::toString(value);
9694
}
9795
};
9896

99-
template<typename ElementType>
100-
struct StringConversionHandler<QList<ElementType> >
97+
template<typename T>
98+
struct StringConversionHandler<QList<T> >
10199
{
102-
static QString toString(const QList<ElementType> &v)
100+
static QString toString(const QList<T> &v)
103101
{
104102
QString s;
105103
QTextStream str(&s);
106104
str << "[ ";
107105
for (const auto &element : v) {
108-
str << StringConversionHandler<ElementType>::toString(element);
106+
str << StringConversionHandler<T>::toString(element);
109107
str << ", ";
110108
}
111109
str << "]";
112110
return s;
113111
}
114112
};
115113

116-
template<typename ElementType>
117-
struct StringConversionHandler<QMap<QString, ElementType> >
114+
template<typename T>
115+
struct StringConversionHandler<QMap<QString, T> >
118116
{
119-
static QString toString(const QMap<QString, ElementType> &map)
117+
static QString toString(const QMap<QString, T> &map)
120118
{
121119
QString s;
122120
QTextStream str(&s);
123121
str << "[ ";
124122
for (auto i = map.constBegin(); i != map.constEnd(); ++i) {
125123
str << StringConversionHandler<QString>::toString(i.key());
126124
str << ":";
127-
str << StringConversionHandler<ElementType>::toString(i.value());
125+
str << StringConversionHandler<T>::toString(i.value());
128126
str << ", ";
129127
}
130128
str << "]";
131129
return s;
132130
}
133131
};
134132

135-
template<typename Type>
136-
inline QString toString(const Type &v)
133+
template<typename T>
134+
inline QString toString(const T &v)
137135
{
138-
return StringConversionHandler<Type>::toString(v);
136+
return StringConversionHandler<T>::toString(v);
139137
}
140138

139+
141140
}

0 commit comments

Comments
 (0)