diff options
Diffstat (limited to 'src/corelib/tools/qtaggedpointer.h')
-rw-r--r-- | src/corelib/tools/qtaggedpointer.h | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/corelib/tools/qtaggedpointer.h b/src/corelib/tools/qtaggedpointer.h index 504645993a..6c467d59f8 100644 --- a/src/corelib/tools/qtaggedpointer.h +++ b/src/corelib/tools/qtaggedpointer.h @@ -21,7 +21,7 @@ namespace QtPrivate { static_assert((alignment & (alignment - 1)) == 0, "Alignment of template parameter must be power of two"); - static constexpr quint8 tagBits = QtPrivate::qConstexprCountTrailingZeroBits(alignment); + static constexpr quint8 tagBits = quint8{QtPrivate::qConstexprCountTrailingZeroBits(alignment)}; static_assert(tagBits > 0, "Alignment of template parameter does not allow any tags"); @@ -43,10 +43,10 @@ public: static constexpr quintptr tagMask() { return QtPrivate::TagInfo<T>::alignment - 1; } static constexpr quintptr pointerMask() { return ~tagMask(); } - constexpr QTaggedPointer() noexcept : d(0) {} - constexpr QTaggedPointer(std::nullptr_t) noexcept : QTaggedPointer() {} + Q_NODISCARD_CTOR constexpr QTaggedPointer() noexcept : d(0) {} + Q_NODISCARD_CTOR constexpr QTaggedPointer(std::nullptr_t) noexcept : QTaggedPointer() {} - explicit QTaggedPointer(T *pointer, Tag tag = Tag()) noexcept + Q_NODISCARD_CTOR explicit QTaggedPointer(T *pointer, Tag tag = Tag()) noexcept : d(quintptr(pointer) | quintptr(tag)) { static_assert(sizeof(Type*) == sizeof(QTaggedPointer)); @@ -72,12 +72,31 @@ public: return !isNull(); } - QTaggedPointer &operator=(T *other) noexcept +#ifdef Q_QDOC + QTaggedPointer &operator=(T *other) noexcept; +#else + // Disables the usage of `ptr = {}`, which would go through this operator + // (rather than using the implicitly-generated assignment operator). + // The operators have different semantics: the ones here leave the tag intact, + // the implicitly-generated one overwrites it. + template <typename U, + std::enable_if_t<std::is_convertible_v<U *, T *>, bool> = false> + QTaggedPointer &operator=(U *other) noexcept { - d = reinterpret_cast<quintptr>(other) | (d & tagMask()); + T *otherT = other; + d = reinterpret_cast<quintptr>(otherT) | (d & tagMask()); return *this; } + template <typename U, + std::enable_if_t<std::is_null_pointer_v<U>, bool> = false> + QTaggedPointer &operator=(U) noexcept + { + d = reinterpret_cast<quintptr>(static_cast<T *>(nullptr)) | (d & tagMask()); + return *this; + } +#endif + static constexpr Tag maximumTag() noexcept { return TagType(typename QtPrivate::TagInfo<T>::TagType(tagMask())); @@ -85,8 +104,10 @@ public: void setTag(Tag tag) { - Q_ASSERT_X((static_cast<typename QtPrivate::TagInfo<T>::TagType>(tag) & pointerMask()) == 0, - "QTaggedPointer<T, Tag>::setTag", "Tag is larger than allowed by number of available tag bits"); + Q_ASSERT_X( + (static_cast<quintptr>(tag) & pointerMask()) == 0, + "QTaggedPointer<T, Tag>::setTag", + "Tag is larger than allowed by number of available tag bits"); d = (d & pointerMask()) | static_cast<quintptr>(tag); } |