forked from KDAB/GammaRay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetaenum.h
136 lines (111 loc) · 3.44 KB
/
metaenum.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
metaenum.h
This file is part of GammaRay, the Qt application inspection and manipulation tool.
SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Volker Krause <[email protected]>
SPDX-License-Identifier: GPL-2.0-or-later
Contact KDAB at <[email protected]> for commercial licensing options.
*/
#ifndef GAMMARAY_METAENUM_H
#define GAMMARAY_METAENUM_H
#include <QStringList>
#include <type_traits>
namespace GammaRay {
/** Enum/flag stringification utilities. */
namespace MetaEnum {
template<typename T>
struct Value
{
T value;
const char *const name;
};
template<typename T, std::size_t N>
std::size_t count(const Value<T> (&)[N])
{
return N;
}
template<typename T, std::size_t N>
QString enumToString(T value, const Value<T> (&lookupTable)[N])
{
for (std::size_t i = 0; i < N; ++i) {
if (lookupTable[i].value == value)
return QString::fromUtf8(lookupTable[i].name);
}
return QStringLiteral("unknown (") + QString::number(value) + ')';
}
template<typename T, typename F, std::size_t N>
QString flagsToString(T flags, const Value<F> (&lookupTable)[N])
{
QStringList l;
T handledFlags = T();
for (std::size_t i = 0; i < N; ++i) {
if (flags & lookupTable[i].value) {
l.push_back(QString::fromUtf8(lookupTable[i].name));
}
handledFlags |= lookupTable[i].value;
}
if (flags & ~handledFlags) {
l.push_back(QStringLiteral("flag 0x") + QString::number(qulonglong(flags & ~handledFlags), 16));
}
if (l.isEmpty()) {
// check if we have a special 0-value
for (std::size_t i = 0; i < N; ++i) {
if (lookupTable[i].value == 0)
return QString::fromUtf8(lookupTable[i].name);
}
return QStringLiteral("<none>");
}
return l.join(QStringLiteral("|"));
}
// functors for easy use with VariantHandler::registerStringConverter
namespace detail {
template<typename T, std::size_t N>
class enum_to_string_functor
{
public:
explicit enum_to_string_functor(const MetaEnum::Value<T> (&lookupTable)[N])
: m_lookupTable(lookupTable)
{
}
QString operator()(T value)
{
return MetaEnum::enumToString(value, m_lookupTable);
}
private:
const MetaEnum::Value<T> (&m_lookupTable)[N];
};
template<typename T, std::size_t N>
class flags_to_string_functor
{
public:
explicit flags_to_string_functor(const MetaEnum::Value<T> (&lookupTable)[N])
: m_lookupTable(lookupTable)
{
}
#if !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // krazy:exclude=cpp to deal with older MS compilers
QString operator()(typename std::underlying_type<T>::type value)
#else
QString operator()(unsigned int value)
#endif
{
return MetaEnum::flagsToString(value, m_lookupTable);
}
private:
const MetaEnum::Value<T> (&m_lookupTable)[N];
};
}
/** Creates a functor for MetaEnum::enumToString and a specific lookup table. */
template<typename T, std::size_t N>
detail::enum_to_string_functor<T, N> enumToString_fn(const Value<T> (&lookupTable)[N])
{
return detail::enum_to_string_functor<T, N>(lookupTable);
}
/** Creates a functor for MetaEnum::flagsToString and a specific lookup table. */
template<typename T, std::size_t N>
detail::flags_to_string_functor<T, N> flagsToString_fn(const Value<T> (&lookupTable)[N])
{
return detail::flags_to_string_functor<T, N>(lookupTable);
}
} // MetaEnum
} // GammaRay
#endif