summaryrefslogtreecommitdiffstats
path: root/core/config/number.hh
blob: 99079936f07de2d21ee33465f9265a3f3e3efcad (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
#ifndef CORE_CONFIG_NUMBER_HH
#define CORE_CONFIG_NUMBER_HH 1
#pragma once

#include "core/config/ivalue.hh"
#include "core/math/concepts.hh"

namespace config
{
template<math::Arithmetic T>
class Number : public IValue {
public:
    explicit Number(T default_value = T(0));
    explicit Number(T default_value, T min_value, T max_value);
    virtual ~Number(void) = default;

    virtual void set(const char* value) override;
    virtual const char* get(void) const override;

    T get_value(void) const;
    void set_value(T value);

    T get_min_value(void) const;
    T get_max_value(void) const;
    void set_limits(T min_value, T max_value);

private:
    T m_value;
    T m_min_value;
    T m_max_value;
    std::string m_string;
};
} // namespace config

namespace config
{
class Int final : public Number<int> {
public:
    using Number<int>::Number;
};

class Float final : public Number<float> {
public:
    using Number<float>::Number;
};

class Unsigned final : public Number<unsigned int> {
public:
    using Number<unsigned int>::Number;
};

class Unsigned64 final : public Number<std::uint64_t> {
public:
    using Number<std::uint64_t>::Number;
};

class SizeType final : public Number<std::size_t> {
public:
    using Number<std::size_t>::Number;
};
} // namespace config

template<math::Arithmetic T>
inline config::Number<T>::Number(T default_value)
{
    m_value = default_value;
    m_min_value = std::numeric_limits<T>::lowest();
    m_max_value = std::numeric_limits<T>::max();
    m_string = std::to_string(default_value);
}

template<math::Arithmetic T>
inline config::Number<T>::Number(T default_value, T min_value, T max_value)
{
    m_value = default_value;
    m_min_value = min_value;
    m_max_value = max_value;
    m_string = std::to_string(default_value);
}

template<math::Arithmetic T>
inline void config::Number<T>::set(const char* value)
{
    std::istringstream(value) >> m_value;
    m_value = std::clamp(m_value, m_min_value, m_max_value);
    m_string = std::to_string(m_value);
}

template<math::Arithmetic T>
inline const char* config::Number<T>::get(void) const
{
    return m_string.c_str();
}

template<math::Arithmetic T>
inline T config::Number<T>::get_value(void) const
{
    return m_value;
}

template<math::Arithmetic T>
inline void config::Number<T>::set_value(T value)
{
    m_value = std::clamp(value, m_min_value, m_max_value);
    m_string = std::to_string(m_value);
}

template<math::Arithmetic T>
inline T config::Number<T>::get_min_value(void) const
{
    return m_min_value;
}

template<math::Arithmetic T>
inline T config::Number<T>::get_max_value(void) const
{
    return m_max_value;
}

template<math::Arithmetic T>
inline void config::Number<T>::set_limits(T min_value, T max_value)
{
    m_min_value = min_value;
    m_max_value = max_value;
    m_value = std::clamp(m_value, m_min_value, m_max_value);
    m_string = std::to_string(m_value);
}

#endif // CORE_CONFIG_NUMBER_HH