diff options
Diffstat (limited to 'options/value.hpp')
-rw-r--r-- | options/value.hpp | 75 |
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()); } }; |