sanisizer
Sanitize sizes to avoid integer overflow
Loading...
Searching...
No Matches
comparisons.hpp
Go to the documentation of this file.
1#ifndef SANISIZER_COMPARISONS_HPP
2#define SANISIZER_COMPARISONS_HPP
3
4#include "utils.hpp"
5#include "generics.hpp"
6
12namespace sanisizer {
13
17// A little wrapper for convenience.
18template<typename Integer_>
19constexpr auto as_unsigned(Integer_ x) {
20 static_assert(std::is_integral<Integer_>::value);
21 if constexpr(std::is_unsigned<Integer_>::value) {
22 return x;
23 } else {
24 return static_cast<typename std::make_unsigned<Integer_>::type>(x);
25 }
26}
42template<typename Left_, typename Right_>
43constexpr bool is_equal(Left_ left, Right_ right) {
44 return as_unsigned(get_value(left)) == as_unsigned(get_value(right));
45}
46
58template<typename Left_, typename Right_>
59constexpr bool is_less_than(Left_ left, Right_ right) {
60 return as_unsigned(get_value(left)) < as_unsigned(get_value(right));
61}
62
74template<typename Left_, typename Right_>
75constexpr bool is_less_than_or_equal(Left_ left, Right_ right) {
76 return as_unsigned(get_value(left)) <= as_unsigned(get_value(right));
77}
78
90template<typename Left_, typename Right_>
91constexpr bool is_greater_than(Left_ left, Right_ right) {
92 return as_unsigned(get_value(left)) > as_unsigned(get_value(right));
93}
94
106template<typename Left_, typename Right_>
107constexpr bool is_greater_than_or_equal(Left_ left, Right_ right) {
108 return as_unsigned(get_value(left)) >= as_unsigned(get_value(right));
109}
110
122template<typename First_, typename Second_>
123constexpr auto min(First_ first, Second_ second) {
124 const auto fval = get_value(first);
125 const auto sval = get_value(second);
126 const bool first_larger = as_unsigned(fval) > as_unsigned(sval);
127
128 if constexpr(as_unsigned(get_max<I<decltype(fval)> >()) > as_unsigned(get_max<I<decltype(sval)> >())) {
129 if (first_larger) {
130 return sval;
131 } else {
132 return static_cast<I<decltype(sval)> >(fval);
133 }
134 } else {
135 if (first_larger) {
136 return static_cast<I<decltype(fval)> >(sval);
137 } else {
138 return fval;
139 }
140 }
141}
142
154template<typename First_, typename Second_>
155constexpr auto max(First_ first, Second_ second) {
156 const auto fval = get_value(first);
157 const auto sval = get_value(second);
158 const bool first_larger = as_unsigned(fval) > as_unsigned(sval);
159
160 if constexpr(as_unsigned(get_max<I<decltype(fval)> >()) > as_unsigned(get_max<I<decltype(sval)> >())) {
161 if (first_larger) {
162 return fval;
163 } else {
164 return static_cast<I<decltype(fval)> >(sval);
165 }
166 } else {
167 if (first_larger) {
168 return static_cast<I<decltype(sval)> >(fval);
169 } else {
170 return sval;
171 }
172 }
173}
174
175}
176
177#endif
Generics for operating on integer representations.
Sanitize sizes to avoid integer overflow.
Definition Bounded.hpp:15
constexpr bool is_greater_than(Left_ left, Right_ right)
Definition comparisons.hpp:91
constexpr bool is_equal(Left_ left, Right_ right)
Definition comparisons.hpp:43
constexpr auto get_value(const Value_ x)
Definition generics.hpp:23
constexpr auto max(First_ first, Second_ second)
Definition comparisons.hpp:155
constexpr bool is_greater_than_or_equal(Left_ left, Right_ right)
Definition comparisons.hpp:107
constexpr auto get_max()
Definition generics.hpp:39
constexpr bool is_less_than_or_equal(Left_ left, Right_ right)
Definition comparisons.hpp:75
constexpr auto min(First_ first, Second_ second)
Definition comparisons.hpp:123
constexpr bool is_less_than(Left_ left, Right_ right)
Definition comparisons.hpp:59