diff options
author | Ville Voutilainen <ville.voutilainen@qt.io> | 2022-11-11 04:53:36 +0200 |
---|---|---|
committer | Ville Voutilainen <ville.voutilainen@qt.io> | 2022-11-12 03:10:16 +0200 |
commit | 8a11f16dc0d3f5b9f0e03e3500f48815d9cdaa83 (patch) | |
tree | f8abb5d34a8653e31c0473fd37337847e64adbfa /src/corelib/text/qanystringview.h | |
parent | 2fd4d0586fe9637b14480e03839fd586d9660b89 (diff) |
Fix QAnyStringView build with GCC 13
The problem is caused by GCC 13 having an intrinsic for is_convertible,
and that (correctly) checks for incomplete types. We then manage to
trigger the instantiation of the QAnyStringView converting constructor from isUtf16 etc.,
and that triggers the enable_if and is_convertible. The fix is to move
the Tag definition earlier, and to eagerly SFINAE away the Tag type so
that the converting constructor rejects it. Otherwise, the converting
constructor is considered a candidate for comparisons of Tags, and gets
instantiated for overload resolution.
Fixes: QTBUG-108136
Change-Id: I9b0c0f7ac771cdbf6a9c35a3d3b0ea01b88b970e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib/text/qanystringview.h')
-rw-r--r-- | src/corelib/text/qanystringview.h | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h index bdb2387ebb..fd17462b6d 100644 --- a/src/corelib/text/qanystringview.h +++ b/src/corelib/text/qanystringview.h @@ -33,6 +33,29 @@ public: typedef qptrdiff difference_type; typedef qsizetype size_type; private: + // TODO: Optimize by inverting and storing the flags in the low bits and + // the size in the high. + static_assert(std::is_same_v<std::size_t, size_t>); + static_assert(sizeof(size_t) == sizeof(qsizetype)); + static constexpr size_t SizeMask = (std::numeric_limits<size_t>::max)() / 4; + static constexpr size_t Latin1Flag = SizeMask + 1; + static constexpr size_t TwoByteCodePointFlag = Latin1Flag << 1; + static constexpr size_t TypeMask = (std::numeric_limits<size_t>::max)() & ~SizeMask; + static_assert(TypeMask == (Latin1Flag|TwoByteCodePointFlag)); + // HI HI LO LO ... + // 0 0 SZ SZ Utf8 + // 0 1 SZ SZ Latin1 + // 1 0 SZ SZ Utf16 + // 1 1 SZ SZ Unused + // ^ ^ latin1 + // | sizeof code-point == 2 + enum Tag : size_t { + Utf8 = 0, + Latin1 = Latin1Flag, + Utf16 = TwoByteCodePointFlag, + Unused = TypeMask, + }; + template <typename Char> using if_compatible_char = std::enable_if_t<std::disjunction_v< QtPrivate::IsCompatibleCharType<Char>, @@ -56,6 +79,7 @@ private: using if_convertible_to = std::enable_if_t<std::conjunction_v< // need to exclude a bunch of stuff, because we take by universal reference: std::negation<std::disjunction< + std::is_same<q20::remove_cvref_t<T>, QAnyStringView::Tag>, std::is_same<q20::remove_cvref_t<T>, QAnyStringView>, // don't make a copy/move ctor std::is_pointer<std::decay_t<T>>, // const char*, etc std::is_same<q20::remove_cvref_t<T>, QByteArray>, @@ -273,28 +297,6 @@ private: { return QAnyStringView::compare(lhs, rhs) > 0; } #endif - // TODO: Optimize by inverting and storing the flags in the low bits and - // the size in the high. - static_assert(std::is_same_v<std::size_t, size_t>); - static_assert(sizeof(size_t) == sizeof(qsizetype)); - static constexpr size_t SizeMask = (std::numeric_limits<size_t>::max)() / 4; - static constexpr size_t Latin1Flag = SizeMask + 1; - static constexpr size_t TwoByteCodePointFlag = Latin1Flag << 1; - static constexpr size_t TypeMask = (std::numeric_limits<size_t>::max)() & ~SizeMask; - static_assert(TypeMask == (Latin1Flag|TwoByteCodePointFlag)); - // HI HI LO LO ... - // 0 0 SZ SZ Utf8 - // 0 1 SZ SZ Latin1 - // 1 0 SZ SZ Utf16 - // 1 1 SZ SZ Unused - // ^ ^ latin1 - // | sizeof code-point == 2 - enum Tag : size_t { - Utf8 = 0, - Latin1 = Latin1Flag, - Utf16 = TwoByteCodePointFlag, - Unused = TypeMask, - }; [[nodiscard]] constexpr Tag tag() const noexcept { return Tag{m_size & TypeMask}; } [[nodiscard]] constexpr bool isUtf16() const noexcept { return tag() == Tag::Utf16; } [[nodiscard]] constexpr bool isUtf8() const noexcept { return tag() == Tag::Utf8; } |