summaryrefslogtreecommitdiffhomepage
path: root/options/value.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'options/value.hpp')
-rw-r--r--options/value.hpp75
1 files changed, 28 insertions, 47 deletions
diff --git a/options/value.hpp b/options/value.hpp
index bfa8b352..887f0d39 100644
--- a/options/value.hpp
+++ b/options/value.hpp
@@ -23,51 +23,47 @@
namespace options::detail {
template<typename t>
- struct dereference_wrapper final
+ class dereference_wrapper final
{
- cc_forceinline constexpr t const* operator->() const { return &x; }
- cc_forceinline constexpr t* operator->() { return &x; }
t x;
- constexpr explicit cc_forceinline dereference_wrapper(t&& x) : x(x) {}
+ public:
+ constexpr t const* operator->() const { return &x; }
+ constexpr t* operator->() { return &x; }
+ constexpr explicit dereference_wrapper(t&& x) : x(x) {}
};
} // ns options::detail
namespace options {
-template<typename t>
+template<typename u>
class value final : public value_
{
+ using t = std::conditional_t<std::is_enum_v<remove_cvref_t<u>>,
+ std::decay_t<u>,
+ remove_cvref_t<u>>;
const t def;
using traits = detail::value_traits<t>;
- using stored_type = typename traits::stored_type;
-
- static bool is_equal(const QVariant& val1, const QVariant& val2)
- {
- return val1.value<stored_type>() == val2.value<stored_type>();
- }
cc_noinline
t get() const
{
- if (self_name.isEmpty())
- return def;
+ if (self_name.isEmpty() || !b->contains(self_name))
+ return traits::pass_value(def);
- QVariant variant = b->get<QVariant>(self_name);
+ QVariant variant = b->get_variant(self_name);
- if (!b->contains(self_name) || variant.type() == QVariant::Invalid)
- return def;
+ if (variant.isNull() || !variant.isValid())
+ return traits::pass_value(def);
- const stored_type x { variant.value<stored_type>() };
-
- return traits::from_value(traits::from_storage(x), def);
+ return traits::pass_value(traits::value_with_default(traits::value_from_qvariant(variant), def));
}
friend class detail::connector;
void bundle_value_changed() const override
{
if (!self_name.isEmpty())
- emit valueChanged(traits::to_storage(get()));
+ emit valueChanged(traits::storage_from_value(get()));
}
void store_variant(const QVariant& value) override
@@ -75,21 +71,20 @@ class value final : public value_
if (self_name.isEmpty())
return;
- if (value.type() == qMetaTypeId<stored_type>())
+ if (traits::is_equal(get(), traits::value_from_qvariant(value)))
+ return;
+
+ if (value.isValid() && !value.isNull())
b->store_kv(self_name, value);
else
- operator=(traits::value_from_variant(value));
+ b->store_kv(self_name, traits::qvariant_from_value(def));
}
public:
cc_noinline
- value<t>& operator=(const t& datum)
+ value<u>& operator=(const t& datum)
{
- if (self_name.isEmpty())
- return *this;
-
- if (datum != get())
- b->store_kv(self_name, QVariant::fromValue<stored_type>(traits::to_storage(datum)));
+ store_variant(traits::qvariant_from_value(traits::pass_value(datum)));
return *this;
}
@@ -99,13 +94,8 @@ public:
cc_noinline
value(bundle b, const QString& name, t def) :
- value_(b, name, &is_equal, std::type_index(typeid(stored_type))),
- def(def)
+ value_(b, name), def(def)
{
- if (!self_name.isEmpty())
- QObject::connect(b.get(), &detail::bundle::reloading,
- this, &value_::reload,
- DIRECT_CONNTYPE);
}
cc_noinline
@@ -120,7 +110,7 @@ public:
*this = def;
}
- operator t() const { return get(); } // NOLINT
+ operator t() const { return get(); }
template<typename u, typename = decltype(static_cast<u>(std::declval<t>()))>
explicit cc_forceinline operator u() const { return to<u>(); }
@@ -130,22 +120,13 @@ public:
return detail::dereference_wrapper<t>{get()};
}
- cc_noinline
- void reload() override
- {
-#if 0
- if (!self_name.isEmpty())
- store(traits::to_storage(get()));
-#endif
- }
-
cc_forceinline t operator()() const { return get(); }
cc_forceinline t operator*() const { return get(); }
- template<typename u>
- u to() const
+ template<typename w>
+ w to() const
{
- return static_cast<u>(get());
+ return static_cast<w>(get());
}
};