#pragma once #include "slider.hpp" #include "export.hpp" #include #include #include namespace options::detail { template struct value_traits; template struct default_value_traits { using stored_type = std::decay_t; using value_type = std::decay_t; using self = value_traits; static value_type value_with_default(const value_type& val, const value_type&) { return val; } static value_type value_from_storage(const stored_type& x) { return static_cast(x); } static stored_type storage_from_value(const value_type& val) { return static_cast(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) 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(); } static QVariant qvariant_from_storage(const stored_type& val) { // XXX TODO return QVariant::fromValue(val); } static bool is_equal(const value_type& x, const value_type& y) { return x == y; } }; template struct value_traits : default_value_traits {}; template<> struct value_traits : default_value_traits { 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 : default_value_traits { static stored_type storage_from_qvariant(const QVariant& x) { if (x.type() == QVariant::String) return x.toBool(); else return !!x.toInt(); } static QVariant qvariant_from_storage(const stored_type& val) { return QVariant::fromValue(!!val); } static value_type value_from_storage(const stored_type& x) { return !!x; } }; template<> struct value_traits : value_traits { static constexpr inline value_type pass_value(const value_type& x) { return x; } }; template<> struct value_traits : default_value_traits { 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; return tr::is_equal(x.cur(), y.cur()); } }; // Qt uses int a lot in slots so use it for all enums template struct value_traits>> : default_value_traits {}; } // ns options::detail