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))
59 if (b == -1 && a ==
MinInt)
70 static constexpr void check(
bool ok,
const char *where,
const char *description)
72 Q_ASSERT_X(ok, where, description);
76template <
typename Int,
83#define Q_CHECKEDINT_POLICY_CHECK(cond, what)
84 FailureReportPolicy::check(cond, Q_FUNC_INFO, what)
87 template <
typename AInt>
97 explicit constexpr operator Int()
const noexcept
103 constexpr Int
value()
const noexcept {
return m_i; }
104 template <
typename AInt, if_is_same_int<AInt> =
true>
105 constexpr void setValue(AInt i)
noexcept { m_i = i; }
110 constexpr const Int &&
as_underlying()
const &&
noexcept {
return std::move(m_i); }
117 const bool ok = Impl::sub(Int(0), m_i, &result.m_i);
124 const bool ok = Impl::add(m_i, Int(1), &m_i);
138 const bool ok = Impl::sub(m_i, Int(1), &m_i);
154 const bool ok = Impl::add(lhs.m_i, rhs.m_i, &result.m_i);
159 template <
typename AInt, if_is_same_int<AInt> =
true>
165 template <
typename AInt, if_is_same_int<AInt> =
true>
173 return *
this = *
this + other;
176 template <
typename AInt, if_is_same_int<AInt> =
true>
186 const bool ok = Impl::sub(lhs.m_i, rhs.m_i, &result.m_i);
191 template <
typename AInt, if_is_same_int<AInt> =
true>
197 template <
typename AInt, if_is_same_int<AInt> =
true>
205 return *
this = *
this - other;
208 template <
typename AInt, if_is_same_int<AInt> =
true>
218 const bool ok = Impl::mul(lhs.m_i, rhs.m_i, &result.m_i);
223 template <
typename AInt, if_is_same_int<AInt> =
true>
229 template <
typename AInt, if_is_same_int<AInt> =
true>
237 return *
this = *
this * other;
240 template <
typename AInt, if_is_same_int<AInt> =
true>
250 const bool ok = Impl::div(lhs.m_i, rhs.m_i, &result.m_i);
255 template <
typename AInt, if_is_same_int<AInt> =
true>
261 template <
typename AInt, if_is_same_int<AInt> =
true>
269 return *
this = *
this / other;
272 template <
typename AInt, if_is_same_int<AInt> =
true>
278#undef Q_CHECKEDINT_POLICY_CHECK
283 return lhs.m_i == rhs.m_i;
286 template <
typename AInt, if_is_same_int<AInt> =
true>
289 return lhs.m_i == rhs;
294 return Qt::compareThreeWay(lhs.m_i, rhs.m_i);
297 template <
typename AInt, if_is_same_int<AInt> =
true>
300 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