Implement enum support in CachedSettingValue

Enums are stored as strings, that improves configuration file
readability and maintainability. String values are obtained via
QMetaEnum, and since with Qt 5.5 QMetaEnum::fromType() includes a
static_assert, this has to be a safe method.
This commit is contained in:
Eugene Shalygin 2017-07-05 12:19:58 +02:00
parent 8e6df572a8
commit a22d2f0139
5 changed files with 71 additions and 49 deletions

View file

@ -30,7 +30,10 @@
#define SETTINGVALUE_H
#include <functional>
#include <type_traits>
#include <QMetaEnum>
#include <QString>
#include <QVariant>
#include "settingsstorage.h"
@ -42,16 +45,14 @@ class CachedSettingValue
public:
explicit CachedSettingValue(const char *keyName, const T &defaultValue = T())
: m_keyName(QLatin1String(keyName))
, m_value(SettingsStorage::instance()->loadValue(
m_keyName, defaultValue).template value<T>())
, m_value(loadValue(defaultValue))
{
}
explicit CachedSettingValue(const char *keyName, const T &defaultValue
, const ProxyFunc &proxyFunc)
: m_keyName(QLatin1String(keyName))
, m_value(proxyFunc(SettingsStorage::instance()->loadValue(
m_keyName, defaultValue).template value<T>()))
, m_value(proxyFunc(loadValue(defaultValue)))
{
}
@ -68,11 +69,45 @@ public:
CachedSettingValue<T> &operator=(const T &newValue)
{
m_value = newValue;
SettingsStorage::instance()->storeValue(m_keyName, m_value);
storeValue(m_value);
return *this;
}
private:
// regular load/save pair
template <typename U, typename std::enable_if<!std::is_enum<U>::value, int>::type = 0>
U loadValue(const U &defaultValue)
{
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value<T>();
}
template <typename U, typename std::enable_if<!std::is_enum<U>::value, int>::type = 0>
void storeValue(const U &value)
{
SettingsStorage::instance()->storeValue(m_keyName, value);
}
// load/save pair for enum
// saves literal value of the enum constant, obtained from QMetaEnum
template <typename U, typename std::enable_if<std::is_enum<U>::value, int>::type = 0>
U loadValue(const U &defaultValue)
{
static_assert(std::is_same<int, typename std::underlying_type<U>::type>::value,
"Enumeration underlying type has to be int");
bool ok = false;
const U res = static_cast<U>(QMetaEnum::fromType<U>().keyToValue(
SettingsStorage::instance()->loadValue(m_keyName, QString()).toString().toLatin1().constData(), &ok));
return ok ? res : defaultValue;
}
template <typename U, typename std::enable_if<std::is_enum<U>::value, int>::type = 0>
void storeValue(const U &value)
{
SettingsStorage::instance()->storeValue(m_keyName,
QString::fromLatin1(QMetaEnum::fromType<U>().valueToKey(static_cast<int>(value))));
}
const QString m_keyName;
T m_value;
};