summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qanystringview.h
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@qt.io>2022-11-11 04:53:36 +0200
committerVille Voutilainen <ville.voutilainen@qt.io>2022-11-12 03:10:16 +0200
commit8a11f16dc0d3f5b9f0e03e3500f48815d9cdaa83 (patch)
treef8abb5d34a8653e31c0473fd37337847e64adbfa /src/corelib/text/qanystringview.h
parent2fd4d0586fe9637b14480e03839fd586d9660b89 (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.h46
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; }