HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
fixed.hpp
1// Copyright Take Vos 2019, 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "utility.hpp"
8#include "string_tag.hpp"
9#include "safe_int.hpp"
10#include <type_traits>
11#include <limits>
12#include <concepts>
13
14namespace hi::inline v1 {
15
16template<typename T, int M>
17struct fixed {
18 using value_type = T;
19 static constexpr int multiplier = M;
20
21 T value;
22
23 fixed() = default;
24 ~fixed() = default;
25 fixed(fixed const &) = default;
26 fixed &operator=(fixed const &) = default;
27 fixed(fixed &&) = default;
28 fixed &operator=(fixed &&) = default;
29
30 explicit constexpr fixed(std::floating_point auto other) noexcept : value(static_cast<T>(other * M))
31 {
32 hi_assert(other >= (std::numeric_limits<T>::min() / M) && other <= (std::numeric_limits<T>::max() / M));
33 }
34
35 explicit constexpr fixed(std::integral auto other) noexcept : value(static_cast<T>(other) * M)
36 {
37 hi_assert(other >= (std::numeric_limits<T>::min() / M) && other <= (std::numeric_limits<T>::max() / M));
38 }
39
40 explicit fixed(std::string const &other) : fixed(stod(other)) {}
41
42 constexpr fixed &operator=(std::floating_point auto other) noexcept
43 {
44 value = static_cast<T>(other * M);
45 hi_assert(other >= (std::numeric_limits<T>::min() / M) && other <= (std::numeric_limits<T>::max() / M));
46 return *this;
47 }
48
49 constexpr fixed &operator=(std::integral auto other) noexcept
50 {
51 value = static_cast<T>(other) * M;
52 hi_assert(other >= (std::numeric_limits<T>::min() / M) && other <= (std::numeric_limits<T>::max() / M));
53 return *this;
54 }
55
56 fixed &operator=(std::string const &other)
57 {
58 value = static_cast<T>(stod(other) * M);
59 hi_assert(other >= (std::numeric_limits<T>::min() / M) && other <= (std::numeric_limits<T>::max() / M));
60 return *this;
61 }
62
63 template<std::floating_point O>
64 explicit operator O() const noexcept
65 {
66 return static_cast<O>(value) / M;
67 }
68
69 template<std::integral O>
70 explicit operator O() const noexcept
71 {
72 return static_cast<O>(value / M);
73 }
74
75 std::string string() const noexcept
76 {
77 return std::format("{}", static_cast<double>(value) / M);
78 }
79
80 static fixed from_raw_value(T value) noexcept
81 {
82 fixed r;
83 r.value = value;
84 return r;
85 }
86
87 [[nodiscard]] constexpr friend bool operator==(fixed const &lhs, fixed const &rhs) noexcept
88 {
89 return lhs.value == rhs.value;
90 }
91
92 [[nodiscard]] constexpr friend auto operator<=>(fixed const &lhs, fixed const &rhs) noexcept
93 {
94 return lhs.value <=> rhs.value;
95 }
96
97 [[nodiscard]] constexpr friend fixed operator+(fixed const &lhs, fixed const &rhs) noexcept
98 {
99 return fixed<T, M>::from_raw_value(lhs.value + rhs.value);
100 }
101
102 [[nodiscard]] constexpr friend fixed operator-(fixed const &lhs, fixed const &rhs) noexcept
103 {
104 return fixed<T, M>::from_raw_value(lhs.value - rhs.value);
105 }
106
107 [[nodiscard]] friend std::string to_string(fixed const v)
108 {
109 return v.string();
110 }
111
112 friend std::ostream &operator<<(std::ostream &lhs, fixed const &rhs)
113 {
114 return lhs << rhs.string();
115 }
116};
117
118using money = fixed<safe_int<int64_t>, 100>;
119
120} // namespace hi::inline v1
Utilities used by the HikoGUI library itself.
DOXYGEN BUG.
Definition algorithm.hpp:15
Definition fixed.hpp:17