summaryrefslogtreecommitdiffhomepage
path: root/options/value-traits.hpp
blob: e676f9422590b6946a3b0ab2596059642b49c098 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#pragma once

#include "slider.hpp"
#include "export.hpp"

#include <cmath>
#include <type_traits>

#include <QString>

namespace options::detail {
template<typename t>
using cv_qualified =
    std::conditional_t<std::is_fundamental_v<std::remove_cvref_t<t>>,
                       std::remove_cvref_t<t>,
                       std::add_lvalue_reference_t<std::add_const_t<std::remove_cvref_t<t>>>>;

template<typename t, typename = void>
struct maybe_enum_type {
    using type = t;
};
template<typename t>
struct maybe_enum_type<t, std::enable_if_t<std::is_enum_v<t>>> {
    using type = int;
};

template<typename t> using maybe_enum_type_t = typename maybe_enum_type<t>::type;

template<typename t, typename u = t, typename Enable = void>
struct default_value_traits
{
    using value_type = t;
    using stored_type = u;

    static inline
    value_type value_with_default(cv_qualified<value_type> val, cv_qualified<value_type>)
    {
        return val;
    }

    static inline
    value_type value_from_storage(cv_qualified<stored_type> x)
    {
        return static_cast<value_type>(x);
    }

    static inline
    stored_type storage_from_value(cv_qualified<value_type> val)
    {
        return static_cast<stored_type>(val);
    }

    static inline
    value_type value_from_qvariant(const QVariant& x)
    {
        return value_from_storage(storage_from_qvariant(x));
    }

    static inline
    QVariant qvariant_from_value(cv_qualified<value_type> val)
    {
        return qvariant_from_storage(storage_from_value(val));
    }

    static constexpr inline
    value_type pass_value(cv_qualified<value_type> x)
    {
        if constexpr(std::is_same_v<value_type, stored_type>)
            return x;
        else
            return value_from_storage(storage_from_value(x));
    }

    static inline
    stored_type storage_from_qvariant(const QVariant& x)
    {
        // XXX TODO
        return x.value<stored_type>();
    }

    static inline
    QVariant qvariant_from_storage(cv_qualified<stored_type> val)
    {
        // XXX TODO
        return QVariant::fromValue<stored_type>(val);
    }

    static inline
    bool is_equal(cv_qualified<value_type> x, cv_qualified<value_type> y)
    {
        return x == y;
    }
};

template<typename t, typename Enable = void>
struct value_traits : default_value_traits<t> {};

template<>
inline
bool default_value_traits<double>::is_equal(double x, double y)
{
    return std::fabs(x - y) < 1e-6;
}

template<> struct value_traits<float, double> : default_value_traits<float> {};

template<>
inline
bool default_value_traits<float, double>::is_equal(float x, float y)
{
    return std::fabs(x - y) < 1e-6f;
}

template<>
inline
slider_value default_value_traits<slider_value>::value_with_default(cv_qualified<slider_value> val, cv_qualified<slider_value> def)
{
    return { val.cur(), def.min(), def.max() };
}

template<>
inline
bool default_value_traits<slider_value>::is_equal(cv_qualified<slider_value> x, cv_qualified<slider_value> y)
{
    return value_traits<double>::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