summaryrefslogtreecommitdiffhomepage
path: root/options/value-traits.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'options/value-traits.hpp')
-rw-r--r--options/value-traits.hpp125
1 files changed, 104 insertions, 21 deletions
diff --git a/options/value-traits.hpp b/options/value-traits.hpp
index 1c98f3e9..3ab623da 100644
--- a/options/value-traits.hpp
+++ b/options/value-traits.hpp
@@ -1,62 +1,145 @@
#pragma once
-#include "export.hpp"
-
#include "slider.hpp"
+#include "export.hpp"
#include <QString>
+#include <cinttypes>
#include <type_traits>
namespace options::detail {
+template<typename t, typename Enable = void>
+struct value_traits;
+
template<typename t, typename u = t, typename Enable = void>
struct default_value_traits
{
- virtual ~default_value_traits() = default;
+ using stored_type = std::decay_t<u>;
+ using value_type = std::decay_t<t>;
- using stored_type = std::decay_t<t>;
- using value_type = std::decay_t<u>;
+ using self = value_traits<t>;
- static value_type from_value(const value_type& val, const value_type&) { return val; }
- static value_type from_storage(const stored_type& x) { return static_cast<value_type>(x); }
- static stored_type to_storage(const value_type& val) { return static_cast<stored_type>(val); }
+ static value_type value_with_default(const value_type& val, const value_type&)
+ {
+ return val;
+ }
- static value_type value_from_variant(const QVariant& x)
+ static value_type value_from_storage(const stored_type& x)
{
- return from_storage(storage_from_variant(x));
+ return static_cast<value_type>(x);
}
- static stored_type storage_from_variant(const QVariant& x)
+ static stored_type storage_from_value(const value_type& val)
{
+ return static_cast<stored_type>(val);
+ }
+
+ static value_type value_from_qvariant(const QVariant& x)
+ {
+ return self::value_from_storage(self::storage_from_qvariant(x));
+ }
+
+ static QVariant qvariant_from_value(const value_type& val)
+ {
+ return self::qvariant_from_storage(self::storage_from_value(val));
+ }
+
+ static constexpr inline
+ value_type pass_value(const value_type& x)
+ {
+ if constexpr(std::is_same_v<value_type, stored_type>)
+ return x;
+ else
+ return self::value_from_storage(self::storage_from_value(x));
+ }
+
+ static stored_type storage_from_qvariant(const QVariant& x)
+ {
+ // XXX TODO
return x.value<stored_type>();
}
+
+ static QVariant qvariant_from_storage(const stored_type& val)
+ {
+ // XXX TODO
+ return QVariant::fromValue<stored_type>(val);
+ }
+
+ static bool is_equal(const value_type& x, const value_type& y)
+ {
+ return x == y;
+ }
};
-template<typename t, typename u = t, typename Enable = void>
-struct value_traits : default_value_traits<t, u, Enable>
+template<typename t, typename Enable>
+struct value_traits : default_value_traits<t> {};
+
+template<>
+struct value_traits<double> : default_value_traits<double>
{
+ static bool is_equal(value_type x, value_type y)
+ {
+ if (x == y)
+ return true;
+ else
+ {
+ using I = std::int64_t;
+ constexpr int K = 1000;
+
+ value_type x_, y_;
+
+ return I(std::round(std::modf(x, &x_) * K)) == I(std::round(std::modf(y, &y_) * K)) &&
+ I(std::round(x_)) == I(std::round(y_));
+ }
+ }
};
-template<>
-struct value_traits<slider_value> : default_value_traits<slider_value>
+template<> struct value_traits<bool> : default_value_traits<bool, int>
{
- static inline slider_value from_value(const slider_value& val, const slider_value& def)
+ static stored_type storage_from_qvariant(const QVariant& x)
{
- return { val.cur(), def.min(), def.max() };
+ if (x.type() == QVariant::String)
+ return x.toBool();
+ else
+ return !!x.toInt();
+ }
+
+ static QVariant qvariant_from_storage(const stored_type& val)
+ {
+ return QVariant::fromValue<int>(!!val);
+ }
+
+ static value_type value_from_storage(const stored_type& x)
+ {
+ return !!x;
}
};
-// Qt uses int a lot in slots so use it for all enums
-template<typename t>
-struct value_traits<t, t, std::enable_if_t<std::is_enum_v<t>>> : public default_value_traits<int, t>
+template<> struct value_traits<float> : value_traits<float, double>
{
+ static constexpr inline value_type pass_value(const value_type& x) { return x; }
};
template<>
-struct value_traits<float> : public default_value_traits<float, double, void>
+struct value_traits<slider_value> : default_value_traits<slider_value>
{
+ static slider_value value_with_default(const slider_value& val, const slider_value& def)
+ {
+ return { val.cur(), def.min(), def.max() };
+ }
+
+ static bool is_equal(const slider_value& x, const slider_value& y)
+ {
+ using tr = value_traits<double>;
+ return tr::is_equal(x.cur(), y.cur());
+ }
};
+// Qt uses int a lot in slots so use it for all enums
+template<typename t>
+struct value_traits<t, std::enable_if_t<std::is_enum_v<t>>> : default_value_traits<t, int> {};
+
} // ns options::detail