8#include <QtCore/qassert.h>
9#include <QtCore/qcompare.h>
10#include <QtCore/qhashfunctions.h>
11#include <QtCore/qnumeric.h>
20template <
typename Int>
23 static_assert(
std::is_integral_v<Int>,
"Only integer types are supported");
24 static_assert(
std::is_signed_v<Int>,
"Only signed types are supported");
25 static_assert(
std::is_same_v<Int,
decltype(+Int{})>,
"Only fully promoted types are supported");
30template <
typename Int>
37 static constexpr bool add(Int a, Int b, Int *result)
noexcept
39 return !qAddOverflow(a, b, result);
43 static constexpr bool sub(Int a, Int b, Int *result)
noexcept
45 return !qSubOverflow(a, b, result);
49 static constexpr bool mul(Int a, Int b, Int *result)
noexcept
51 return !qMulOverflow(a, b, result);
55 static constexpr bool div(Int a, Int b, Int *result)
noexcept
57 if (Q_UNLIKELY(b == 0))
68 static constexpr void check(
bool ok,
const char *where,
const char *description)
70 Q_ASSERT_X(ok, where, description);
74template <
typename Int,
81#define Q_CHECKEDINT_POLICY_CHECK(cond, what)
82 FailureReportPolicy::check(cond, Q_FUNC_INFO, what)
85 template <
typename AInt>
95 explicit constexpr operator Int()
const noexcept
101 constexpr Int
value()
const noexcept {
return m_i; }
102 template <
typename AInt, if_is_same_int<AInt> =
true>
103 constexpr void setValue(AInt i)
noexcept { m_i = i; }
108 constexpr const Int &&
as_underlying()
const &&
noexcept {
return std::move(m_i); }
115 const bool ok = Impl::sub(Int(0), m_i, &result.m_i);
122 const bool ok = Impl::add(m_i, Int(1), &m_i);
136 const bool ok = Impl::sub(m_i, Int(1), &m_i);
152 const bool ok = Impl::add(lhs.m_i, rhs.m_i, &result.m_i);
157 template <
typename AInt, if_is_same_int<AInt> =
true>
163 template <
typename AInt, if_is_same_int<AInt> =
true>
171 return *
this = *
this + other;
174 template <
typename AInt, if_is_same_int<AInt> =
true>
184 const bool ok = Impl::sub(lhs.m_i, rhs.m_i, &result.m_i);
189 template <
typename AInt, if_is_same_int<AInt> =
true>
195 template <
typename AInt, if_is_same_int<AInt> =
true>
203 return *
this = *
this - other;
206 template <
typename AInt, if_is_same_int<AInt> =
true>
216 const bool ok = Impl::mul(lhs.m_i, rhs.m_i, &result.m_i);
221 template <
typename AInt, if_is_same_int<AInt> =
true>
227 template <
typename AInt, if_is_same_int<AInt> =
true>
235 return *
this = *
this * other;
238 template <
typename AInt, if_is_same_int<AInt> =
true>
248 const bool ok = Impl::div(lhs.m_i, rhs.m_i, &result.m_i);
253 template <
typename AInt, if_is_same_int<AInt> =
true>
259 template <
typename AInt, if_is_same_int<AInt> =
true>
267 return *
this = *
this / other;
270 template <
typename AInt, if_is_same_int<AInt> =
true>
276#undef Q_CHECKEDINT_POLICY_CHECK
281 return lhs.m_i == rhs.m_i;
284 template <
typename AInt, if_is_same_int<AInt> =
true>
287 return lhs.m_i == rhs;
292 return Qt::compareThreeWay(lhs.m_i, rhs.m_i);
295 template <
typename AInt, if_is_same_int<AInt> =
true>
298 return Qt::compareThreeWay(lhs.m_i, rhs);
friend constexpr QCheckedInt operator+(AInt lhs, QCheckedInt rhs)
constexpr QCheckedInt operator--(int)
constexpr QCheckedInt & operator-=(AInt other)
friend constexpr QCheckedInt operator/(AInt lhs, QCheckedInt rhs)
friend constexpr QCheckedInt operator/(QCheckedInt lhs, QCheckedInt rhs)
constexpr QCheckedInt operator+() const noexcept
constexpr QCheckedInt & operator*=(QCheckedInt other)
constexpr const Int & as_underlying() const &noexcept
constexpr QCheckedInt operator++(int)
friend constexpr QCheckedInt operator+(QCheckedInt lhs, QCheckedInt rhs)
friend constexpr QCheckedInt operator-(QCheckedInt lhs, QCheckedInt rhs)
friend constexpr Qt::strong_ordering compareThreeWay(QCheckedInt lhs, AInt rhs) noexcept
constexpr QCheckedInt & operator*=(AInt other)
constexpr QCheckedInt(Int i) noexcept
constexpr const Int && as_underlying() const &&noexcept
constexpr void setValue(AInt i) noexcept
constexpr QCheckedInt & operator/=(AInt other)
constexpr QCheckedInt & operator--()
friend constexpr QCheckedInt operator-(AInt lhs, QCheckedInt rhs)
constexpr QCheckedInt & operator+=(QCheckedInt other)
friend constexpr bool comparesEqual(QCheckedInt lhs, QCheckedInt rhs) noexcept
constexpr Int && as_underlying() &&noexcept
constexpr QCheckedInt & operator/=(QCheckedInt other)
constexpr Int & as_underlying() &noexcept
constexpr Int value() const noexcept
constexpr QCheckedInt & operator++()
friend constexpr Qt::strong_ordering compareThreeWay(QCheckedInt lhs, QCheckedInt rhs) noexcept
friend constexpr QCheckedInt operator-(QCheckedInt lhs, AInt rhs)
constexpr operator Int() const noexcept
friend constexpr QCheckedInt operator*(AInt lhs, QCheckedInt rhs)
friend constexpr QCheckedInt operator*(QCheckedInt lhs, QCheckedInt rhs)
friend constexpr QCheckedInt operator*(QCheckedInt lhs, AInt rhs)
friend constexpr bool comparesEqual(QCheckedInt lhs, AInt rhs) noexcept
constexpr QCheckedInt operator-() const
friend constexpr QCheckedInt operator+(QCheckedInt lhs, AInt rhs)
constexpr QCheckedInt & operator+=(AInt other)
constexpr QCheckedInt & operator-=(QCheckedInt other)
friend constexpr QCheckedInt operator/(QCheckedInt lhs, AInt rhs)
#define Q_CHECKEDINT_POLICY_CHECK(cond, what)
static constexpr void check(bool ok, const char *where, const char *description)
static constexpr bool mul(Int a, Int b, Int *result) noexcept
static constexpr bool add(Int a, Int b, Int *result) noexcept
static constexpr bool sub(Int a, Int b, Int *result) noexcept
static constexpr bool div(Int a, Int b, Int *result) noexcept
static constexpr Int MinInt
static constexpr Int MaxInt