7#include <QtCore/qassert.h>
8#include <QtCore/qcompare.h>
9#include <QtCore/qhashfunctions.h>
10#include <QtCore/qnumeric.h>
19template <
typename Int>
22 static_assert(
std::is_integral_v<Int>,
"Only integer types are supported");
23 static_assert(
std::is_signed_v<Int>,
"Only signed types are supported");
24 static_assert(
std::is_same_v<Int,
decltype(+Int{})>,
"Only fully promoted types are supported");
29template <
typename Int>
36 static constexpr bool add(Int a, Int b, Int *result)
noexcept
38 return !qAddOverflow(a, b, result);
42 static constexpr bool sub(Int a, Int b, Int *result)
noexcept
44 return !qSubOverflow(a, b, result);
48 static constexpr bool mul(Int a, Int b, Int *result)
noexcept
50 return !qMulOverflow(a, b, result);
54 static constexpr bool div(Int a, Int b, Int *result)
noexcept
56 if (Q_UNLIKELY(b == 0))
67 static constexpr void check(
bool ok,
const char *where,
const char *description)
69 Q_ASSERT_X(ok, where, description);
73template <
typename Int,
80#define Q_CHECKEDINT_POLICY_CHECK(cond, what)
81 FailureReportPolicy::check(cond, Q_FUNC_INFO, what)
84 template <
typename AInt>
94 explicit constexpr operator Int()
const noexcept
100 constexpr Int
value()
const noexcept {
return m_i; }
101 template <
typename AInt, if_is_same_int<AInt> =
true>
102 constexpr void setValue(AInt i)
noexcept { m_i = i; }
107 constexpr const Int &&
as_underlying()
const &&
noexcept {
return std::move(m_i); }
114 const bool ok = Impl::sub(Int(0), m_i, &result.m_i);
121 const bool ok = Impl::add(m_i, Int(1), &m_i);
135 const bool ok = Impl::sub(m_i, Int(1), &m_i);
151 const bool ok = Impl::add(lhs.m_i, rhs.m_i, &result.m_i);
156 template <
typename AInt, if_is_same_int<AInt> =
true>
162 template <
typename AInt, if_is_same_int<AInt> =
true>
170 return *
this = *
this + other;
173 template <
typename AInt, if_is_same_int<AInt> =
true>
183 const bool ok = Impl::sub(lhs.m_i, rhs.m_i, &result.m_i);
188 template <
typename AInt, if_is_same_int<AInt> =
true>
194 template <
typename AInt, if_is_same_int<AInt> =
true>
202 return *
this = *
this - other;
205 template <
typename AInt, if_is_same_int<AInt> =
true>
215 const bool ok = Impl::mul(lhs.m_i, rhs.m_i, &result.m_i);
220 template <
typename AInt, if_is_same_int<AInt> =
true>
226 template <
typename AInt, if_is_same_int<AInt> =
true>
234 return *
this = *
this * other;
237 template <
typename AInt, if_is_same_int<AInt> =
true>
247 const bool ok = Impl::div(lhs.m_i, rhs.m_i, &result.m_i);
252 template <
typename AInt, if_is_same_int<AInt> =
true>
258 template <
typename AInt, if_is_same_int<AInt> =
true>
266 return *
this = *
this / other;
269 template <
typename AInt, if_is_same_int<AInt> =
true>
275#undef Q_CHECKEDINT_POLICY_CHECK
280 return lhs.m_i == rhs.m_i;
283 template <
typename AInt, if_is_same_int<AInt> =
true>
286 return lhs.m_i == rhs;
291 return Qt::compareThreeWay(lhs.m_i, rhs.m_i);
294 template <
typename AInt, if_is_same_int<AInt> =
true>
297 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