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