mirror of https://github.com/qt/qtbase.git
qNextPowerOfTwo: rewrite using the newly added q20::bit_ceil()
Change-Id: I6f6d8110327d1ba7d519fffd0aa2e18d87477e56 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
b027f12392
commit
4d1004fe1e
|
@ -288,67 +288,16 @@ constexpr inline long double qRadiansToDegrees(long double radians)
|
||||||
// questionable that someone is manipulating quantities in radians
|
// questionable that someone is manipulating quantities in radians
|
||||||
// using integral datatypes...
|
// using integral datatypes...
|
||||||
|
|
||||||
namespace QtPrivate {
|
|
||||||
constexpr inline quint32 qConstexprNextPowerOfTwo(quint32 v)
|
|
||||||
{
|
|
||||||
v |= v >> 1;
|
|
||||||
v |= v >> 2;
|
|
||||||
v |= v >> 4;
|
|
||||||
v |= v >> 8;
|
|
||||||
v |= v >> 16;
|
|
||||||
++v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline quint64 qConstexprNextPowerOfTwo(quint64 v)
|
|
||||||
{
|
|
||||||
v |= v >> 1;
|
|
||||||
v |= v >> 2;
|
|
||||||
v |= v >> 4;
|
|
||||||
v |= v >> 8;
|
|
||||||
v |= v >> 16;
|
|
||||||
v |= v >> 32;
|
|
||||||
++v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline quint32 qConstexprNextPowerOfTwo(qint32 v)
|
|
||||||
{
|
|
||||||
return qConstexprNextPowerOfTwo(quint32(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline quint64 qConstexprNextPowerOfTwo(qint64 v)
|
|
||||||
{
|
|
||||||
return qConstexprNextPowerOfTwo(quint64(v));
|
|
||||||
}
|
|
||||||
} // namespace QtPrivate
|
|
||||||
|
|
||||||
constexpr inline quint32 qNextPowerOfTwo(quint32 v)
|
constexpr inline quint32 qNextPowerOfTwo(quint32 v)
|
||||||
{
|
{
|
||||||
Q_ASSERT(static_cast<qint32>(v) >= 0); // There is a next power of two
|
Q_ASSERT(static_cast<qint32>(v) >= 0); // There is a next power of two
|
||||||
#if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
|
return q20::bit_ceil(v + 1);
|
||||||
return std::bit_ceil(v + 1);
|
|
||||||
#elif defined(QT_HAS_BUILTIN_CLZ)
|
|
||||||
if (v == 0)
|
|
||||||
return 1;
|
|
||||||
return 2U << (31 ^ QAlgorithmsPrivate::qt_builtin_clz(v));
|
|
||||||
#else
|
|
||||||
return QtPrivate::qConstexprNextPowerOfTwo(v);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline quint64 qNextPowerOfTwo(quint64 v)
|
constexpr inline quint64 qNextPowerOfTwo(quint64 v)
|
||||||
{
|
{
|
||||||
Q_ASSERT(static_cast<qint64>(v) >= 0); // There is a next power of two
|
Q_ASSERT(static_cast<qint64>(v) >= 0); // There is a next power of two
|
||||||
#if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
|
return q20::bit_ceil(v + 1);
|
||||||
return std::bit_ceil(v + 1);
|
|
||||||
#elif defined(QT_HAS_BUILTIN_CLZLL)
|
|
||||||
if (v == 0)
|
|
||||||
return 1;
|
|
||||||
return Q_UINT64_C(2) << (63 ^ QAlgorithmsPrivate::qt_builtin_clzll(v));
|
|
||||||
#else
|
|
||||||
return QtPrivate::qConstexprNextPowerOfTwo(v);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline quint32 qNextPowerOfTwo(qint32 v)
|
constexpr inline quint32 qNextPowerOfTwo(qint32 v)
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace QtPrivate {
|
||||||
static_assert(tagBits > 0,
|
static_assert(tagBits > 0,
|
||||||
"Alignment of template parameter does not allow any tags");
|
"Alignment of template parameter does not allow any tags");
|
||||||
|
|
||||||
static constexpr size_t tagSize = QtPrivate::qConstexprNextPowerOfTwo(nextByteSize(tagBits));
|
static constexpr size_t tagSize = qNextPowerOfTwo(nextByteSize(tagBits));
|
||||||
static_assert(tagSize < sizeof(quintptr),
|
static_assert(tagSize < sizeof(quintptr),
|
||||||
"Alignment of template parameter allows tags masking away pointer");
|
"Alignment of template parameter allows tags masking away pointer");
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
#include <qfloat16.h>
|
#include <qfloat16.h>
|
||||||
|
|
||||||
|
#include <q20bit.h>
|
||||||
|
|
||||||
class tst_QMath : public QObject
|
class tst_QMath : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -294,6 +296,12 @@ void tst_QMath::qNextPowerOfTwo32U_data()
|
||||||
|
|
||||||
void tst_QMath::qNextPowerOfTwo32U()
|
void tst_QMath::qNextPowerOfTwo32U()
|
||||||
{
|
{
|
||||||
|
// confirm constexprness
|
||||||
|
static_assert(q20::bit_ceil(0U) == 1);
|
||||||
|
static_assert(q20::bit_ceil(1U) == 1);
|
||||||
|
static_assert(q20::bit_ceil(2U) == 2);
|
||||||
|
static_assert(q20::bit_ceil(3U) == 4);
|
||||||
|
static_assert(q20::bit_ceil(0x7fff'ffffU) == 0x8000'0000U);
|
||||||
QFETCH(quint32, input);
|
QFETCH(quint32, input);
|
||||||
QFETCH(quint32, output);
|
QFETCH(quint32, output);
|
||||||
|
|
||||||
|
@ -343,6 +351,13 @@ void tst_QMath::qNextPowerOfTwo64U_data()
|
||||||
|
|
||||||
void tst_QMath::qNextPowerOfTwo64U()
|
void tst_QMath::qNextPowerOfTwo64U()
|
||||||
{
|
{
|
||||||
|
static_assert(q20::bit_ceil(Q_UINT64_C(0)) == 1);
|
||||||
|
static_assert(q20::bit_ceil(Q_UINT64_C(1)) == 1);
|
||||||
|
static_assert(q20::bit_ceil(Q_UINT64_C(2)) == 2);
|
||||||
|
static_assert(q20::bit_ceil(Q_UINT64_C(3)) == 4);
|
||||||
|
static_assert(q20::bit_ceil(quint64(~0U)) == Q_UINT64_C(0x1'0000'0000));
|
||||||
|
static_assert(q20::bit_ceil(Q_UINT64_C(0x7FFFFFFFFFFFFFFF))
|
||||||
|
== Q_UINT64_C(0x8000000000000000));
|
||||||
QFETCH(quint64, input);
|
QFETCH(quint64, input);
|
||||||
QFETCH(quint64, output);
|
QFETCH(quint64, output);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue