settings: Fix MSVC issues

According to https://stackoverflow.com/questions/469508, we run into a
MSVC bug (since VS 2005) when using diamond inheritance for
RangedSetting.

This explicitly implements those functions in RangedSetting. GetValue is
implemented as just calling the inherited version. The explicit
converson operator is reimplemented. I opted for this over ignoring the
warning with a pragma since this specifies the inherited behavior, and I
have now less faith in MSVC to pick the right one.

In addition, we mark destructors as virtual to silence what I believe is
a fair MSVC compilation error.
This commit is contained in:
lat9nq 2021-08-11 15:49:01 -07:00
parent e6b80c2cf8
commit 5be2d6fd28
1 changed files with 22 additions and 7 deletions

View File

@ -75,7 +75,7 @@ public:
*/ */
explicit BasicSetting(const Type& default_val, const std::string& name) explicit BasicSetting(const Type& default_val, const std::string& name)
: default_value{default_val}, global{default_val}, label{name} {} : default_value{default_val}, global{default_val}, label{name} {}
~BasicSetting() = default; virtual ~BasicSetting() = default;
/** /**
* Returns a reference to the setting's value. * Returns a reference to the setting's value.
@ -161,7 +161,7 @@ public:
explicit BasicRangedSetting(const Type& default_val, const Type& min_val, const Type& max_val, explicit BasicRangedSetting(const Type& default_val, const Type& min_val, const Type& max_val,
const std::string& name) const std::string& name)
: BasicSetting<Type>{default_val, name}, minimum{min_val}, maximum{max_val} {} : BasicSetting<Type>{default_val, name}, minimum{min_val}, maximum{max_val} {}
~BasicRangedSetting() = default; virtual ~BasicRangedSetting() = default;
/** /**
* Like BasicSetting's SetValue, except value is clamped to the range of the setting. * Like BasicSetting's SetValue, except value is clamped to the range of the setting.
@ -208,7 +208,7 @@ public:
*/ */
explicit Setting(const Type& default_val, const std::string& name) explicit Setting(const Type& default_val, const std::string& name)
: BasicSetting<Type>(default_val, name) {} : BasicSetting<Type>(default_val, name) {}
~Setting() = default; virtual ~Setting() = default;
/** /**
* Tells this setting to represent either the global or custom setting when other member * Tells this setting to represent either the global or custom setting when other member
@ -237,13 +237,13 @@ public:
* *
* @returns The required value of the setting * @returns The required value of the setting
*/ */
[[nodiscard]] const Type& GetValue() const override { [[nodiscard]] virtual const Type& GetValue() const override {
if (use_global) { if (use_global) {
return this->global; return this->global;
} }
return custom; return custom;
} }
[[nodiscard]] const Type& GetValue(bool need_global) const { [[nodiscard]] virtual const Type& GetValue(bool need_global) const {
if (use_global || need_global) { if (use_global || need_global) {
return this->global; return this->global;
} }
@ -286,7 +286,7 @@ public:
* *
* @returns A reference to the current setting value * @returns A reference to the current setting value
*/ */
explicit operator const Type&() const override { virtual explicit operator const Type&() const override {
if (use_global) { if (use_global) {
return this->global; return this->global;
} }
@ -318,7 +318,22 @@ public:
: BasicSetting<Type>{default_val, name}, : BasicSetting<Type>{default_val, name},
BasicRangedSetting<Type>{default_val, min_val, max_val, name}, Setting<Type>{default_val, BasicRangedSetting<Type>{default_val, min_val, max_val, name}, Setting<Type>{default_val,
name} {} name} {}
~RangedSetting() = default; virtual ~RangedSetting() = default;
// The following are needed to avoid a MSVC bug
// (source: https://stackoverflow.com/questions/469508)
[[nodiscard]] const Type& GetValue() const override {
return Setting<Type>::GetValue();
}
[[nodiscard]] const Type& GetValue(bool need_global) const override {
return Setting<Type>::GetValue(need_global);
}
explicit operator const Type&() const override {
if (this->use_global) {
return this->global;
}
return this->custom;
}
/** /**
* Like BasicSetting's SetValue, except value is clamped to the range of the setting. Sets the * Like BasicSetting's SetValue, except value is clamped to the range of the setting. Sets the