HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
interval.hpp
1// Copyright Take Vos 2020.
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 "assert.hpp"
9#include <type_traits>
10#include <limits>
11#include <concepts>
12#include <algorithm>
13
14namespace tt {
15
16template<typename T>
17requires std::floating_point<T> class interval {
18public:
19 using value_type = T;
20
21 constexpr interval() noexcept : v()
22 {
25 }
26
27 constexpr interval(interval const &rhs) noexcept = default;
28 constexpr interval(interval &&rhs) noexcept = default;
29 constexpr interval &operator=(interval const &rhs) noexcept = default;
30 constexpr interval &operator=(interval &&rhs) noexcept = default;
31
32 [[nodiscard]] constexpr interval(value_type _minimum, value_type _maximum) noexcept : v()
33 {
34 v[0] = -_minimum;
35 v[1] = _maximum;
36 tt_axiom(minimum() <= maximum());
37 }
38
39 [[nodiscard]] constexpr interval(value_type rhs) noexcept : interval(rhs, rhs) {}
40
41 [[nodiscard]] constexpr value_type minimum() const noexcept
42 {
43 return -v[0];
44 }
45
46 [[nodiscard]] constexpr value_type maximum() const noexcept
47 {
48 return v[1];
49 }
50
51 interval &operator+=(interval const &rhs) noexcept
52 {
53 for (int i = 0; i != 2; ++i) {
54 v[i] += rhs.v[i];
55 }
56 return *this;
57 }
58
59 interval &operator-=(interval const &rhs) noexcept
60 {
61 for (int i = 0; i != 2; ++i) {
62 v[i] -= rhs.v[1 - i];
63 }
64 return *this;
65 }
66
67 [[nodiscard]] friend constexpr interval operator+(interval const &lhs, interval const &rhs) noexcept
68 {
69 auto r = interval{};
70 for (int i = 0; i != 2; ++i) {
71 r.v[i] = lhs.v[i] + rhs.v[i];
72 }
73 tt_axiom(r.minimum() <= r.maximum());
74 return r;
75 }
76
77 [[nodiscard]] friend constexpr interval operator-(interval const &lhs, interval const &rhs) noexcept
78 {
79 auto r = interval{};
80 for (int i = 0; i != 2; ++i) {
81 r.v[i] = lhs.v[i] - rhs.v[1 - i];
82 }
83 tt_axiom(r.minimum() <= r.maximum());
84 return r;
85 }
86
89 [[nodiscard]] friend constexpr bool operator<(value_type const &lhs, interval const &rhs) noexcept
90 {
91 return lhs < rhs.maximum();
92 }
93
96 [[nodiscard]] friend constexpr bool operator<=(value_type const &lhs, interval const &rhs) noexcept
97 {
98 return lhs <= rhs.maximum();
99 }
100
103 [[nodiscard]] friend constexpr bool operator<<(value_type const &lhs, interval const &rhs) noexcept
104 {
105 return lhs < rhs.minimum();
106 }
107
110 [[nodiscard]] friend constexpr bool operator>(value_type const &lhs, interval const &rhs) noexcept
111 {
112 return lhs > rhs.minimum();
113 }
114
117 [[nodiscard]] friend constexpr bool operator>=(value_type const &lhs, interval const &rhs) noexcept
118 {
119 return lhs >= rhs.minimum();
120 }
121
124 [[nodiscard]] friend constexpr bool operator>>(value_type const &lhs, interval const &rhs) noexcept
125 {
126 return lhs > rhs.maximum();
127 }
128
129 [[nodiscard]] friend constexpr interval max(interval const &lhs, interval const &rhs) noexcept
130 {
131 auto r = interval{};
132 r.v[0] = lhs.v[0] < rhs.v[0] ? lhs.v[0] : rhs.v[0]; // std::min()
133 r.v[1] = lhs.v[1] > rhs.v[1] ? lhs.v[1] : rhs.v[1]; // std::max()
134 tt_axiom(r.minimum() <= r.maximum());
135 return r;
136 }
137
138 [[nodiscard]] friend constexpr interval min(interval const &lhs, interval const &rhs) noexcept
139 {
140 auto r = interval{};
141 r.v[0] = lhs.v[0] > rhs.v[0] ? lhs.v[0] : rhs.v[0]; // std::max()
142 r.v[1] = lhs.v[1] < rhs.v[1] ? lhs.v[1] : rhs.v[1]; // std::min()
143 tt_axiom(r.minimum() <= r.maximum());
144 return r;
145 }
146
147 [[nodiscard]] friend constexpr interval intersect(interval const &lhs, interval const &rhs) noexcept
148 {
149 auto r = interval{};
150 for (int i = 0; i != 2; ++i) {
151 r.v[i] = lhs.v[i] < rhs.v[i] ? lhs.v[i] : rhs.v[i]; // std::min()
152 }
153 tt_axiom(r.minimum() <= r.maximum());
154 return r;
155 }
156
157 [[nodiscard]] friend constexpr interval merge(interval const &lhs, interval const &rhs) noexcept
158 {
159 auto r = interval{};
160 for (int i = 0; i != 2; ++i) {
161 r.v[i] = lhs.v[i] > rhs.v[i] ? lhs.v[i] : rhs.v[i]; // std::max()
162 }
163 tt_axiom(r.minimum() <= r.maximum());
164 return r;
165 }
166
167 [[nodiscard]] friend constexpr value_type clamp(value_type const &lhs, interval const &rhs) noexcept
168 {
169 tt_axiom(rhs.minimum() <= rhs.maximum());
170 return std::clamp(lhs, rhs.minimum(), rhs.maximum());
171 }
172
173private:
174 alignas(sizeof(value_type) * 2) value_type v[2];
175};
176
177using finterval = interval<float>;
178using dinterval = interval<double>;
179
180} // namespace tt
Definition interval.hpp:17
friend constexpr bool operator<<(value_type const &lhs, interval const &rhs) noexcept
lhs is less than and outside of the interval
Definition interval.hpp:103
friend constexpr bool operator>(value_type const &lhs, interval const &rhs) noexcept
lhs is greater than the lower edge of the interval.
Definition interval.hpp:110
friend constexpr bool operator>>(value_type const &lhs, interval const &rhs) noexcept
lhs is greater than and outside of the interval
Definition interval.hpp:124
friend constexpr bool operator>=(value_type const &lhs, interval const &rhs) noexcept
lhs is greater than or equal to the lower edge of the interval.
Definition interval.hpp:117
friend constexpr bool operator<=(value_type const &lhs, interval const &rhs) noexcept
lhs is less than or equal the upper edge of the interval.
Definition interval.hpp:96
friend constexpr bool operator<(value_type const &lhs, interval const &rhs) noexcept
lhs is less than the upper edge of the interval.
Definition interval.hpp:89
T max(T... args)