HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
fixed.hpp
1// Copyright 2019 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include "TTauri/Foundation/required.hpp"
7#include "TTauri/Foundation/string_tag.hpp"
8#include "TTauri/Foundation/safe_int.hpp"
9#include <type_traits>
10#include <limits>
11
12namespace tt {
13
14template<typename T, int M>
15struct fixed {
16 using value_type = T;
17 static constexpr int multiplier = M;
18
19 T value;
20
21 fixed() = default;
22 ~fixed() = default;
23 fixed(fixed const &) = default;
24 fixed &operator=(fixed const &) = default;
25 fixed(fixed &&) = default;
26 fixed &operator=(fixed &&) = default;
27
28 template<typename O, std::enable_if_t<std::is_floating_point_v<O>, int> = 0>
29 explicit constexpr fixed(O other) noexcept :
30 value(static_cast<T>(other * M)) {
31 tt_assert(
32 other >= (std::numeric_limits<T>::min() / M) &&
33 other <= (std::numeric_limits<T>::max() / M)
34 );
35 }
36
37 template<typename O, std::enable_if_t<std::is_integral_v<O>, int> = 0>
38 explicit constexpr fixed(O other) noexcept :
39 value(static_cast<T>(other) * M) {
40 tt_assert(
41 other >= (std::numeric_limits<T>::min() / M) &&
42 other <= (std::numeric_limits<T>::max() / M)
43 );
44 }
45
46 explicit fixed(std::string const &other) :
47 fixed(stod(other)) {}
48
49 template<typename O, std::enable_if_t<std::is_floating_point_v<O>, int> = 0>
50 constexpr fixed &operator=(O other) noexcept {
51 value = static_cast<T>(other * M);
52 tt_assert(
53 other >= (std::numeric_limits<T>::min() / M) &&
54 other <= (std::numeric_limits<T>::max() / M)
55 );
56 return *this;
57 }
58
59 template<typename O, std::enable_if_t<std::is_integral_v<O>, int> = 0>
60 constexpr fixed &operator=(O other) noexcept {
61 value = static_cast<T>(other) * M;
62 tt_assert(
63 other >= (std::numeric_limits<T>::min() / M) &&
64 other <= (std::numeric_limits<T>::max() / M)
65 );
66 return *this;
67 }
68
69 fixed &operator=(std::string const &other) {
70 value = static_cast<T>(stod(other) * M);
71 tt_assert(
72 other >= (std::numeric_limits<T>::min() / M) &&
73 other <= (std::numeric_limits<T>::max() / M)
74 );
75 return *this;
76 }
77
78 template<typename O, std::enable_if_t<std::is_floating_point_v<O>, int> = 0>
79 explicit operator O () const noexcept {
80 return static_cast<O>(value) / M;
81 }
82
83 template<typename O, std::enable_if_t<std::is_integral_v<O>, int> = 0>
84 explicit operator O () const noexcept {
85 return static_cast<O>(value / M);
86 }
87
88 std::string string() const noexcept {
89 return fmt::format("{}", static_cast<double>(value) / M);
90 }
91
92 static fixed fromValue(T value) noexcept {
93 fixed r;
94 r.value = value;
95 return r;
96 }
97};
98
99template<typename T, int M> inline bool operator==(fixed<T,M> const &lhs, fixed<T,M> const &rhs) { return lhs.value == rhs.value; }
100template<typename T, int M> inline bool operator!=(fixed<T,M> const &lhs, fixed<T,M> const &rhs) { return lhs.value != rhs.value; }
101template<typename T, int M> inline bool operator<(fixed<T,M> const &lhs, fixed<T,M> const &rhs) { return lhs.value < rhs.value; }
102template<typename T, int M> inline bool operator>(fixed<T,M> const &lhs, fixed<T,M> const &rhs) { return lhs.value > rhs.value; }
103template<typename T, int M> inline bool operator<=(fixed<T,M> const &lhs, fixed<T,M> const &rhs) { return lhs.value <= rhs.value; }
104template<typename T, int M> inline bool operator>=(fixed<T,M> const &lhs, fixed<T,M> const &rhs) { return lhs.value >= rhs.value; }
105
106template<typename T, int M>
107fixed<T,M> operator+(fixed<T,M> const &lhs, fixed<T,M> const &rhs)
108{
109 return fixed<T,M>::fromValue(lhs.value + rhs.value);
110}
111
112template<typename T, int M>
113fixed<T,M> operator-(fixed<T,M> const &lhs, fixed<T,M> const &rhs)
114{
115 return fixed<T,M>::fromValue(lhs.value - rhs.value);
116}
117
118template<typename T, int M>
119std::string to_string(fixed<T,M> const v)
120{
121 return v.string();
122}
123
124template<typename T, int M>
125std::ostream &operator<<(std::ostream &lhs, fixed<T,M> const &rhs)
126{
127 return lhs << rhs.string();
128}
129
130using money = fixed<safe_int<int64_t>,100>;
131
132}
133
Definition fixed.hpp:15
T operator>(T... args)
T to_string(T... args)