7#include "int_overflow.hpp"
8#include "../utility/utility.hpp"
9#include "../macros.hpp"
10#include <system_error>
35 if (lhs == on_overflow_t::Throw || rhs == on_overflow_t::Throw) {
36 return on_overflow_t::Throw;
37 }
else if (lhs == on_overflow_t::Saturate || rhs == on_overflow_t::Saturate) {
38 return on_overflow_t::Saturate;
39 }
else if (lhs == on_overflow_t::Assert || rhs == on_overflow_t::Assert) {
40 return on_overflow_t::Assert;
42 return on_overflow_t::Axiom;
51template<
typename T, on_overflow_t OnOverflow>
54 if constexpr (
OnOverflow == on_overflow_t::Throw) {
58 }
else if constexpr (
OnOverflow == on_overflow_t::Assert) {
60 }
else if constexpr (
OnOverflow == on_overflow_t::Axiom) {
62 }
else if constexpr (
OnOverflow == on_overflow_t::Saturate) {
70template<
typename T, on_overflow_t OnOverflow,
typename U>
71T safe_convert(U
const &rhs)
noexcept(
OnOverflow != on_overflow_t::Throw)
75 hilet overflow = convert_overflow(rhs, &r);
79template<on_overflow_t OnOverflow,
typename T,
typename U>
86 hilet overflow = add_overflow(
lhs_,
rhs_, &r);
90template<on_overflow_t OnOverflow,
typename T,
typename U>
97 hilet overflow = sub_overflow(
lhs_,
rhs_, &r);
101template<on_overflow_t OnOverflow,
typename T,
typename U>
112template<
typename T, on_overflow_t OnOverflow = on_overflow_t::Assert>
114 using value_type = T;
126 explicit safe_int(std::integral
auto const &other)
noexcept(OnOverflow != on_overflow_t::Throw) :
127 value(safe_convert<T, OnOverflow>(other))
131 explicit safe_int(std::floating_point
auto const &other)
noexcept(OnOverflow != on_overflow_t::Throw) :
132 value(safe_convert<T, OnOverflow>(other))
136 template<
typename O, on_overflow_t OtherOnOverflow>
138 value(safe_convert<T, OnOverflow>(other.value))
142 safe_int &operator=(std::integral
auto const &other)
noexcept(OnOverflow != on_overflow_t::Throw)
144 value = safe_convert<T, OnOverflow>(other);
148 template<
typename O, on_overflow_t OtherOnOverflow>
151 value = safe_convert<T, OnOverflow>(other.value);
155 template<std::
integral O>
156 explicit operator O()
const noexcept(OnOverflow != on_overflow_t::Throw)
158 return safe_convert<O, OnOverflow>(value);
161 template<std::
floating_po
int O>
162 explicit operator O()
const noexcept
164 return static_cast<O
>(value);
168#define TEMPLATE(op) \
169 template<typename T, on_overflow_t TO, typename U, on_overflow_t UO> \
170 bool operator op(safe_int<T, TO> const &lhs, safe_int<U, UO> const &rhs) noexcept \
172 return lhs.value op rhs.value; \
175 template<typename T, on_overflow_t TO, typename U> \
176 bool operator op(safe_int<T, TO> const &lhs, U const &rhs) noexcept \
178 return lhs.value op rhs; \
180 template<typename T, typename U, on_overflow_t UO> \
181 bool operator op(T const &lhs, safe_int<U, UO> const &rhs) noexcept \
183 return lhs op rhs.value; \
194#define TEMPLATE(op, func) \
195 template<typename T, on_overflow_t TO, typename U, on_overflow_t UO> \
196 safe_int<make_promote_t<T, U>, TO | UO> operator op(safe_int<T, TO> const &lhs, safe_int<U, UO> const &rhs) noexcept( \
197 (TO | UO) != on_overflow_t::Throw) \
199 return safe_int<make_promote_t<T, U>, TO | UO>{func<TO | UO>(lhs.value, rhs.value)}; \
202 template<typename T, on_overflow_t TO, typename U> \
203 safe_int<make_promote_t<T, U>, TO> operator op(safe_int<T, TO> const &lhs, U const &rhs) noexcept( \
204 TO != on_overflow_t::Throw) \
206 return safe_int<make_promote_t<T, U>, TO>{func<TO>(lhs.value, rhs)}; \
209 template<typename T, typename U, on_overflow_t UO> \
210 safe_int<make_promote_t<T, U>, UO> operator op(T const &lhs, safe_int<U, UO> const &rhs) noexcept( \
211 UO != on_overflow_t::Throw) \
213 return safe_int<make_promote_t<T, U>, UO>{func<UO>(lhs, rhs.value)}; \
DOXYGEN BUG.
Definition algorithm.hpp:16
T safe_handle_overflow(T value, bool overflow, bool is_positive) noexcept(OnOverflow !=on_overflow_t::Throw)
Definition safe_int.hpp:52
bool mul_overflow(T lhs, T rhs, T *r) noexcept
Multiply with overflow detection.
Definition int_overflow.hpp:99
on_overflow_t
Definition safe_int.hpp:19
@ Axiom
On overflow assert and teminate in debug, assume in release.
@ Throw
On overflow throw an exception.
@ Assert
On overflow assert and terminate.
@ Saturate
On overflow saturate the result in the appropiate direction.
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition safe_int.hpp:113