summaryrefslogtreecommitdiffhomepage
path: root/options/value.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'options/value.hpp')
-rw-r--r--options/value.hpp96
1 files changed, 53 insertions, 43 deletions
diff --git a/options/value.hpp b/options/value.hpp
index e73456ca..af3cfd57 100644
--- a/options/value.hpp
+++ b/options/value.hpp
@@ -16,24 +16,19 @@
#include "value-traits.hpp"
#include "compat/macros.hpp"
-#include <cstdio>
#include <type_traits>
#include <typeinfo>
-#include <typeindex>
-#include <utility>
-#include <QVariant>
-#include <QString>
-#include <QPointF>
-#include <QList>
-#include <QMutex>
+#include <QMetaType>
namespace options {
template<typename t>
class value final : public value_
{
- using traits = detail::value_traits<t, t, void>;
+ 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)
@@ -52,22 +47,40 @@ class value final : public value_
if (!b->contains(self_name) || variant.type() == QVariant::Invalid)
return def;
- const stored_type x(variant.value<stored_type>());
+ const stored_type x { variant.value<stored_type>() };
return traits::from_value(traits::from_storage(x), def);
}
+ friend class detail::connector;
+ void bundle_value_changed() const override
+ {
+ if (!self_name.isEmpty())
+ emit valueChanged(traits::to_storage(get()));
+ }
+
+ void store_variant(const QVariant& value) override
+ {
+ if (self_name.isEmpty())
+ return;
+
+ if (value.type() == qMetaTypeId<stored_type>())
+ b->store_kv(self_name, value);
+ else
+ operator=(traits::value_from_variant(value));
+ }
+
public:
cc_noinline
- t operator=(const t& datum)
+ value<t>& operator=(const t& datum)
{
if (self_name.isEmpty())
- return def;
+ return *this;
if (datum != get())
- store(traits::to_storage(datum));
+ b->store_kv(self_name, QVariant::fromValue<stored_type>(traits::to_storage(datum)));
- return datum;
+ return *this;
}
static constexpr inline Qt::ConnectionType DIRECT_CONNTYPE = Qt::DirectConnection;
@@ -79,8 +92,8 @@ public:
def(def)
{
if (!self_name.isEmpty())
- QObject::connect(b.get(), SIGNAL(reloading()),
- this, SLOT(reload()),
+ QObject::connect(b.get(), &detail::bundle::reloading,
+ this, &value_::reload,
DIRECT_CONNTYPE);
}
@@ -96,52 +109,49 @@ public:
*this = def;
}
- operator t() const { return get(); }
+ operator t() const { return get(); } // NOLINT
- t operator->() const
- {
- return get();
- }
+ template<typename u, typename = decltype(static_cast<u>(std::declval<t>()))>
+ explicit cc_forceinline operator u() const { return to<u>(); }
- cc_noinline
- void reload() override
+ auto operator->() const
{
- if (!self_name.isEmpty())
- *this = static_cast<t>(*this);
+ struct dereference_wrapper final
+ {
+ cc_forceinline t const* operator->() const { return &x; }
+ cc_forceinline t* operator->() { return &x; }
+ t x;
+ explicit cc_forceinline dereference_wrapper(t&& x) : x(x) {}
+ };
+
+ return dereference_wrapper { get() };
}
cc_noinline
- void bundle_value_changed() const override
+ void reload() override
{
+#if 0
if (!self_name.isEmpty())
- emit valueChanged(traits::to_storage(get()));
- }
-
- t operator()() const
- {
- return get();
+ store(traits::to_storage(get()));
+#endif
}
- t operator*() const
- {
- return get();
- }
+ cc_forceinline t operator()() const { return get(); }
+ cc_forceinline t operator*() const { return get(); }
template<typename u>
u to() const
{
return static_cast<u>(get());
}
-
-private:
- const t def;
};
-#if !defined OTR_INST_VALUE
-# define OTR_INST_VALUE OTR_TEMPLATE_IMPORT
-#endif
-
+// some linker problems
#if !defined __APPLE__
+# if !defined OTR_INST_VALUE
+# define OTR_INST_VALUE OTR_TEMPLATE_IMPORT
+# endif
+
OTR_INST_VALUE(value<double>);
OTR_INST_VALUE(value<float>);
OTR_INST_VALUE(value<int>);