33 explicit Checked(T
const value) : value{value} {}
34 Checked(Checked<T>
const & other) =
default;
35 Checked(Checked<T> && other) =
default;
36 Checked<T> & operator=(Checked<T>
const & other) =
default;
38 std::strong_ordering operator<=>(Checked<T>
const & other)
const =
default;
39 std::strong_ordering operator<=>(T
const & other)
const
41 return value <=> other;
44 explicit operator T()
const
49 enum class OverflowKind {
58 OverflowKind overflowed_;
61 Result(T value,
bool overflowed) : value{value}, overflowed_{overflowed ? OverflowKind::Overflow : OverflowKind::NoOverflow} {}
62 Result(T value, OverflowKind overflowed) : value{value}, overflowed_{overflowed} {}
64 bool operator==(Result other)
const
66 return value == other.value && overflowed_ == other.overflowed_;
69 std::optional<T> valueChecked()
const
71 if (overflowed_ != OverflowKind::NoOverflow) {
85 if (overflowed_ == OverflowKind::DivByZero) {
91 bool overflowed()
const
93 return overflowed_ == OverflowKind::Overflow;
96 bool divideByZero()
const
98 return overflowed_ == OverflowKind::DivByZero;
102 Result operator+(Checked<T>
const other)
const
104 return (*
this) + other.value;
106 Result operator+(T
const other)
const
109 bool overflowed = __builtin_add_overflow(value, other, &result);
110 return Result{result, overflowed};
113 Result operator-(Checked<T>
const other)
const
115 return (*
this) - other.value;
117 Result operator-(T
const other)
const
120 bool overflowed = __builtin_sub_overflow(value, other, &result);
121 return Result{result, overflowed};
124 Result operator*(Checked<T>
const other)
const
126 return (*
this) * other.value;
128 Result operator*(T
const other)
const
131 bool overflowed = __builtin_mul_overflow(value, other, &result);
132 return Result{result, overflowed};
135 Result operator/(Checked<T>
const other)
const
137 return (*
this) / other.value;
147 constexpr T
const minV = std::numeric_limits<T>::min();
153 if (std::is_signed<T>() && (value == minV && other == -1)) {
154 return Result{minV,
true};
155 }
else if (other == 0) {
156 return Result{0, OverflowKind::DivByZero};
158 T result = value / other;
159 return Result{result,
false};