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 <info@kdab.com>
Author: Volker Krause <volker.krause@kdab.com>
SPDX-License-Identifier: GPL-2.0-or-later
Contact KDAB at <info@kdab.com> 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
|