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