diff options
Diffstat (limited to 'src')
74 files changed, 1789 insertions, 502 deletions
diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 10dee70d834..e9a94e05de3 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,4 +1,4 @@ -libpng 1.6.52 - December 3, 2025 +libpng 1.6.53 - December 5, 2025 ================================ This is a public release of libpng, intended for use in production code. @@ -9,10 +9,10 @@ Files available for download Source files: - * libpng-1.6.52.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.52.tar.gz (deflate-compressed) - * lpng1652.7z (LZMA-compressed) - * lpng1652.zip (deflate-compressed) + * libpng-1.6.53.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.53.tar.gz (deflate-compressed) + * lpng1653.7z (LZMA-compressed) + * lpng1653.zip (deflate-compressed) Other information: @@ -22,18 +22,14 @@ Other information: * TRADEMARK.md -Changes from version 1.6.51 to version 1.6.52 +Changes from version 1.6.52 to version 1.6.53 --------------------------------------------- - * Fixed CVE-2025-66293 (high severity): - Out-of-bounds read in `png_image_read_composite`. - (Reported by flyfish101 <[email protected]>.) - * Fixed the Paeth filter handling in the RISC-V RVV implementation. - (Reported by Filip Wasil; fixed by Liang Junzhao.) - * Improved the performance of the RISC-V RVV implementation. - (Contributed by Liang Junzhao.) - * Added allocation failure fuzzing to oss-fuzz. - (Contributed by Philippe Antoine.) + * Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic. + (Contributed by Alexander Smorkalov.) + * Fixed a build failure with CMake 4.1 or newer, on Windows, when using + Visual C++ without MASM installed. + (Reported by Andrew Tribick; fixed by Luis Caro Campos.) Send comments/corrections/commendations to png-mng-implement at lists.sf.net. diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index f8ad74bbdf3..ea43101538a 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6315,6 +6315,12 @@ Version 1.6.52 [December 3, 2025] Added allocation failure fuzzing to oss-fuzz. (Contributed by Philippe Antoine.) +Version 1.6.53 [December 5, 2025] + Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic. + (Contributed by Alexander Smorkalov.) + Fixed a build failure with CMake 4.1 or newer, on Windows, when using + Visual C++ without MASM installed. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index 87e5f8b177e..4041ad86eb3 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.52 +README for libpng version 1.6.53 ================================ See the note about version numbers near the top of `png.h`. diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index f284d987ba6..750025cfdad 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.52 - December 2025 + libpng version 1.6.36, December 2018, through 1.6.53 - December 2025 Updated and distributed by Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index 11b65d1f13e..85b49496520 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -13,7 +13,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_52 Your_png_h_is_not_version_1_6_52; +typedef png_libpng_version_1_6_53 Your_png_h_is_not_version_1_6_53; /* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the * corresponding macro definitions. This causes a compile time failure if @@ -817,7 +817,7 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.52" PNG_STRING_NEWLINE \ + "libpng version 1.6.53" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index bceb9aa45d7..bdcd243dea2 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,6 +1,6 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.52 + * libpng version 1.6.53 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson @@ -14,7 +14,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.52, December 2025: + * libpng versions 1.6.36, December 2018, through 1.6.53, December 2025: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -238,7 +238,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.52 16 10651 16.so.16.52[.0] + * 1.6.53 16 10651 16.so.16.53[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -274,7 +274,7 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.52" +#define PNG_LIBPNG_VER_STRING "1.6.53" #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" /* The versions of shared library builds should stay in sync, going forward */ @@ -285,7 +285,7 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 52 +#define PNG_LIBPNG_VER_RELEASE 53 /* This should be zero for a public release, or non-zero for a * development version. @@ -316,7 +316,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10652 /* 1.6.52 */ +#define PNG_LIBPNG_VER 10653 /* 1.6.53 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -426,7 +426,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_52; +typedef char* png_libpng_version_1_6_53; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 76b5c20bdff..f4ff19209c6 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,6 +1,6 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.52 + * libpng version 1.6.53 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index f4a993441f7..27fa87045b3 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,6 +1,6 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.52 */ +/* libpng version 1.6.53 */ /* Copyright (c) 2018-2025 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index f8ca2b7e31d..13a93deedcb 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -3278,7 +3278,7 @@ png_image_read_composite(png_voidp argument) /* Clamp to the valid range to defend against * unforeseen cases where the data might be sRGB * instead of linear premultiplied. - * (Belt-and-suspenders for GitHub Issue #764.) + * (Belt-and-suspenders for CVE-2025-66293.) */ if (component > 255*65535) component = 255*65535; diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index 1f942f8f564..132e5e8d4cd 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -7,8 +7,8 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.52", - "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.52.tar.xz", + "Version": "1.6.53", + "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.53.tar.xz", "PURL": "pkg:github/pnggroup/libpng@v$<VERSION>", "CPE": "cpe:2.3:a:libpng:libpng:$<VERSION>:*:*:*:*:*:*:*", diff --git a/src/corelib/configure.cmake b/src/corelib/configure.cmake index 7216f2920fe..4386b907c13 100644 --- a/src/corelib/configure.cmake +++ b/src/corelib/configure.cmake @@ -1285,7 +1285,7 @@ qt_feature("openssl-hash" PRIVATE qt_feature("async-io" PRIVATE LABEL "Async File I/O" PURPOSE "Provides support for asynchronous file I/O." - CONDITION (QT_FEATURE_thread AND QT_FEATURE_future) OR APPLE + CONDITION (QT_FEATURE_thread AND QT_FEATURE_future) OR APPLE OR (LINUX AND QT_FEATURE_liburing) OR (WIN32 AND QT_FEATURE_windows_ioring) ) qt_configure_add_summary_section(NAME "Qt Core") diff --git a/src/corelib/global/patches/tlexpected/0006-Namespace-TL_-macros-with-Q23_.patch b/src/corelib/global/patches/tlexpected/0006-Namespace-TL_-macros-with-Q23_.patch new file mode 100644 index 00000000000..f3c45f07594 --- /dev/null +++ b/src/corelib/global/patches/tlexpected/0006-Namespace-TL_-macros-with-Q23_.patch @@ -0,0 +1,914 @@ +From 5676e5f83597dc1fb32b551c863633eff102e879 Mon Sep 17 00:00:00 2001 +From: Marc Mutz <[email protected]> +Date: Thu, 27 Nov 2025 07:51:19 +0100 +Subject: [PATCH] Namespace TL_ macros with Q23_ + +Change-Id: Ib5762ec8ebe81e0c750da84be29531b7179c5025 +--- + src/corelib/global/qexpected_p.h | 312 +++++++++++++++---------------- + 1 file changed, 156 insertions(+), 156 deletions(-) + +diff --git a/src/corelib/global/qexpected_p.h b/src/corelib/global/qexpected_p.h +index 24ea5be1e5e..54bcae51102 100644 +--- a/src/corelib/global/qexpected_p.h ++++ b/src/corelib/global/qexpected_p.h +@@ -16,8 +16,8 @@ + // <http://creativecommons.org/publicdomain/zero/1.0/>. + /// + +-#ifndef TL_EXPECTED_HPP +-#define TL_EXPECTED_HPP ++#ifndef Q23_TL_EXPECTED_HPP ++#define Q23_TL_EXPECTED_HPP + + // + // W A R N I N G +@@ -30,9 +30,9 @@ + // We mean it. + // + +-#define TL_EXPECTED_VERSION_MAJOR 1 +-#define TL_EXPECTED_VERSION_MINOR 1 +-#define TL_EXPECTED_VERSION_PATCH 0 ++#define Q23_TL_EXPECTED_VERSION_MAJOR 1 ++#define Q23_TL_EXPECTED_VERSION_MINOR 1 ++#define Q23_TL_EXPECTED_VERSION_PATCH 0 + + #include <QtCore/private/qglobal_p.h> + #include <QtCore/qassert.h> +@@ -44,45 +44,45 @@ + #include <type_traits> + #include <utility> + +-#define TL_ASSERT Q_ASSERT ++#define Q23_TL_ASSERT Q_ASSERT + + #if defined(__EXCEPTIONS) || defined(_CPPUNWIND) +-#define TL_EXPECTED_EXCEPTIONS_ENABLED ++#define Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + #endif + +-#if defined(TL_EXPECTED_EXCEPTIONS_ENABLED) && defined(QT_NO_EXCEPTIONS) +-# undef TL_EXPECTED_EXCEPTIONS_ENABLED ++#if defined(Q23_TL_EXPECTED_EXCEPTIONS_ENABLED) && defined(QT_NO_EXCEPTIONS) ++# undef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + #endif + + #if (defined(_MSC_VER) && _MSC_VER == 1900) +-#define TL_EXPECTED_MSVC2015 +-#define TL_EXPECTED_MSVC2015_CONSTEXPR ++#define Q23_TL_EXPECTED_MSVC2015 ++#define Q23_TL_EXPECTED_MSVC2015_CONSTEXPR + #else +-#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr ++#define Q23_TL_EXPECTED_MSVC2015_CONSTEXPR constexpr + #endif + + #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ + !defined(__clang__)) +-#define TL_EXPECTED_GCC49 ++#define Q23_TL_EXPECTED_GCC49 + #endif + + #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \ + !defined(__clang__)) +-#define TL_EXPECTED_GCC54 ++#define Q23_TL_EXPECTED_GCC54 + #endif + + #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \ + !defined(__clang__)) +-#define TL_EXPECTED_GCC55 ++#define Q23_TL_EXPECTED_GCC55 + #endif + +-#if !defined(TL_ASSERT) ++#if !defined(Q23_TL_ASSERT) + //can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug +-#if (TL_CPLUSPLUS > 201103L) && !defined(TL_EXPECTED_GCC49) ++#if (Q23_TL_CPLUSPLUS > 201103L) && !defined(Q23_TL_EXPECTED_GCC49) + #include <cassert> +-#define TL_ASSERT(x) assert(x) ++#define Q23_TL_ASSERT(x) assert(x) + #else +-#define TL_ASSERT(x) ++#define Q23_TL_ASSERT(x) + #endif + #endif + +@@ -90,22 +90,22 @@ + !defined(__clang__)) + // GCC < 5 doesn't support overloading on const&& for member functions + +-#define TL_EXPECTED_NO_CONSTRR ++#define Q23_TL_EXPECTED_NO_CONSTRR + // GCC < 5 doesn't support some standard C++11 type traits +-#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + std::has_trivial_copy_constructor<T> +-#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::has_trivial_copy_assign<T> + + // This one will be different for GCC 5.7 if it's ever supported +-#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ + std::is_trivially_destructible<T> + + // GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks + // std::vector for non-copyable types + #elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)) +-#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +-#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX ++#ifndef Q23_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX ++#define Q23_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX + QT_BEGIN_NAMESPACE + namespace q23 { + namespace detail { +@@ -121,50 +121,50 @@ struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {}; + QT_END_NAMESPACE + #endif + +-#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + q23::detail::is_trivially_copy_constructible<T> +-#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::is_trivially_copy_assignable<T> +-#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ + std::is_trivially_destructible<T> + #else +-#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ + std::is_trivially_copy_constructible<T> +-#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ + std::is_trivially_copy_assignable<T> +-#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ ++#define Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ + std::is_trivially_destructible<T> + #endif + + #ifdef _MSVC_LANG +-#define TL_CPLUSPLUS _MSVC_LANG ++#define Q23_TL_CPLUSPLUS _MSVC_LANG + #else +-#define TL_CPLUSPLUS __cplusplus ++#define Q23_TL_CPLUSPLUS __cplusplus + #endif + +-#if TL_CPLUSPLUS > 201103L +-#define TL_EXPECTED_CXX14 ++#if Q23_TL_CPLUSPLUS > 201103L ++#define Q23_TL_EXPECTED_CXX14 + #endif + +-#ifdef TL_EXPECTED_GCC49 +-#define TL_EXPECTED_GCC49_CONSTEXPR ++#ifdef Q23_TL_EXPECTED_GCC49 ++#define Q23_TL_EXPECTED_GCC49_CONSTEXPR + #else +-#define TL_EXPECTED_GCC49_CONSTEXPR constexpr ++#define Q23_TL_EXPECTED_GCC49_CONSTEXPR constexpr + #endif + +-#if (TL_CPLUSPLUS == 201103L || defined(TL_EXPECTED_MSVC2015) || \ +- defined(TL_EXPECTED_GCC49)) +-#define TL_EXPECTED_11_CONSTEXPR ++#if (Q23_TL_CPLUSPLUS == 201103L || defined(Q23_TL_EXPECTED_MSVC2015) || \ ++ defined(Q23_TL_EXPECTED_GCC49)) ++#define Q23_TL_EXPECTED_11_CONSTEXPR + #else +-#define TL_EXPECTED_11_CONSTEXPR constexpr ++#define Q23_TL_EXPECTED_11_CONSTEXPR constexpr + #endif + + QT_BEGIN_NAMESPACE + namespace q23 { + template <class T, class E> class expected; + +-#ifndef TL_MONOSTATE_INPLACE_MUTEX +-#define TL_MONOSTATE_INPLACE_MUTEX ++#ifndef Q23_TL_MONOSTATE_INPLACE_MUTEX ++#define Q23_TL_MONOSTATE_INPLACE_MUTEX + class monostate {}; + + struct in_place_t { +@@ -196,8 +196,8 @@ public: + : m_val(l, std::forward<Args>(args)...) {} + + constexpr const E &error() const & { return m_val; } +- TL_EXPECTED_11_CONSTEXPR E &error() & { return m_val; } +- TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(m_val); } ++ Q23_TL_EXPECTED_11_CONSTEXPR E &error() & { return m_val; } ++ Q23_TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(m_val); } + constexpr const E &&error() const && { return std::move(m_val); } + + private: +@@ -245,8 +245,8 @@ static constexpr unexpect_t unexpect{}; + + namespace detail { + template <typename E> +-[[noreturn]] TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) { +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++[[noreturn]] Q23_TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) { ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + throw std::forward<E>(e); + #else + (void)e; +@@ -258,8 +258,8 @@ template <typename E> + #endif + } + +-#ifndef TL_TRAITS_MUTEX +-#define TL_TRAITS_MUTEX ++#ifndef Q23_TL_TRAITS_MUTEX ++#define Q23_TL_TRAITS_MUTEX + // C++14-style aliases for brevity + template <class T> using remove_const_t = typename std::remove_const<T>::type; + template <class T> +@@ -278,13 +278,13 @@ struct conjunction<B, Bs...> + : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {}; + + #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L +-#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND ++#define Q23_TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND + #endif + + // In C++11 mode, there's an issue in libc++'s std::mem_fn + // which results in a hard-error when using it in a noexcept expression + // in some cases. This is a check to workaround the common failing case. +-#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND ++#ifdef Q23_TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND + template <class T> + struct is_pointer_to_non_const_member_func : std::false_type {}; + template <class T, class Ret, class... Args> +@@ -315,7 +315,7 @@ template <class T> struct is_const_or_const_ref<T const> : std::true_type {}; + // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround + template < + typename Fn, typename... Args, +-#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND ++#ifdef Q23_TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND + typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && + is_const_or_const_ref<Args...>::value)>, + #endif +@@ -574,7 +574,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> { + // T is trivial, E is not. + template <class T, class E> struct expected_storage_base<T, E, true, false> { + constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} +- TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) ++ Q23_TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) + : m_no_init(), m_has_val(false) {} + + template <class... Args, +@@ -675,7 +675,7 @@ template <class E> struct expected_storage_base<void, E, false, true> { + #if __GNUC__ <= 5 + //no constexpr for GCC 4/5 bug + #else +- TL_EXPECTED_MSVC2015_CONSTEXPR ++ Q23_TL_EXPECTED_MSVC2015_CONSTEXPR + #endif + expected_storage_base() : m_has_val(true) {} + +@@ -770,7 +770,7 @@ struct expected_operations_base : expected_storage_base<T, E> { + this->m_has_val = false; + } + +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + + // These assign overloads ensure that the most efficient assignment + // implementation is used while maintaining the strong exception guarantee. +@@ -820,7 +820,7 @@ struct expected_operations_base : expected_storage_base<T, E> { + auto tmp = std::move(geterr()); + geterr().~unexpected<E>(); + +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + construct(rhs.get()); + } catch (...) { +@@ -855,7 +855,7 @@ struct expected_operations_base : expected_storage_base<T, E> { + if (!this->m_has_val && rhs.m_has_val) { + auto tmp = std::move(geterr()); + geterr().~unexpected<E>(); +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + construct(std::move(rhs).get()); + } catch (...) { +@@ -911,27 +911,27 @@ struct expected_operations_base : expected_storage_base<T, E> { + + bool has_value() const { return this->m_has_val; } + +- TL_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; } ++ Q23_TL_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; } + constexpr const T &get() const & { return this->m_val; } +- TL_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); } +-#ifndef TL_EXPECTED_NO_CONSTRR ++ Q23_TL_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); } ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + constexpr const T &&get() const && { return std::move(this->m_val); } + #endif + +- TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { ++ Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { + return this->m_unexpect; + } + constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; } +- TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { ++ Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { + return std::move(this->m_unexpect); + } +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + constexpr const unexpected<E> &&geterr() const && { + return std::move(this->m_unexpect); + } + #endif + +- TL_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); } ++ Q23_TL_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); } + }; + + // This base class provides some handy member functions which can be used in +@@ -971,20 +971,20 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> { + + bool has_value() const { return this->m_has_val; } + +- TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { ++ Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { + return this->m_unexpect; + } + constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; } +- TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { ++ Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { + return std::move(this->m_unexpect); + } +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + constexpr const unexpected<E> &&geterr() const && { + return std::move(this->m_unexpect); + } + #endif + +- TL_EXPECTED_11_CONSTEXPR void destroy_val() { ++ Q23_TL_EXPECTED_11_CONSTEXPR void destroy_val() { + // no-op + } + }; +@@ -992,8 +992,8 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> { + // This class manages conditionally having a trivial copy constructor + // This specialization is for when T and E are trivially copy constructible + template <class T, class E, +- bool = is_void_or<T, TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>:: +- value &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value, ++ bool = is_void_or<T, Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>:: ++ value &&Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value, + bool = (is_copy_constructible_or_void<T>::value && + std::is_copy_constructible<E>::value)> + struct expected_copy_base : expected_operations_base<T, E> { +@@ -1025,7 +1025,7 @@ struct expected_copy_base<T, E, false, true> : expected_operations_base<T, E> { + // doesn't implement an analogue to std::is_trivially_move_constructible. We + // have to make do with a non-trivial move constructor even if T is trivially + // move constructible +-#ifndef TL_EXPECTED_GCC49 ++#ifndef Q23_TL_EXPECTED_GCC49 + template <class T, class E, + bool = is_void_or<T, std::is_trivially_move_constructible<T>>::value + &&std::is_trivially_move_constructible<E>::value> +@@ -1058,12 +1058,12 @@ struct expected_move_base<T, E, false> : expected_copy_base<T, E> { + // This class manages conditionally having a trivial copy assignment operator + template <class T, class E, + bool = is_void_or< +- T, conjunction<TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T), +- TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T), +- TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)>>::value +- &&TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value +- &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value +- &&TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value, ++ T, conjunction<Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T), ++ Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T), ++ Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)>>::value ++ &&Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value ++ &&Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value ++ &&Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value, + bool = (is_copy_constructible_or_void<T>::value && + std::is_copy_constructible<E>::value && + is_copy_assignable_or_void<T>::value && +@@ -1093,7 +1093,7 @@ struct expected_copy_assign_base<T, E, false, true> : expected_move_base<T, E> { + // doesn't implement an analogue to std::is_trivially_move_assignable. We have + // to make do with a non-trivial move assignment operator even if T is trivially + // move assignable +-#ifndef TL_EXPECTED_GCC49 ++#ifndef Q23_TL_EXPECTED_GCC49 + template <class T, class E, + bool = + is_void_or<T, conjunction<std::is_trivially_destructible<T>, +@@ -1330,10 +1330,10 @@ class expected : private detail::expected_move_assign_base<T, E>, + + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR U &val() { ++ Q23_TL_EXPECTED_11_CONSTEXPR U &val() { + return this->m_val; + } +- TL_EXPECTED_11_CONSTEXPR unexpected<E> &err() { return this->m_unexpect; } ++ Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &err() { return this->m_unexpect; } + + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +@@ -1350,19 +1350,19 @@ public: + typedef E error_type; + typedef unexpected<E> unexpected_type; + +-#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ +- !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) +- template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & { ++#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ ++ !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & { + return and_then_impl(*this, std::forward<F>(f)); + } +- template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && { ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && { + return and_then_impl(std::move(*this), std::forward<F>(f)); + } + template <class F> constexpr auto and_then(F &&f) const & { + return and_then_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> constexpr auto and_then(F &&f) const && { + return and_then_impl(std::move(*this), std::forward<F>(f)); + } +@@ -1370,13 +1370,13 @@ public: + + #else + template <class F> +- TL_EXPECTED_11_CONSTEXPR auto ++ Q23_TL_EXPECTED_11_CONSTEXPR auto + and_then(F &&f) & -> decltype(and_then_impl(std::declval<expected &>(), + std::forward<F>(f))) { + return and_then_impl(*this, std::forward<F>(f)); + } + template <class F> +- TL_EXPECTED_11_CONSTEXPR auto ++ Q23_TL_EXPECTED_11_CONSTEXPR auto + and_then(F &&f) && -> decltype(and_then_impl(std::declval<expected &&>(), + std::forward<F>(f))) { + return and_then_impl(std::move(*this), std::forward<F>(f)); +@@ -1387,7 +1387,7 @@ public: + return and_then_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> + constexpr auto and_then(F &&f) const && -> decltype(and_then_impl( + std::declval<expected const &&>(), std::forward<F>(f))) { +@@ -1396,12 +1396,12 @@ public: + #endif + #endif + +-#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ +- !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) +- template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & { ++#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ ++ !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & { + return expected_map_impl(*this, std::forward<F>(f)); + } +- template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && { ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && { + return expected_map_impl(std::move(*this), std::forward<F>(f)); + } + template <class F> constexpr auto map(F &&f) const & { +@@ -1412,13 +1412,13 @@ public: + } + #else + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( + std::declval<expected &>(), std::declval<F &&>())) + map(F &&f) & { + return expected_map_impl(*this, std::forward<F>(f)); + } + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), + std::declval<F &&>())) + map(F &&f) && { + return expected_map_impl(std::move(*this), std::forward<F>(f)); +@@ -1430,7 +1430,7 @@ public: + return expected_map_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> + constexpr decltype(expected_map_impl(std::declval<const expected &&>(), + std::declval<F &&>())) +@@ -1440,12 +1440,12 @@ public: + #endif + #endif + +-#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ +- !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) +- template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & { ++#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ ++ !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & { + return expected_map_impl(*this, std::forward<F>(f)); + } +- template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && { ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && { + return expected_map_impl(std::move(*this), std::forward<F>(f)); + } + template <class F> constexpr auto transform(F &&f) const & { +@@ -1456,13 +1456,13 @@ public: + } + #else + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( + std::declval<expected &>(), std::declval<F &&>())) + transform(F &&f) & { + return expected_map_impl(*this, std::forward<F>(f)); + } + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), + std::declval<F &&>())) + transform(F &&f) && { + return expected_map_impl(std::move(*this), std::forward<F>(f)); +@@ -1474,7 +1474,7 @@ public: + return expected_map_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> + constexpr decltype(expected_map_impl(std::declval<const expected &&>(), + std::declval<F &&>())) +@@ -1484,12 +1484,12 @@ public: + #endif + #endif + +-#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ +- !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) +- template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & { ++#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ ++ !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & { + return map_error_impl(*this, std::forward<F>(f)); + } +- template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && { ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && { + return map_error_impl(std::move(*this), std::forward<F>(f)); + } + template <class F> constexpr auto map_error(F &&f) const & { +@@ -1500,13 +1500,13 @@ public: + } + #else + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), + std::declval<F &&>())) + map_error(F &&f) & { + return map_error_impl(*this, std::forward<F>(f)); + } + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), + std::declval<F &&>())) + map_error(F &&f) && { + return map_error_impl(std::move(*this), std::forward<F>(f)); +@@ -1518,7 +1518,7 @@ public: + return map_error_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> + constexpr decltype(map_error_impl(std::declval<const expected &&>(), + std::declval<F &&>())) +@@ -1527,12 +1527,12 @@ public: + } + #endif + #endif +-#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ +- !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) +- template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & { ++#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ ++ !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & { + return map_error_impl(*this, std::forward<F>(f)); + } +- template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && { ++ template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && { + return map_error_impl(std::move(*this), std::forward<F>(f)); + } + template <class F> constexpr auto transform_error(F &&f) const & { +@@ -1543,13 +1543,13 @@ public: + } + #else + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), + std::declval<F &&>())) + transform_error(F &&f) & { + return map_error_impl(*this, std::forward<F>(f)); + } + template <class F> +- TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), ++ Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), + std::declval<F &&>())) + transform_error(F &&f) && { + return map_error_impl(std::move(*this), std::forward<F>(f)); +@@ -1561,7 +1561,7 @@ public: + return map_error_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> + constexpr decltype(map_error_impl(std::declval<const expected &&>(), + std::declval<F &&>())) +@@ -1570,11 +1570,11 @@ public: + } + #endif + #endif +- template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & { ++ template <class F> expected Q23_TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & { + return or_else_impl(*this, std::forward<F>(f)); + } + +- template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && { ++ template <class F> expected Q23_TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && { + return or_else_impl(std::move(*this), std::forward<F>(f)); + } + +@@ -1582,7 +1582,7 @@ public: + return or_else_impl(*this, std::forward<F>(f)); + } + +-#ifndef TL_EXPECTED_NO_CONSTRR ++#ifndef Q23_TL_EXPECTED_NO_CONSTRR + template <class F> expected constexpr or_else(F &&f) const && { + return or_else_impl(std::move(*this), std::forward<F>(f)); + } +@@ -1664,7 +1664,7 @@ public: + nullptr, + detail::expected_enable_from_other<T, E, U, G, const U &, const G &> + * = nullptr> +- explicit TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) ++ explicit Q23_TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) + : ctor_base(detail::default_constructor_tag{}) { + if (rhs.has_value()) { + this->construct(*rhs); +@@ -1679,7 +1679,7 @@ public: + nullptr, + detail::expected_enable_from_other<T, E, U, G, const U &, const G &> + * = nullptr> +- TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) ++ Q23_TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) + : ctor_base(detail::default_constructor_tag{}) { + if (rhs.has_value()) { + this->construct(*rhs); +@@ -1693,7 +1693,7 @@ public: + detail::enable_if_t<!(std::is_convertible<U &&, T>::value && + std::is_convertible<G &&, E>::value)> * = nullptr, + detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr> +- explicit TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) ++ explicit Q23_TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) + : ctor_base(detail::default_constructor_tag{}) { + if (rhs.has_value()) { + this->construct(std::move(*rhs)); +@@ -1707,7 +1707,7 @@ public: + detail::enable_if_t<(std::is_convertible<U &&, T>::value && + std::is_convertible<G &&, E>::value)> * = nullptr, + detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) ++ Q23_TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) + : ctor_base(detail::default_constructor_tag{}) { + if (rhs.has_value()) { + this->construct(std::move(*rhs)); +@@ -1720,14 +1720,14 @@ public: + class U = T, + detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr, + detail::expected_enable_forward_value<T, E, U> * = nullptr> +- explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) ++ explicit Q23_TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) + : expected(in_place, std::forward<U>(v)) {} + + template < + class U = T, + detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr, + detail::expected_enable_forward_value<T, E, U> * = nullptr> +- TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) ++ Q23_TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) + : expected(in_place, std::forward<U>(v)) {} + + template < +@@ -1773,7 +1773,7 @@ public: + auto tmp = std::move(err()); + err().~unexpected<E>(); + +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + ::new (valptr()) T(std::forward<U>(v)); + this->m_has_val = true; +@@ -1842,7 +1842,7 @@ public: + auto tmp = std::move(err()); + err().~unexpected<E>(); + +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + ::new (valptr()) T(std::forward<Args>(args)...); + this->m_has_val = true; +@@ -1882,7 +1882,7 @@ public: + auto tmp = std::move(err()); + err().~unexpected<E>(); + +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + ::new (valptr()) T(il, std::forward<Args>(args)...); + this->m_has_val = true; +@@ -1943,7 +1943,7 @@ private: + move_constructing_e_can_throw) { + auto temp = std::move(val()); + val().~T(); +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + ::new (errptr()) unexpected_type(std::move(rhs.err())); + rhs.err().~unexpected_type(); +@@ -1966,7 +1966,7 @@ private: + e_is_nothrow_move_constructible) { + auto temp = std::move(rhs.err()); + rhs.err().~unexpected_type(); +-#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED ++#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED + try { + ::new (rhs.valptr()) T(std::move(val())); + val().~T(); +@@ -2008,36 +2008,36 @@ public: + } + + constexpr const T *operator->() const { +- TL_ASSERT(has_value()); ++ Q23_TL_ASSERT(has_value()); + return valptr(); + } +- TL_EXPECTED_11_CONSTEXPR T *operator->() { +- TL_ASSERT(has_value()); ++ Q23_TL_EXPECTED_11_CONSTEXPR T *operator->() { ++ Q23_TL_ASSERT(has_value()); + return valptr(); + } + + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> + constexpr const U &operator*() const & { +- TL_ASSERT(has_value()); ++ Q23_TL_ASSERT(has_value()); + return val(); + } + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR U &operator*() & { +- TL_ASSERT(has_value()); ++ Q23_TL_EXPECTED_11_CONSTEXPR U &operator*() & { ++ Q23_TL_ASSERT(has_value()); + return val(); + } + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> + constexpr const U &&operator*() const && { +- TL_ASSERT(has_value()); ++ Q23_TL_ASSERT(has_value()); + return std::move(val()); + } + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR U &&operator*() && { +- TL_ASSERT(has_value()); ++ Q23_TL_EXPECTED_11_CONSTEXPR U &&operator*() && { ++ Q23_TL_ASSERT(has_value()); + return std::move(val()); + } + +@@ -2046,47 +2046,47 @@ public: + + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR const U &value() const & { ++ Q23_TL_EXPECTED_11_CONSTEXPR const U &value() const & { + if (!has_value()) + detail::throw_exception(bad_expected_access<E>(err().error())); + return val(); + } + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR U &value() & { ++ Q23_TL_EXPECTED_11_CONSTEXPR U &value() & { + if (!has_value()) + detail::throw_exception(bad_expected_access<E>(err().error())); + return val(); + } + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR const U &&value() const && { ++ Q23_TL_EXPECTED_11_CONSTEXPR const U &&value() const && { + if (!has_value()) + detail::throw_exception(bad_expected_access<E>(std::move(err()).error())); + return std::move(val()); + } + template <class U = T, + detail::enable_if_t<!std::is_void<U>::value> * = nullptr> +- TL_EXPECTED_11_CONSTEXPR U &&value() && { ++ Q23_TL_EXPECTED_11_CONSTEXPR U &&value() && { + if (!has_value()) + detail::throw_exception(bad_expected_access<E>(std::move(err()).error())); + return std::move(val()); + } + + constexpr const E &error() const & { +- TL_ASSERT(!has_value()); ++ Q23_TL_ASSERT(!has_value()); + return err().error(); + } +- TL_EXPECTED_11_CONSTEXPR E &error() & { +- TL_ASSERT(!has_value()); ++ Q23_TL_EXPECTED_11_CONSTEXPR E &error() & { ++ Q23_TL_ASSERT(!has_value()); + return err().error(); + } + constexpr const E &&error() const && { +- TL_ASSERT(!has_value()); ++ Q23_TL_ASSERT(!has_value()); + return std::move(err().error()); + } +- TL_EXPECTED_11_CONSTEXPR E &&error() && { +- TL_ASSERT(!has_value()); ++ Q23_TL_EXPECTED_11_CONSTEXPR E &&error() && { ++ Q23_TL_ASSERT(!has_value()); + return std::move(err().error()); + } + +@@ -2096,7 +2096,7 @@ public: + "T must be copy-constructible and convertible to from U&&"); + return bool(*this) ? **this : static_cast<T>(std::forward<U>(v)); + } +- template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && { ++ template <class U> Q23_TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && { + static_assert(std::is_move_constructible<T>::value && + std::is_convertible<U &&, T>::value, + "T must be move-constructible and convertible to from U&&"); +@@ -2109,7 +2109,7 @@ template <class Exp> using exp_t = typename detail::decay_t<Exp>::value_type; + template <class Exp> using err_t = typename detail::decay_t<Exp>::error_type; + template <class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>; + +-#ifdef TL_EXPECTED_CXX14 ++#ifdef Q23_TL_EXPECTED_CXX14 + template <class Exp, class F, + detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr, + class Ret = decltype(detail::invoke(std::declval<F>(), +@@ -2156,7 +2156,7 @@ constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret { + } + #endif + +-#ifdef TL_EXPECTED_CXX14 ++#ifdef Q23_TL_EXPECTED_CXX14 + template <class Exp, class F, + detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr, + class Ret = decltype(detail::invoke(std::declval<F>(), +@@ -2266,8 +2266,8 @@ auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> { + } + #endif + +-#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ +- !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) ++#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ ++ !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) + template <class Exp, class F, + detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr, + class Ret = decltype(detail::invoke(std::declval<F>(), +@@ -2382,7 +2382,7 @@ auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> { + } + #endif + +-#ifdef TL_EXPECTED_CXX14 ++#ifdef Q23_TL_EXPECTED_CXX14 + template <class Exp, class F, + class Ret = decltype(detail::invoke(std::declval<F>(), + std::declval<Exp>().error())), +-- +2.25.1 + diff --git a/src/corelib/global/qexpected_p.h b/src/corelib/global/qexpected_p.h index 24ea5be1e5e..54bcae51102 100644 --- a/src/corelib/global/qexpected_p.h +++ b/src/corelib/global/qexpected_p.h @@ -16,8 +16,8 @@ // <http://creativecommons.org/publicdomain/zero/1.0/>. /// -#ifndef TL_EXPECTED_HPP -#define TL_EXPECTED_HPP +#ifndef Q23_TL_EXPECTED_HPP +#define Q23_TL_EXPECTED_HPP // // W A R N I N G @@ -30,9 +30,9 @@ // We mean it. // -#define TL_EXPECTED_VERSION_MAJOR 1 -#define TL_EXPECTED_VERSION_MINOR 1 -#define TL_EXPECTED_VERSION_PATCH 0 +#define Q23_TL_EXPECTED_VERSION_MAJOR 1 +#define Q23_TL_EXPECTED_VERSION_MINOR 1 +#define Q23_TL_EXPECTED_VERSION_PATCH 0 #include <QtCore/private/qglobal_p.h> #include <QtCore/qassert.h> @@ -44,45 +44,45 @@ #include <type_traits> #include <utility> -#define TL_ASSERT Q_ASSERT +#define Q23_TL_ASSERT Q_ASSERT #if defined(__EXCEPTIONS) || defined(_CPPUNWIND) -#define TL_EXPECTED_EXCEPTIONS_ENABLED +#define Q23_TL_EXPECTED_EXCEPTIONS_ENABLED #endif -#if defined(TL_EXPECTED_EXCEPTIONS_ENABLED) && defined(QT_NO_EXCEPTIONS) -# undef TL_EXPECTED_EXCEPTIONS_ENABLED +#if defined(Q23_TL_EXPECTED_EXCEPTIONS_ENABLED) && defined(QT_NO_EXCEPTIONS) +# undef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED #endif #if (defined(_MSC_VER) && _MSC_VER == 1900) -#define TL_EXPECTED_MSVC2015 -#define TL_EXPECTED_MSVC2015_CONSTEXPR +#define Q23_TL_EXPECTED_MSVC2015 +#define Q23_TL_EXPECTED_MSVC2015_CONSTEXPR #else -#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr +#define Q23_TL_EXPECTED_MSVC2015_CONSTEXPR constexpr #endif #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ !defined(__clang__)) -#define TL_EXPECTED_GCC49 +#define Q23_TL_EXPECTED_GCC49 #endif #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \ !defined(__clang__)) -#define TL_EXPECTED_GCC54 +#define Q23_TL_EXPECTED_GCC54 #endif #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \ !defined(__clang__)) -#define TL_EXPECTED_GCC55 +#define Q23_TL_EXPECTED_GCC55 #endif -#if !defined(TL_ASSERT) +#if !defined(Q23_TL_ASSERT) //can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug -#if (TL_CPLUSPLUS > 201103L) && !defined(TL_EXPECTED_GCC49) +#if (Q23_TL_CPLUSPLUS > 201103L) && !defined(Q23_TL_EXPECTED_GCC49) #include <cassert> -#define TL_ASSERT(x) assert(x) +#define Q23_TL_ASSERT(x) assert(x) #else -#define TL_ASSERT(x) +#define Q23_TL_ASSERT(x) #endif #endif @@ -90,22 +90,22 @@ !defined(__clang__)) // GCC < 5 doesn't support overloading on const&& for member functions -#define TL_EXPECTED_NO_CONSTRR +#define Q23_TL_EXPECTED_NO_CONSTRR // GCC < 5 doesn't support some standard C++11 type traits -#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::has_trivial_copy_constructor<T> -#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::has_trivial_copy_assign<T> // This one will be different for GCC 5.7 if it's ever supported -#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible<T> // GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks // std::vector for non-copyable types #elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)) -#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX -#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +#ifndef Q23_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX +#define Q23_TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX QT_BEGIN_NAMESPACE namespace q23 { namespace detail { @@ -121,50 +121,50 @@ struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {}; QT_END_NAMESPACE #endif -#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ q23::detail::is_trivially_copy_constructible<T> -#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::is_trivially_copy_assignable<T> -#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible<T> #else -#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ std::is_trivially_copy_constructible<T> -#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ std::is_trivially_copy_assignable<T> -#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ +#define Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \ std::is_trivially_destructible<T> #endif #ifdef _MSVC_LANG -#define TL_CPLUSPLUS _MSVC_LANG +#define Q23_TL_CPLUSPLUS _MSVC_LANG #else -#define TL_CPLUSPLUS __cplusplus +#define Q23_TL_CPLUSPLUS __cplusplus #endif -#if TL_CPLUSPLUS > 201103L -#define TL_EXPECTED_CXX14 +#if Q23_TL_CPLUSPLUS > 201103L +#define Q23_TL_EXPECTED_CXX14 #endif -#ifdef TL_EXPECTED_GCC49 -#define TL_EXPECTED_GCC49_CONSTEXPR +#ifdef Q23_TL_EXPECTED_GCC49 +#define Q23_TL_EXPECTED_GCC49_CONSTEXPR #else -#define TL_EXPECTED_GCC49_CONSTEXPR constexpr +#define Q23_TL_EXPECTED_GCC49_CONSTEXPR constexpr #endif -#if (TL_CPLUSPLUS == 201103L || defined(TL_EXPECTED_MSVC2015) || \ - defined(TL_EXPECTED_GCC49)) -#define TL_EXPECTED_11_CONSTEXPR +#if (Q23_TL_CPLUSPLUS == 201103L || defined(Q23_TL_EXPECTED_MSVC2015) || \ + defined(Q23_TL_EXPECTED_GCC49)) +#define Q23_TL_EXPECTED_11_CONSTEXPR #else -#define TL_EXPECTED_11_CONSTEXPR constexpr +#define Q23_TL_EXPECTED_11_CONSTEXPR constexpr #endif QT_BEGIN_NAMESPACE namespace q23 { template <class T, class E> class expected; -#ifndef TL_MONOSTATE_INPLACE_MUTEX -#define TL_MONOSTATE_INPLACE_MUTEX +#ifndef Q23_TL_MONOSTATE_INPLACE_MUTEX +#define Q23_TL_MONOSTATE_INPLACE_MUTEX class monostate {}; struct in_place_t { @@ -196,8 +196,8 @@ public: : m_val(l, std::forward<Args>(args)...) {} constexpr const E &error() const & { return m_val; } - TL_EXPECTED_11_CONSTEXPR E &error() & { return m_val; } - TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(m_val); } + Q23_TL_EXPECTED_11_CONSTEXPR E &error() & { return m_val; } + Q23_TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(m_val); } constexpr const E &&error() const && { return std::move(m_val); } private: @@ -245,8 +245,8 @@ static constexpr unexpect_t unexpect{}; namespace detail { template <typename E> -[[noreturn]] TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) { -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +[[noreturn]] Q23_TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) { +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED throw std::forward<E>(e); #else (void)e; @@ -258,8 +258,8 @@ template <typename E> #endif } -#ifndef TL_TRAITS_MUTEX -#define TL_TRAITS_MUTEX +#ifndef Q23_TL_TRAITS_MUTEX +#define Q23_TL_TRAITS_MUTEX // C++14-style aliases for brevity template <class T> using remove_const_t = typename std::remove_const<T>::type; template <class T> @@ -278,13 +278,13 @@ struct conjunction<B, Bs...> : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {}; #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L -#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND +#define Q23_TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND #endif // In C++11 mode, there's an issue in libc++'s std::mem_fn // which results in a hard-error when using it in a noexcept expression // in some cases. This is a check to workaround the common failing case. -#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND +#ifdef Q23_TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND template <class T> struct is_pointer_to_non_const_member_func : std::false_type {}; template <class T, class Ret, class... Args> @@ -315,7 +315,7 @@ template <class T> struct is_const_or_const_ref<T const> : std::true_type {}; // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround template < typename Fn, typename... Args, -#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND +#ifdef Q23_TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && is_const_or_const_ref<Args...>::value)>, #endif @@ -574,7 +574,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> { // T is trivial, E is not. template <class T, class E> struct expected_storage_base<T, E, true, false> { constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) + Q23_TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {} template <class... Args, @@ -675,7 +675,7 @@ template <class E> struct expected_storage_base<void, E, false, true> { #if __GNUC__ <= 5 //no constexpr for GCC 4/5 bug #else - TL_EXPECTED_MSVC2015_CONSTEXPR + Q23_TL_EXPECTED_MSVC2015_CONSTEXPR #endif expected_storage_base() : m_has_val(true) {} @@ -770,7 +770,7 @@ struct expected_operations_base : expected_storage_base<T, E> { this->m_has_val = false; } -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED // These assign overloads ensure that the most efficient assignment // implementation is used while maintaining the strong exception guarantee. @@ -820,7 +820,7 @@ struct expected_operations_base : expected_storage_base<T, E> { auto tmp = std::move(geterr()); geterr().~unexpected<E>(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { construct(rhs.get()); } catch (...) { @@ -855,7 +855,7 @@ struct expected_operations_base : expected_storage_base<T, E> { if (!this->m_has_val && rhs.m_has_val) { auto tmp = std::move(geterr()); geterr().~unexpected<E>(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { construct(std::move(rhs).get()); } catch (...) { @@ -911,27 +911,27 @@ struct expected_operations_base : expected_storage_base<T, E> { bool has_value() const { return this->m_has_val; } - TL_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; } + Q23_TL_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; } constexpr const T &get() const & { return this->m_val; } - TL_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); } -#ifndef TL_EXPECTED_NO_CONSTRR + Q23_TL_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); } +#ifndef Q23_TL_EXPECTED_NO_CONSTRR constexpr const T &&get() const && { return std::move(this->m_val); } #endif - TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { + Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { return this->m_unexpect; } constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; } - TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { + Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { return std::move(this->m_unexpect); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR constexpr const unexpected<E> &&geterr() const && { return std::move(this->m_unexpect); } #endif - TL_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); } + Q23_TL_EXPECTED_11_CONSTEXPR void destroy_val() { get().~T(); } }; // This base class provides some handy member functions which can be used in @@ -971,20 +971,20 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> { bool has_value() const { return this->m_has_val; } - TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { + Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & { return this->m_unexpect; } constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; } - TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { + Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && { return std::move(this->m_unexpect); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR constexpr const unexpected<E> &&geterr() const && { return std::move(this->m_unexpect); } #endif - TL_EXPECTED_11_CONSTEXPR void destroy_val() { + Q23_TL_EXPECTED_11_CONSTEXPR void destroy_val() { // no-op } }; @@ -992,8 +992,8 @@ struct expected_operations_base<void, E> : expected_storage_base<void, E> { // This class manages conditionally having a trivial copy constructor // This specialization is for when T and E are trivially copy constructible template <class T, class E, - bool = is_void_or<T, TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>:: - value &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value, + bool = is_void_or<T, Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>:: + value &&Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value, bool = (is_copy_constructible_or_void<T>::value && std::is_copy_constructible<E>::value)> struct expected_copy_base : expected_operations_base<T, E> { @@ -1025,7 +1025,7 @@ struct expected_copy_base<T, E, false, true> : expected_operations_base<T, E> { // doesn't implement an analogue to std::is_trivially_move_constructible. We // have to make do with a non-trivial move constructor even if T is trivially // move constructible -#ifndef TL_EXPECTED_GCC49 +#ifndef Q23_TL_EXPECTED_GCC49 template <class T, class E, bool = is_void_or<T, std::is_trivially_move_constructible<T>>::value &&std::is_trivially_move_constructible<E>::value> @@ -1058,12 +1058,12 @@ struct expected_move_base<T, E, false> : expected_copy_base<T, E> { // This class manages conditionally having a trivial copy assignment operator template <class T, class E, bool = is_void_or< - T, conjunction<TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T), - TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T), - TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)>>::value - &&TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value - &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value - &&TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value, + T, conjunction<Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T), + Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T), + Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)>>::value + &&Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value + &&Q23_TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value + &&Q23_TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value, bool = (is_copy_constructible_or_void<T>::value && std::is_copy_constructible<E>::value && is_copy_assignable_or_void<T>::value && @@ -1093,7 +1093,7 @@ struct expected_copy_assign_base<T, E, false, true> : expected_move_base<T, E> { // doesn't implement an analogue to std::is_trivially_move_assignable. We have // to make do with a non-trivial move assignment operator even if T is trivially // move assignable -#ifndef TL_EXPECTED_GCC49 +#ifndef Q23_TL_EXPECTED_GCC49 template <class T, class E, bool = is_void_or<T, conjunction<std::is_trivially_destructible<T>, @@ -1330,10 +1330,10 @@ class expected : private detail::expected_move_assign_base<T, E>, template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR U &val() { + Q23_TL_EXPECTED_11_CONSTEXPR U &val() { return this->m_val; } - TL_EXPECTED_11_CONSTEXPR unexpected<E> &err() { return this->m_unexpect; } + Q23_TL_EXPECTED_11_CONSTEXPR unexpected<E> &err() { return this->m_unexpect; } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> @@ -1350,19 +1350,19 @@ public: typedef E error_type; typedef unexpected<E> unexpected_type; -#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ - !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) - template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & { +#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ + !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & { return and_then_impl(*this, std::forward<F>(f)); } - template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && { + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && { return and_then_impl(std::move(*this), std::forward<F>(f)); } template <class F> constexpr auto and_then(F &&f) const & { return and_then_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> constexpr auto and_then(F &&f) const && { return and_then_impl(std::move(*this), std::forward<F>(f)); } @@ -1370,13 +1370,13 @@ public: #else template <class F> - TL_EXPECTED_11_CONSTEXPR auto + Q23_TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & -> decltype(and_then_impl(std::declval<expected &>(), std::forward<F>(f))) { return and_then_impl(*this, std::forward<F>(f)); } template <class F> - TL_EXPECTED_11_CONSTEXPR auto + Q23_TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && -> decltype(and_then_impl(std::declval<expected &&>(), std::forward<F>(f))) { return and_then_impl(std::move(*this), std::forward<F>(f)); @@ -1387,7 +1387,7 @@ public: return and_then_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> constexpr auto and_then(F &&f) const && -> decltype(and_then_impl( std::declval<expected const &&>(), std::forward<F>(f))) { @@ -1396,12 +1396,12 @@ public: #endif #endif -#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ - !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) - template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & { +#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ + !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & { return expected_map_impl(*this, std::forward<F>(f)); } - template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && { + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && { return expected_map_impl(std::move(*this), std::forward<F>(f)); } template <class F> constexpr auto map(F &&f) const & { @@ -1412,13 +1412,13 @@ public: } #else template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( + Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( std::declval<expected &>(), std::declval<F &&>())) map(F &&f) & { return expected_map_impl(*this, std::forward<F>(f)); } template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), + Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), std::declval<F &&>())) map(F &&f) && { return expected_map_impl(std::move(*this), std::forward<F>(f)); @@ -1430,7 +1430,7 @@ public: return expected_map_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> constexpr decltype(expected_map_impl(std::declval<const expected &&>(), std::declval<F &&>())) @@ -1440,12 +1440,12 @@ public: #endif #endif -#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ - !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) - template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & { +#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ + !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & { return expected_map_impl(*this, std::forward<F>(f)); } - template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && { + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && { return expected_map_impl(std::move(*this), std::forward<F>(f)); } template <class F> constexpr auto transform(F &&f) const & { @@ -1456,13 +1456,13 @@ public: } #else template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( + Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl( std::declval<expected &>(), std::declval<F &&>())) transform(F &&f) & { return expected_map_impl(*this, std::forward<F>(f)); } template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), + Q23_TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval<expected>(), std::declval<F &&>())) transform(F &&f) && { return expected_map_impl(std::move(*this), std::forward<F>(f)); @@ -1474,7 +1474,7 @@ public: return expected_map_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> constexpr decltype(expected_map_impl(std::declval<const expected &&>(), std::declval<F &&>())) @@ -1484,12 +1484,12 @@ public: #endif #endif -#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ - !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) - template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & { +#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ + !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & { return map_error_impl(*this, std::forward<F>(f)); } - template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && { + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && { return map_error_impl(std::move(*this), std::forward<F>(f)); } template <class F> constexpr auto map_error(F &&f) const & { @@ -1500,13 +1500,13 @@ public: } #else template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), + Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), std::declval<F &&>())) map_error(F &&f) & { return map_error_impl(*this, std::forward<F>(f)); } template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), + Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), std::declval<F &&>())) map_error(F &&f) && { return map_error_impl(std::move(*this), std::forward<F>(f)); @@ -1518,7 +1518,7 @@ public: return map_error_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> constexpr decltype(map_error_impl(std::declval<const expected &&>(), std::declval<F &&>())) @@ -1527,12 +1527,12 @@ public: } #endif #endif -#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ - !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) - template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & { +#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ + !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & { return map_error_impl(*this, std::forward<F>(f)); } - template <class F> TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && { + template <class F> Q23_TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && { return map_error_impl(std::move(*this), std::forward<F>(f)); } template <class F> constexpr auto transform_error(F &&f) const & { @@ -1543,13 +1543,13 @@ public: } #else template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), + Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), std::declval<F &&>())) transform_error(F &&f) & { return map_error_impl(*this, std::forward<F>(f)); } template <class F> - TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), + Q23_TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), std::declval<F &&>())) transform_error(F &&f) && { return map_error_impl(std::move(*this), std::forward<F>(f)); @@ -1561,7 +1561,7 @@ public: return map_error_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> constexpr decltype(map_error_impl(std::declval<const expected &&>(), std::declval<F &&>())) @@ -1570,11 +1570,11 @@ public: } #endif #endif - template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & { + template <class F> expected Q23_TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & { return or_else_impl(*this, std::forward<F>(f)); } - template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && { + template <class F> expected Q23_TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && { return or_else_impl(std::move(*this), std::forward<F>(f)); } @@ -1582,7 +1582,7 @@ public: return or_else_impl(*this, std::forward<F>(f)); } -#ifndef TL_EXPECTED_NO_CONSTRR +#ifndef Q23_TL_EXPECTED_NO_CONSTRR template <class F> expected constexpr or_else(F &&f) const && { return or_else_impl(std::move(*this), std::forward<F>(f)); } @@ -1664,7 +1664,7 @@ public: nullptr, detail::expected_enable_from_other<T, E, U, G, const U &, const G &> * = nullptr> - explicit TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) + explicit Q23_TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) : ctor_base(detail::default_constructor_tag{}) { if (rhs.has_value()) { this->construct(*rhs); @@ -1679,7 +1679,7 @@ public: nullptr, detail::expected_enable_from_other<T, E, U, G, const U &, const G &> * = nullptr> - TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) + Q23_TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs) : ctor_base(detail::default_constructor_tag{}) { if (rhs.has_value()) { this->construct(*rhs); @@ -1693,7 +1693,7 @@ public: detail::enable_if_t<!(std::is_convertible<U &&, T>::value && std::is_convertible<G &&, E>::value)> * = nullptr, detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr> - explicit TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) + explicit Q23_TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) : ctor_base(detail::default_constructor_tag{}) { if (rhs.has_value()) { this->construct(std::move(*rhs)); @@ -1707,7 +1707,7 @@ public: detail::enable_if_t<(std::is_convertible<U &&, T>::value && std::is_convertible<G &&, E>::value)> * = nullptr, detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr> - TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) + Q23_TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs) : ctor_base(detail::default_constructor_tag{}) { if (rhs.has_value()) { this->construct(std::move(*rhs)); @@ -1720,14 +1720,14 @@ public: class U = T, detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr, detail::expected_enable_forward_value<T, E, U> * = nullptr> - explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) + explicit Q23_TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) : expected(in_place, std::forward<U>(v)) {} template < class U = T, detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr, detail::expected_enable_forward_value<T, E, U> * = nullptr> - TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) + Q23_TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) : expected(in_place, std::forward<U>(v)) {} template < @@ -1773,7 +1773,7 @@ public: auto tmp = std::move(err()); err().~unexpected<E>(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { ::new (valptr()) T(std::forward<U>(v)); this->m_has_val = true; @@ -1842,7 +1842,7 @@ public: auto tmp = std::move(err()); err().~unexpected<E>(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { ::new (valptr()) T(std::forward<Args>(args)...); this->m_has_val = true; @@ -1882,7 +1882,7 @@ public: auto tmp = std::move(err()); err().~unexpected<E>(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { ::new (valptr()) T(il, std::forward<Args>(args)...); this->m_has_val = true; @@ -1943,7 +1943,7 @@ private: move_constructing_e_can_throw) { auto temp = std::move(val()); val().~T(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { ::new (errptr()) unexpected_type(std::move(rhs.err())); rhs.err().~unexpected_type(); @@ -1966,7 +1966,7 @@ private: e_is_nothrow_move_constructible) { auto temp = std::move(rhs.err()); rhs.err().~unexpected_type(); -#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED +#ifdef Q23_TL_EXPECTED_EXCEPTIONS_ENABLED try { ::new (rhs.valptr()) T(std::move(val())); val().~T(); @@ -2008,36 +2008,36 @@ public: } constexpr const T *operator->() const { - TL_ASSERT(has_value()); + Q23_TL_ASSERT(has_value()); return valptr(); } - TL_EXPECTED_11_CONSTEXPR T *operator->() { - TL_ASSERT(has_value()); + Q23_TL_EXPECTED_11_CONSTEXPR T *operator->() { + Q23_TL_ASSERT(has_value()); return valptr(); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> constexpr const U &operator*() const & { - TL_ASSERT(has_value()); + Q23_TL_ASSERT(has_value()); return val(); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR U &operator*() & { - TL_ASSERT(has_value()); + Q23_TL_EXPECTED_11_CONSTEXPR U &operator*() & { + Q23_TL_ASSERT(has_value()); return val(); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> constexpr const U &&operator*() const && { - TL_ASSERT(has_value()); + Q23_TL_ASSERT(has_value()); return std::move(val()); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR U &&operator*() && { - TL_ASSERT(has_value()); + Q23_TL_EXPECTED_11_CONSTEXPR U &&operator*() && { + Q23_TL_ASSERT(has_value()); return std::move(val()); } @@ -2046,47 +2046,47 @@ public: template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR const U &value() const & { + Q23_TL_EXPECTED_11_CONSTEXPR const U &value() const & { if (!has_value()) detail::throw_exception(bad_expected_access<E>(err().error())); return val(); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR U &value() & { + Q23_TL_EXPECTED_11_CONSTEXPR U &value() & { if (!has_value()) detail::throw_exception(bad_expected_access<E>(err().error())); return val(); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR const U &&value() const && { + Q23_TL_EXPECTED_11_CONSTEXPR const U &&value() const && { if (!has_value()) detail::throw_exception(bad_expected_access<E>(std::move(err()).error())); return std::move(val()); } template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * = nullptr> - TL_EXPECTED_11_CONSTEXPR U &&value() && { + Q23_TL_EXPECTED_11_CONSTEXPR U &&value() && { if (!has_value()) detail::throw_exception(bad_expected_access<E>(std::move(err()).error())); return std::move(val()); } constexpr const E &error() const & { - TL_ASSERT(!has_value()); + Q23_TL_ASSERT(!has_value()); return err().error(); } - TL_EXPECTED_11_CONSTEXPR E &error() & { - TL_ASSERT(!has_value()); + Q23_TL_EXPECTED_11_CONSTEXPR E &error() & { + Q23_TL_ASSERT(!has_value()); return err().error(); } constexpr const E &&error() const && { - TL_ASSERT(!has_value()); + Q23_TL_ASSERT(!has_value()); return std::move(err().error()); } - TL_EXPECTED_11_CONSTEXPR E &&error() && { - TL_ASSERT(!has_value()); + Q23_TL_EXPECTED_11_CONSTEXPR E &&error() && { + Q23_TL_ASSERT(!has_value()); return std::move(err().error()); } @@ -2096,7 +2096,7 @@ public: "T must be copy-constructible and convertible to from U&&"); return bool(*this) ? **this : static_cast<T>(std::forward<U>(v)); } - template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && { + template <class U> Q23_TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && { static_assert(std::is_move_constructible<T>::value && std::is_convertible<U &&, T>::value, "T must be move-constructible and convertible to from U&&"); @@ -2109,7 +2109,7 @@ template <class Exp> using exp_t = typename detail::decay_t<Exp>::value_type; template <class Exp> using err_t = typename detail::decay_t<Exp>::error_type; template <class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>; -#ifdef TL_EXPECTED_CXX14 +#ifdef Q23_TL_EXPECTED_CXX14 template <class Exp, class F, detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr, class Ret = decltype(detail::invoke(std::declval<F>(), @@ -2156,7 +2156,7 @@ constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret { } #endif -#ifdef TL_EXPECTED_CXX14 +#ifdef Q23_TL_EXPECTED_CXX14 template <class Exp, class F, detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr, class Ret = decltype(detail::invoke(std::declval<F>(), @@ -2266,8 +2266,8 @@ auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> { } #endif -#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ - !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) +#if defined(Q23_TL_EXPECTED_CXX14) && !defined(Q23_TL_EXPECTED_GCC49) && \ + !defined(Q23_TL_EXPECTED_GCC54) && !defined(Q23_TL_EXPECTED_GCC55) template <class Exp, class F, detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr, class Ret = decltype(detail::invoke(std::declval<F>(), @@ -2382,7 +2382,7 @@ auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> { } #endif -#ifdef TL_EXPECTED_CXX14 +#ifdef Q23_TL_EXPECTED_CXX14 template <class Exp, class F, class Ret = decltype(detail::invoke(std::declval<F>(), std::declval<Exp>().error())), diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h index 4568d089590..db32ae73556 100644 --- a/src/corelib/global/qnumeric.h +++ b/src/corelib/global/qnumeric.h @@ -641,7 +641,7 @@ template <typename T, typename S> [[nodiscard]] constexpr bool fuzzyCompare(const T &lhs, const S &rhs) noexcept { static_assert(noexcept(qIsNull(lhs) && qIsNull(rhs) && qFuzzyIsNull(lhs - rhs) && qFuzzyCompare(lhs, rhs)), - "The operations qIsNull(), qFuzzyIsNull() and qFuzzyCompare() must be noexcept" + "The operations qIsNull(), qFuzzyIsNull() and qFuzzyCompare() must be noexcept " "for both argument types!"); return qIsNull(lhs) || qIsNull(rhs) ? qFuzzyIsNull(lhs - rhs) : qFuzzyCompare(lhs, rhs); } diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp index d27a71526d8..32364fa8eb4 100644 --- a/src/corelib/global/qoperatingsystemversion.cpp +++ b/src/corelib/global/qoperatingsystemversion.cpp @@ -486,6 +486,12 @@ const QOperatingSystemVersionBase QOperatingSystemVersion::Windows11_22H2; */ /*! + \variable QOperatingSystemVersion::Windows11_25H2 + \brief a version corresponding to Windows 11 Version 25H2 (version 10.0.26200). + \since 6.11 + */ + +/*! \variable QOperatingSystemVersion::OSXMavericks \brief a version corresponding to OS X Mavericks (version 10.9). \since 5.9 diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h index 75801a7ddcf..99866692f8c 100644 --- a/src/corelib/global/qoperatingsystemversion.h +++ b/src/corelib/global/qoperatingsystemversion.h @@ -148,6 +148,7 @@ public: static constexpr QOperatingSystemVersionBase Android14 { QOperatingSystemVersionBase::Android, 14, 0 }; static constexpr QOperatingSystemVersionBase Windows11_23H2 { QOperatingSystemVersionBase::Windows, 10, 0, 22631 }; static constexpr QOperatingSystemVersionBase Windows11_24H2 { QOperatingSystemVersionBase::Windows, 10, 0, 26100 }; + static constexpr QOperatingSystemVersionBase Windows11_25H2 { QOperatingSystemVersionBase::Windows, 10, 0, 26200 }; #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED) && !defined(Q_QDOC) }; diff --git a/src/corelib/kernel/qiterable.h b/src/corelib/kernel/qiterable.h index baab2897967..494cec73a3f 100644 --- a/src/corelib/kernel/qiterable.h +++ b/src/corelib/kernel/qiterable.h @@ -502,7 +502,10 @@ public: if (m_metaContainer.hasSize()) return m_metaContainer.size(container); - // ### Qt7: Return -1 here. We shouldn't second-guess the underlying container +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + // We shouldn't second-guess the underlying container, so we're not synthesizing a size. + return -1; +#else QtPrivate::warnSynthesizedAccess( "size() called on an iterable without native size accessor. This is slow"); @@ -515,6 +518,7 @@ public: m_metaContainer.destroyConstIterator(begin); m_metaContainer.destroyConstIterator(end); return size; +#endif } void clear() diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp index abef9fdd663..21bfe5af448 100644 --- a/src/corelib/kernel/qjniobject.cpp +++ b/src/corelib/kernel/qjniobject.cpp @@ -27,7 +27,8 @@ using namespace Qt::StringLiterals; garbage-collected and providing access to most \c JNIEnv method calls (member, static) and fields (setter, getter). It eliminates much boiler-plate that would normally be needed, with direct JNI access, for - every operation, including exception-handling. + every operation. Exceptions thrown by called Java methods are cleared by + default, but can since Qt 6.11 also be handled by the caller. \note This API has been designed and tested for use with Android. It has not been tested for other platforms. @@ -129,12 +130,46 @@ using namespace Qt::StringLiterals; Note that while the first template parameter specifies the return type of the Java function, the method will still return a QJniObject. - \section1 Handling Java Exception + \section1 Handling Java Exceptions After calling Java functions that might throw exceptions, it is important to check for, handle and clear out any exception before continuing. All - QJniObject functions handle exceptions internally by reporting and clearing them, - saving client code the need to handle exceptions. + QJniObject functions can handle exceptions internally by reporting and + clearing them. This includes JNI exceptions, for instance when trying to + call a method that doesn't exist, or with bad parameters; and exceptions + are thrown by the method as a way of reporting errors or returning failure + information. + + From Qt 6.11 on, client code can opt in to handle exceptions explicitly in + each call. To do so, use \c{std::expected} from C++ 23 as the return type, + with the value type as the expected, and \c{jthrowable} as the error type. + For instance, trying to read a setting value via the + \c{android.provider.Settings.Secure} type might throw an exception if the + setting does not exist. + + \code + Q_DECLARE_JNI_CLASS(SettingsSecure, "android/provider/Settings$Secure") + using namespace QtJniTypes; + + QString enabledInputMethods() + { + ContentResolver resolver; + SettingsSecure settings; + + auto defaultInputMethods = settings.callMethod<std::expected<QString, jthrowable>>( + "getString", resolver, u"enabled_input_methods"_s + ); + if (defaultInputMethods) + return defaultInputMethods.value(); + QStringList stackTrace = QJniEnvironment::stackTrace(defaultInputMethods.error()); + } + \endcode + + You can use any other type that behaves like \c{std::expected}, so handling + exceptions explicitly is possible without using C++23. The only + requirements are that the type declares three nested types \c{value_type}, + \c{error_type}, and \c{unexpected_type}, can be constructed from the value + type, and from its \c{unexpected_type} holding a \c{jthrowable}. \note The user must handle exceptions manually when doing JNI calls using \c JNIEnv directly. It is unsafe to make other JNI calls when exceptions are pending. For more information, see @@ -921,7 +956,10 @@ QByteArray QJniObject::className() const jint size = myJavaString.callMethod<jint>("length"); \endcode - The method signature is deduced at compile time from \c Ret and the types of \a args. + The method signature is deduced at compile time from \c Ret and the types + of \a args. \c Ret can be a \c{std::expected}-compatible type that returns + a value, or \l{Handling Java Exceptions}{any Java exception thrown} by the + called method. */ /*! @@ -952,7 +990,10 @@ QByteArray QJniObject::className() const jint value = QJniObject::callStaticMethod<jint>("MyClass", "staticMethod"); \endcode - The method signature is deduced at compile time from \c Ret and the types of \a args. + The method signature is deduced at compile time from \c Ret and the types + of \a args. \c Ret can be a \c{std::expected}-compatible type that returns + a value, or \l{Handling Java Exceptions}{any Java exception thrown} by the + called method. */ /*! @@ -1009,7 +1050,10 @@ QByteArray QJniObject::className() const jdouble randNr = QJniObject::callStaticMethod<jdouble>(javaMathClass, "random"); \endcode - The method signature is deduced at compile time from \c Ret and the types of \a args. + The method signature is deduced at compile time from \c Ret and the types + of \a args. \c Ret can be a \c{std::expected}-compatible type that returns + a value, or \l{Handling Java Exceptions}{any Java exception thrown} by the + called method. */ /*! @@ -1020,8 +1064,12 @@ QByteArray QJniObject::className() const \c Ret (unless \c Ret is \c void). If \c Ret is a jobject type, then the returned value will be a QJniObject. - The method signature is deduced at compile time from \c Ret and the types of \a args. - \c Klass needs to be a C++ type with a registered type mapping to a Java type. + The method signature is deduced at compile time from \c Ret and the types + of \a args. \c Klass needs to be a C++ type with a registered type mapping + to a Java type. \c Ret can be a \c{std::expected}-compatible type that + returns a value, or \l{Handling Java Exceptions}{any Java exception thrown} + by the called method. + */ /*! @@ -1150,7 +1198,10 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, QJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString"); \endcode - The method signature is deduced at compile time from \c Ret and the types of \a args. + The method signature is deduced at compile time from \c Ret and the types + of \a args. \c Ret can be a \c{std::expected}-compatible type that returns + a value, or \l{Handling Java Exceptions}{any Java exception thrown} by the + called method. */ /*! @@ -1164,7 +1215,10 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, QJniObject string = QJniObject::callStaticObjectMethod<jstring>("CustomClass", "getClassName"); \endcode - The method signature is deduced at compile time from \c Ret and the types of \a args. + The method signature is deduced at compile time from \c Ret and the types + of \a args. \c Ret can be a \c{std::expected}-compatible type that returns + a value, or \l{Handling Java Exceptions}{any Java exception thrown} by the + called method. */ /*! diff --git a/src/corelib/kernel/qmetaassociation.h b/src/corelib/kernel/qmetaassociation.h index 6d8de13e90a..d481ae91079 100644 --- a/src/corelib/kernel/qmetaassociation.h +++ b/src/corelib/kernel/qmetaassociation.h @@ -25,8 +25,8 @@ public: using reference = QVariant::Reference<AssociativeIterator>; using pointer = QVariant::Pointer<AssociativeIterator>; - static constexpr bool canNoexceptAssignQVariant = false; - static constexpr bool canNoexceptConvertToQVariant = false; + static constexpr bool CanNoexceptAssignQVariant = false; + static constexpr bool CanNoexceptConvertToQVariant = false; AssociativeIterator(QIterator &&it) : QIterator(std::move(it)) {} @@ -51,7 +51,7 @@ public: using reference = QVariant::ConstReference<AssociativeConstIterator>; using pointer = QVariant::ConstPointer<AssociativeConstIterator>; - static constexpr bool canNoexceptConvertToQVariant = false; + static constexpr bool CanNoexceptConvertToQVariant = false; AssociativeConstIterator(QConstIterator &&it) : QConstIterator(std::move(it)) {} diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 24cc58829c8..c7e50788b45 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -469,6 +469,33 @@ QMetaType QMetaObject::metaType() const } } +static inline QByteArrayView objectMetaObjectHash(const QMetaObject *m) +{ + // metaObjectHash didn't exist before revision 14 + if (QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && priv(m->d.data)->revision < 14) + return {}; + const auto index = priv(m->d.data)->metaObjectHashIndex; + if (index == -1) + return {}; + return stringDataView(m, index); +} + +/*! + \since 6.11 + + Returns the revisioned hash of the contents of this QMetaObject or nullptr. + + The hash has the following format <hash_revision>$<hash_b64>, where + hash_revision is an integer and hash_b64 is the base64 encoding of the + hash. + + Note that only hashes of the same revision should be compared. +*/ +const char *QMetaObject::metaObjectHash() const +{ + return objectMetaObjectHash(this).constData(); +} + /*! Returns the method offset for this class; i.e. the index position of this class's first member function. diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index bfda30fda28..7264d2a956f 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -124,6 +124,7 @@ struct QMetaObjectPrivate int constructorCount, constructorData; int flags; int signalCount; + int metaObjectHashIndex; static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject) { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); } diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index 6065bf2baea..9af6de73680 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -558,6 +558,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty &protot property.setEnumOrFlag(prototype.isEnumType()); property.setConstant(prototype.isConstant()); property.setFinal(prototype.isFinal()); + property.setVirtual(prototype.isVirtual()); + property.setOverride(prototype.isOverride()); property.setRevision(prototype.revision()); if (prototype.hasNotifySignal()) { // Find an existing method for the notify signal, or add a new one. @@ -1177,10 +1179,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, int methodParametersDataSize = aggregateParameterCount(d->methods) + aggregateParameterCount(d->constructors); if constexpr (mode == Construct) { - static_assert(QMetaObjectPrivate::OutputRevision == 13, "QMetaObjectBuilder should generate the same version as moc"); + static_assert(QMetaObjectPrivate::OutputRevision == 14, "QMetaObjectBuilder should generate the same version as moc"); pmeta->revision = QMetaObjectPrivate::OutputRevision; pmeta->flags = d->flags.toInt() | AllocatedMetaObject; pmeta->className = 0; // Class name is always the first string. + pmeta->metaObjectHashIndex = -1; // TODO support hash in the builder too //pmeta->signalCount is handled in the "output method loop" as an optimization. pmeta->classInfoCount = d->classInfoNames.size(); @@ -2068,6 +2071,32 @@ bool QMetaPropertyBuilder::isFinal() const } /*! + Returns \c true if the property is virtual; otherwise returns \c false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isVirtual() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Virtual); + else + return false; +} + +/*! + Returns \c true if the property does override; otherwise returns \c false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isOverride() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Override); + else + return false; +} + +/*! * Returns \c true if the property is an alias. * The default value is false */ @@ -2239,6 +2268,30 @@ void QMetaPropertyBuilder::setFinal(bool value) } /*! + Sets the \c VIRTUAL flag on this property to \a value. + + \sa isFinal() +*/ +void QMetaPropertyBuilder::setVirtual(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Virtual, value); +} + +/*! + Sets the \c OVERRIDE flag on this property to \a value. + + \sa isOverride() +*/ +void QMetaPropertyBuilder::setOverride(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Override, value); +} + +/*! Sets the \c ALIAS flag on this property to \a value */ void QMetaPropertyBuilder::setAlias(bool value) diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index 563704d60e6..9591944602a 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -214,6 +214,8 @@ public: bool isEnumOrFlag() const; bool isConstant() const; bool isFinal() const; + bool isVirtual() const; + bool isOverride() const; bool isAlias() const; bool isBindable() const; bool isRequired() const; @@ -229,6 +231,8 @@ public: void setEnumOrFlag(bool value); void setConstant(bool value); void setFinal(bool value); + void setVirtual(bool value); + void setOverride(bool value); void setAlias(bool value); void setBindable(bool value); void setRequired(bool value); diff --git a/src/corelib/kernel/qmetasequence.h b/src/corelib/kernel/qmetasequence.h index e9505054159..26156e7924f 100644 --- a/src/corelib/kernel/qmetasequence.h +++ b/src/corelib/kernel/qmetasequence.h @@ -24,8 +24,8 @@ public: using reference = QVariant::Reference<SequentialIterator>; using pointer = QVariant::Pointer<SequentialIterator>; - static constexpr bool canNoexceptAssignQVariant = false; - static constexpr bool canNoexceptConvertToQVariant = false; + static constexpr bool CanNoexceptAssignQVariant = false; + static constexpr bool CanNoexceptConvertToQVariant = false; SequentialIterator(QIterator &&it) : QIterator(std::move(it)) {} @@ -41,7 +41,7 @@ public: using reference = QVariant::ConstReference<SequentialConstIterator>; using pointer = QVariant::ConstPointer<SequentialConstIterator>; - static constexpr bool canNoexceptConvertToQVariant = false; + static constexpr bool CanNoexceptConvertToQVariant = false; SequentialConstIterator(QConstIterator &&it) : QConstIterator(std::move(it)) {} @@ -184,13 +184,15 @@ public: return; } - // ### Qt7: Drop this code. We shouldn't second-guess the underlying container +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + // We shouldn't second-guess the underlying container. QtPrivate::warnSynthesizedAccess( "at() called on an iterable without native indexed accessors. This is slow"); void *it = meta.constBegin(m_iterable.constPointer()); meta.advanceConstIterator(it, idx); meta.valueAtConstIterator(it, dataPtr); meta.destroyConstIterator(it); +#endif }); } @@ -204,13 +206,15 @@ public: return; } - // ### Qt7: Drop this code. We shouldn't second-guess the underlying container +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) + // We shouldn't second-guess the underlying container QtPrivate::warnSynthesizedAccess( "set() called on an iterable without native indexed accessors. This is slow"); void *it = meta.begin(m_iterable.mutablePointer()); meta.advanceIterator(it, idx); meta.setValueAtIterator(it, dataPtr); meta.destroyIterator(it); +#endif } void append(const QVariant &value) @@ -248,55 +252,14 @@ public: Unspecified, AtBegin, AtEnd }; - QT_DEPRECATED_VERSION_X_6_11("Use append() or prepend() instead.") void addValue(const QVariant &value, Position position = Unspecified) - { - const QMetaSequence meta = metaContainer(); - QtPrivate::QVariantTypeCoercer coercer; - const void *valuePtr = coercer.coerce(value, meta.valueMetaType()); - - switch (position) { - case AtBegin: - if (meta.canAddValueAtBegin()) - meta.addValueAtBegin(mutableIterable(), valuePtr); - break; - case AtEnd: - if (meta.canAddValueAtEnd()) - meta.addValueAtEnd(mutableIterable(), valuePtr); - break; - case Unspecified: - if (meta.canAddValue()) - meta.addValue(mutableIterable(), valuePtr); - break; - } - } + Q_DECL_EQ_DELETE_X("Use append() or prepend() instead."); - QT_DEPRECATED_VERSION_X_6_11("Use removeLast() or removeFirst() instead.") void removeValue(Position position = Unspecified) - { - const QMetaSequence meta = metaContainer(); + Q_DECL_EQ_DELETE_X("Use removeLast() or removeFirst() instead."); - switch (position) { - case AtBegin: - if (meta.canRemoveValueAtBegin()) - meta.removeValueAtBegin(mutableIterable()); - break; - case AtEnd: - if (meta.canRemoveValueAtEnd()) - meta.removeValueAtEnd(mutableIterable()); - break; - case Unspecified: - if (meta.canRemoveValue()) - meta.removeValue(mutableIterable()); - break; - } - } - - QT_DEPRECATED_VERSION_X_6_11("Use QMetaSequence::valueMetaType() instead.") QMetaType valueMetaType() const - { - return metaContainer().valueMetaType(); - } + Q_DECL_EQ_DELETE_X("Use QMetaSequence::valueMetaType() instead."); QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 11) diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 848102cc57a..d3e761982f5 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -247,6 +247,8 @@ struct Q_CORE_EXPORT QMetaObject QMetaType metaType() const; + const char *metaObjectHash() const; + int methodOffset() const; int enumeratorOffset() const; int propertyOffset() const; diff --git a/src/corelib/kernel/qtmocconstants.h b/src/corelib/kernel/qtmocconstants.h index 260ac2fa5f8..822e02e6c8e 100644 --- a/src/corelib/kernel/qtmocconstants.h +++ b/src/corelib/kernel/qtmocconstants.h @@ -30,7 +30,8 @@ namespace QtMocConstants { // revision 11 is Qt 6.5: The metatype for void is stored in the metatypes array // revision 12 is Qt 6.6: It adds the metatype for enums // revision 13 is Qt 6.9: Adds support for 64-bit QFlags and moves the method revision -enum { OutputRevision = 13 }; // Used by moc, qmetaobjectbuilder and qdbus +// revision 14 is Qt 6.11: Adds a hash of meta object contents +enum { OutputRevision = 14 }; // Used by moc, qmetaobjectbuilder and qdbus enum PropertyFlags : uint { Invalid = 0x00000000, diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h index 4c549e78ad5..3d2b59d2a73 100644 --- a/src/corelib/kernel/qtmochelpers.h +++ b/src/corelib/kernel/qtmochelpers.h @@ -511,7 +511,8 @@ template <typename ObjectType, typename Unique, typename Strings, typename Constructors = UintData<>, typename ClassInfo = detail::UintDataBlock<0, 0>> constexpr auto metaObjectData(uint flags, const Strings &strings, const Methods &methods, const Properties &properties, - const Enums &enums, const Constructors &constructors = {}, + const Enums &enums, int qt_metaObjectHashIndex = -1, + const Constructors &constructors = {}, const ClassInfo &classInfo = {}) { constexpr uint MetaTypeCount = Properties::metaTypeCount() @@ -520,7 +521,7 @@ constexpr auto metaObjectData(uint flags, const Strings &strings, + Methods::metaTypeCount() + Constructors::metaTypeCount(); - constexpr uint HeaderSize = 14; + constexpr uint HeaderSize = 15; constexpr uint TotalSize = HeaderSize + Properties::dataSize() + Enums::dataSize() @@ -582,6 +583,8 @@ constexpr auto metaObjectData(uint flags, const Strings &strings, } } + data[14] = qt_metaObjectHashIndex; + return result; } diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 82eec0693d6..19cd1fea7fb 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -263,7 +263,7 @@ public: ConstReference &operator=(ConstReference &&value) = delete; // To be specialized for each Referred - operator QVariant() const noexcept(Referred::canNoexceptConvertToQVariant); + operator QVariant() const noexcept(Referred::CanNoexceptConvertToQVariant); }; template<typename Referred> @@ -288,18 +288,18 @@ public: ~Reference() = default; Reference &operator=(const Reference &value) - noexcept(Referred::canNoexceptAssignQVariant) + noexcept(Referred::CanNoexceptAssignQVariant) { return operator=(QVariant(value)); } Reference &operator=(Reference &&value) - noexcept(Referred::canNoexceptAssignQVariant) + noexcept(Referred::CanNoexceptAssignQVariant) { return operator=(QVariant(value)); } - operator QVariant() const noexcept(Referred::canNoexceptConvertToQVariant) + operator QVariant() const noexcept(Referred::CanNoexceptConvertToQVariant) { return ConstReference(m_referred); } @@ -313,7 +313,7 @@ public: } // To be specialized for each Referred - Reference &operator=(const QVariant &value) noexcept(Referred::canNoexceptAssignQVariant); + Reference &operator=(const QVariant &value) noexcept(Referred::CanNoexceptAssignQVariant); }; template<typename Pointed> diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 9c26de94b6d..ecd1ac77779 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -517,13 +517,15 @@ QMimeBinaryProvider::loadMimeTypeExtra(const QString &mimeName) // load comment and globPatterns // shared-mime-info since 1.3 lowercases the xml files - QString mimeFile = m_directory + u'/' + mimeName.toLower() + ".xml"_L1; - if (!QFile::exists(mimeFile)) - mimeFile = m_directory + u'/' + mimeName + ".xml"_L1; // pre-1.3 - - QFile qfile(mimeFile); - if (!qfile.open(QFile::ReadOnly)) - return it; + QFile qfile; + const QString mimeFile = m_directory + u'/' + mimeName.toLower() + ".xml"_L1; + qfile.setFileName(mimeFile); + if (!qfile.open(QFile::ReadOnly)) { + const QString fallbackMimeFile = m_directory + u'/' + mimeName + ".xml"_L1; // pre-1.3 + qfile.setFileName(fallbackMimeFile); + if (!qfile.open(QFile::ReadOnly)) + return it; + } MimeTypeExtra &extra = it->second; QString mainPattern; diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 1c0371e463e..d173d824e88 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -162,7 +162,7 @@ allocateHelper(QArrayData **dptr, qsizetype objectSize, qsizetype alignment, qsi QArrayData::AllocationOption option) noexcept { *dptr = nullptr; - if (capacity == 0) + if (capacity <= 0) return {}; const qsizetype headerSize = calculateHeaderSize(alignment); diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index 1c5b02ed1f0..680bf2812d3 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.h @@ -254,15 +254,11 @@ public: inline QSizeF &operator/=(qreal c); private: - QT_WARNING_PUSH - QT_WARNING_DISABLE_FLOAT_COMPARE friend constexpr bool qFuzzyCompare(const QSizeF &s1, const QSizeF &s2) noexcept { - // if one of the arguments is 0.0. return QtPrivate::fuzzyCompare(s1.wd, s2.wd) && QtPrivate::fuzzyCompare(s1.ht, s2.ht); } - QT_WARNING_POP friend constexpr bool qFuzzyIsNull(const QSizeF &size) noexcept { return qFuzzyIsNull(size.wd) && qFuzzyIsNull(size.ht); } friend constexpr bool comparesEqual(const QSizeF &lhs, const QSizeF &rhs) noexcept diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp index 149392f9c3c..a4ffd7a64dd 100644 --- a/src/dbus/qdbusmetaobject.cpp +++ b/src/dbus/qdbusmetaobject.cpp @@ -383,9 +383,10 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj) - methods.size(); // ditto QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data()); - static_assert(QMetaObjectPrivate::OutputRevision == 13, "QtDBus meta-object generator should generate the same version as moc"); + static_assert(QMetaObjectPrivate::OutputRevision == 14, "QtDBus meta-object generator should generate the same version as moc"); header->revision = QMetaObjectPrivate::OutputRevision; header->className = 0; + header->metaObjectHashIndex = -1; // TODO support hash in dbus metaobject too header->classInfoCount = 0; header->classInfoData = 0; header->methodCount = int(signals_.size() + methods.size()); diff --git a/src/gui/accessible/qaccessible_base.h b/src/gui/accessible/qaccessible_base.h index 3881c6346a0..04efeddf06f 100644 --- a/src/gui/accessible/qaccessible_base.h +++ b/src/gui/accessible/qaccessible_base.h @@ -175,11 +175,15 @@ public: // quint64 alertMedium : 1; // quint64 alertHigh : 1; + Q_DECL_UNUSED_MEMBER quint64 qt_reserved : 27; + State() { std::memset(this, 0, sizeof(State)); } friend inline bool operator==(const QAccessible::State &first, const QAccessible::State &second) { + static_assert(std::has_unique_object_representations_v<State>, + "memcmp() cannot be used on types with padding"); return std::memcmp(&first, &second, sizeof(QAccessible::State)) == 0; } }; diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index cb4702b5f7e..633ae7895ba 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -228,8 +228,8 @@ public: // to use single-point precision. friend constexpr bool operator==(const QLastCursorPosition &p1, const QPointF &p2) noexcept { - return qFuzzyCompare(float(p1.x()), float(p2.x())) - && qFuzzyCompare(float(p1.y()), float(p2.y())); + return QtPrivate::fuzzyCompare(float(p1.x()), float(p2.x())) + && QtPrivate::fuzzyCompare(float(p1.y()), float(p2.y())); } friend constexpr bool operator!=(const QLastCursorPosition &p1, const QPointF &p2) noexcept { diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp index e2bafa73988..f361ec86c2d 100644 --- a/src/gui/kernel/qsurface.cpp +++ b/src/gui/kernel/qsurface.cpp @@ -68,7 +68,10 @@ QT_IMPL_METATYPE_EXTERN_TAGGED(QSurface*, QSurface_ptr) bool QSurface::supportsOpenGL() const { - return surfaceType() == OpenGLSurface; + static bool openGLOnRasterSurfaceSupported = + QGuiApplicationPrivate::instance()->platformIntegration()->hasCapability(QPlatformIntegration::OpenGLOnRasterSurface); + return surfaceType() == OpenGLSurface + || (surfaceType() == RasterSurface && openGLOnRasterSurfaceSupported); } /*! diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index f6a06fd47ca..ec6e696ba00 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -294,6 +294,7 @@ double QMatrix4x4::determinant() const if ((flagBits & ~(Translation | Rotation2D | Rotation)) == Identity) return 1.0; + Q_DECL_UNINITIALIZED double mm[4][4]; copyToDoubles(m, mm); if (flagBits < Rotation2D) @@ -355,8 +356,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const *invertible = true; return orthonormalInverse(); } else if (flagBits < Perspective) { + Q_DECL_UNINITIALIZED QMatrix4x4 inv(Qt::Uninitialized); + Q_DECL_UNINITIALIZED double mm[4][4]; copyToDoubles(m, mm); @@ -391,8 +394,10 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const return inv; } + Q_DECL_UNINITIALIZED QMatrix4x4 inv(Qt::Uninitialized); + Q_DECL_UNINITIALIZED double mm[4][4]; copyToDoubles(m, mm); @@ -465,6 +470,7 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const return inv; } + Q_DECL_UNINITIALIZED double mm[4][4]; copyToDoubles(m, mm); double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2); @@ -493,6 +499,7 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const */ QMatrix4x4 QMatrix4x4::transposed() const { + Q_DECL_UNINITIALIZED QMatrix4x4 result(Qt::Uninitialized); for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { @@ -709,6 +716,7 @@ QMatrix4x4& QMatrix4x4::operator/=(float divisor) */ QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor) { + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = matrix.m[0][0] / divisor; m.m[0][1] = matrix.m[0][1] / divisor; @@ -738,22 +746,22 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, float divisor) */ bool qFuzzyCompare(const QMatrix4x4& m1, const QMatrix4x4& m2) noexcept { - return qFuzzyCompare(m1.m[0][0], m2.m[0][0]) && - qFuzzyCompare(m1.m[0][1], m2.m[0][1]) && - qFuzzyCompare(m1.m[0][2], m2.m[0][2]) && - qFuzzyCompare(m1.m[0][3], m2.m[0][3]) && - qFuzzyCompare(m1.m[1][0], m2.m[1][0]) && - qFuzzyCompare(m1.m[1][1], m2.m[1][1]) && - qFuzzyCompare(m1.m[1][2], m2.m[1][2]) && - qFuzzyCompare(m1.m[1][3], m2.m[1][3]) && - qFuzzyCompare(m1.m[2][0], m2.m[2][0]) && - qFuzzyCompare(m1.m[2][1], m2.m[2][1]) && - qFuzzyCompare(m1.m[2][2], m2.m[2][2]) && - qFuzzyCompare(m1.m[2][3], m2.m[2][3]) && - qFuzzyCompare(m1.m[3][0], m2.m[3][0]) && - qFuzzyCompare(m1.m[3][1], m2.m[3][1]) && - qFuzzyCompare(m1.m[3][2], m2.m[3][2]) && - qFuzzyCompare(m1.m[3][3], m2.m[3][3]); + return QtPrivate::fuzzyCompare(m1.m[0][0], m2.m[0][0]) + && QtPrivate::fuzzyCompare(m1.m[0][1], m2.m[0][1]) + && QtPrivate::fuzzyCompare(m1.m[0][2], m2.m[0][2]) + && QtPrivate::fuzzyCompare(m1.m[0][3], m2.m[0][3]) + && QtPrivate::fuzzyCompare(m1.m[1][0], m2.m[1][0]) + && QtPrivate::fuzzyCompare(m1.m[1][1], m2.m[1][1]) + && QtPrivate::fuzzyCompare(m1.m[1][2], m2.m[1][2]) + && QtPrivate::fuzzyCompare(m1.m[1][3], m2.m[1][3]) + && QtPrivate::fuzzyCompare(m1.m[2][0], m2.m[2][0]) + && QtPrivate::fuzzyCompare(m1.m[2][1], m2.m[2][1]) + && QtPrivate::fuzzyCompare(m1.m[2][2], m2.m[2][2]) + && QtPrivate::fuzzyCompare(m1.m[2][3], m2.m[2][3]) + && QtPrivate::fuzzyCompare(m1.m[3][0], m2.m[3][0]) + && QtPrivate::fuzzyCompare(m1.m[3][1], m2.m[3][1]) + && QtPrivate::fuzzyCompare(m1.m[3][2], m2.m[3][2]) + && QtPrivate::fuzzyCompare(m1.m[3][3], m2.m[3][3]); } @@ -1141,6 +1149,7 @@ void QMatrix4x4::rotate(float angle, float x, float y, float z) z = float(double(z) / len); } float ic = 1.0f - c; + Q_DECL_UNINITIALIZED QMatrix4x4 rot(Qt::Uninitialized); rot.m[0][0] = x * x * ic + c; rot.m[1][0] = x * y * ic - z * s; @@ -1244,6 +1253,7 @@ void QMatrix4x4::projectedRotate(float angle, float x, float y, float z, float d z = float(double(z) / len); } const float ic = 1.0f - c; + Q_DECL_UNINITIALIZED QMatrix4x4 rot(Qt::Uninitialized); rot.m[0][0] = x * x * ic + c; rot.m[1][0] = x * y * ic - z * s; @@ -1306,6 +1316,7 @@ void QMatrix4x4::rotate(const QQuaternion& quaternion) // Algorithm from: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54 + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); const float f2x = quaternion.x() + quaternion.x(); @@ -1393,6 +1404,7 @@ void QMatrix4x4::ortho(float left, float right, float bottom, float top, float n const float width = right - left; const float invheight = top - bottom; const float clip = farPlane - nearPlane; + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = 2.0f / width; m.m[1][0] = 0.0f; @@ -1431,6 +1443,7 @@ void QMatrix4x4::frustum(float left, float right, float bottom, float top, float return; // Construct the projection. + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); const float width = right - left; const float invheight = top - bottom; @@ -1474,6 +1487,7 @@ void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearP return; // Construct the projection. + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); const float radians = qDegreesToRadians(verticalAngle / 2.0f); const float sine = std::sin(radians); @@ -1524,6 +1538,7 @@ void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVe QVector3D side = QVector3D::crossProduct(forward, up).normalized(); QVector3D upVector = QVector3D::crossProduct(side, forward); + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = side.x(); m.m[1][0] = side.y(); @@ -1573,6 +1588,7 @@ void QMatrix4x4::viewport(float left, float bottom, float width, float height, f const float w2 = width / 2.0f; const float h2 = height / 2.0f; + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = w2; m.m[1][0] = 0.0f; @@ -1871,6 +1887,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const // of just rotations and translations. QMatrix4x4 QMatrix4x4::orthonormalInverse() const { + Q_DECL_UNINITIALIZED QMatrix4x4 result(Qt::Uninitialized); result.m[0][0] = m[0][0]; @@ -1943,6 +1960,7 @@ void QMatrix4x4::optimize() flagBits &= ~Scale; } else { // If the columns are orthonormal and form a right-handed system, then there is no scale. + Q_DECL_UNINITIALIZED double mm[4][4]; copyToDoubles(m, mm); double det = matrixDet2(mm, 0, 1, 0, 1); @@ -1957,6 +1975,7 @@ void QMatrix4x4::optimize() } } else { // If the columns are orthonormal and form a right-handed system, then there is no scale. + Q_DECL_UNINITIALIZED double mm[4][4]; copyToDoubles(m, mm); double det = matrixDet3(mm, 0, 1, 2, 0, 1, 2); diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 2ba274d4517..2a801905ce0 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -564,6 +564,7 @@ inline bool QMatrix4x4::operator!=(const QMatrix4x4& other) const inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2) { + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = m1.m[0][0] + m2.m[0][0]; m.m[0][1] = m1.m[0][1] + m2.m[0][1]; @@ -586,6 +587,7 @@ inline QMatrix4x4 operator+(const QMatrix4x4& m1, const QMatrix4x4& m2) inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2) { + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = m1.m[0][0] - m2.m[0][0]; m.m[0][1] = m1.m[0][1] - m2.m[0][1]; @@ -608,21 +610,34 @@ inline QMatrix4x4 operator-(const QMatrix4x4& m1, const QMatrix4x4& m2) inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2) { + Q_DECL_UNINITIALIZED + QMatrix4x4 m(Qt::Uninitialized); QMatrix4x4::Flags flagBits = m1.flagBits | m2.flagBits; if (flagBits.toInt() < QMatrix4x4::Rotation2D) { - QMatrix4x4 m = m1; - m.m[3][0] += m.m[0][0] * m2.m[3][0]; - m.m[3][1] += m.m[1][1] * m2.m[3][1]; - m.m[3][2] += m.m[2][2] * m2.m[3][2]; - - m.m[0][0] *= m2.m[0][0]; - m.m[1][1] *= m2.m[1][1]; - m.m[2][2] *= m2.m[2][2]; + // Scale | Translation + m.m[0][0] = m1.m[0][0] * m2.m[0][0]; + m.m[0][1] = 0.0f; + m.m[0][2] = 0.0f; + m.m[0][3] = 0.0f; + + m.m[1][0] = 0.0f; + m.m[1][1] = m1.m[1][1] * m2.m[1][1]; + m.m[1][2] = 0.0f; + m.m[1][3] = 0.0f; + + m.m[2][0] = 0.0f; + m.m[2][1] = 0.0f; + m.m[2][2] = m1.m[2][2] * m2.m[2][2]; + m.m[2][3] = 0.0f; + + m.m[3][0] = m1.m[3][0] + m1.m[0][0] * m2.m[3][0]; + m.m[3][1] = m1.m[3][1] + m1.m[1][1] * m2.m[3][1]; + m.m[3][2] = m1.m[3][2] + m1.m[2][2] * m2.m[3][2]; + m.m[3][3] = 1.0f; m.flagBits = flagBits; return m; } - QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = m1.m[0][0] * m2.m[0][0] + m1.m[1][0] * m2.m[0][1] + m1.m[2][0] * m2.m[0][2] @@ -843,6 +858,7 @@ inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point) inline QMatrix4x4 operator-(const QMatrix4x4& matrix) { + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = -matrix.m[0][0]; m.m[0][1] = -matrix.m[0][1]; @@ -865,6 +881,7 @@ inline QMatrix4x4 operator-(const QMatrix4x4& matrix) inline QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix) { + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = matrix.m[0][0] * factor; m.m[0][1] = matrix.m[0][1] * factor; @@ -887,6 +904,7 @@ inline QMatrix4x4 operator*(float factor, const QMatrix4x4& matrix) inline QMatrix4x4 operator*(const QMatrix4x4& matrix, float factor) { + Q_DECL_UNINITIALIZED QMatrix4x4 m(Qt::Uninitialized); m.m[0][0] = matrix.m[0][0] * factor; m.m[0][1] = matrix.m[0][1] * factor; diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index a7b1d432df7..c92e7177199 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -305,10 +305,10 @@ constexpr QQuaternion operator/(const QQuaternion &quaternion, float divisor) constexpr bool qFuzzyCompare(const QQuaternion &q1, const QQuaternion &q2) noexcept { - return qFuzzyCompare(q1.wp, q2.wp) && - qFuzzyCompare(q1.xp, q2.xp) && - qFuzzyCompare(q1.yp, q2.yp) && - qFuzzyCompare(q1.zp, q2.zp); + return QtPrivate::fuzzyCompare(q1.wp, q2.wp) + && QtPrivate::fuzzyCompare(q1.xp, q2.xp) + && QtPrivate::fuzzyCompare(q1.yp, q2.yp) + && QtPrivate::fuzzyCompare(q1.zp, q2.zp); } #if QT_GUI_INLINE_IMPL_SINCE(6, 11) diff --git a/src/gui/math3d/qvectornd.cpp b/src/gui/math3d/qvectornd.cpp index ec836cfa56e..ee070b2b5be 100644 --- a/src/gui/math3d/qvectornd.cpp +++ b/src/gui/math3d/qvectornd.cpp @@ -375,7 +375,8 @@ QT_BEGIN_NAMESPACE */ bool qFuzzyCompare(QVector2D v1, QVector2D v2) noexcept { - return qFuzzyCompare(v1.v[0], v2.v[0]) && qFuzzyCompare(v1.v[1], v2.v[1]); + return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0]) + && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1]); } #ifndef QT_NO_VECTOR3D @@ -979,9 +980,9 @@ QVector3D QVector3D::unproject(const QMatrix4x4 &modelView, const QMatrix4x4 &pr */ bool qFuzzyCompare(QVector3D v1, QVector3D v2) noexcept { - return qFuzzyCompare(v1.v[0], v2.v[0]) && - qFuzzyCompare(v1.v[1], v2.v[1]) && - qFuzzyCompare(v1.v[2], v2.v[2]); + return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0]) + && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1]) + && QtPrivate::fuzzyCompare(v1.v[2], v2.v[2]); } #ifndef QT_NO_VECTOR2D @@ -1501,10 +1502,10 @@ QDataStream &operator>>(QDataStream &stream, QVector3D &vector) */ bool qFuzzyCompare(QVector4D v1, QVector4D v2) noexcept { - return qFuzzyCompare(v1.v[0], v2.v[0]) && - qFuzzyCompare(v1.v[1], v2.v[1]) && - qFuzzyCompare(v1.v[2], v2.v[2]) && - qFuzzyCompare(v1.v[3], v2.v[3]); + return QtPrivate::fuzzyCompare(v1.v[0], v2.v[0]) + && QtPrivate::fuzzyCompare(v1.v[1], v2.v[1]) + && QtPrivate::fuzzyCompare(v1.v[2], v2.v[2]) + && QtPrivate::fuzzyCompare(v1.v[3], v2.v[3]); } #ifndef QT_NO_VECTOR2D diff --git a/src/gui/opengl/platform/egl/qeglplatformcontext.cpp b/src/gui/opengl/platform/egl/qeglplatformcontext.cpp index e56504833d1..350968b87d4 100644 --- a/src/gui/opengl/platform/egl/qeglplatformcontext.cpp +++ b/src/gui/opengl/platform/egl/qeglplatformcontext.cpp @@ -104,6 +104,14 @@ QT_BEGIN_NAMESPACE #define GL_LOSE_CONTEXT_ON_RESET 0x8252 #endif +// Constants from GL_EXT_robustness. +#ifndef GL_RESET_NOTIFICATION_STRATEGY_EXT +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#endif +#ifndef GL_LOSE_CONTEXT_ON_RESET_EXT +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#endif + // Constants from EGL_NV_robustness_video_memory_purge #ifndef EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV #define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C @@ -452,11 +460,16 @@ void QEGLPlatformContext::updateFormatFromGL() } } } - if (hasExtension("GL_ARB_robustness")) { + if (m_format.renderableType() == QSurfaceFormat::OpenGL && hasExtension("GL_ARB_robustness")) { GLint value = 0; glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &value); if (value == GL_LOSE_CONTEXT_ON_RESET) m_format.setOption(QSurfaceFormat::ResetNotification); + } else if (m_format.renderableType() == QSurfaceFormat::OpenGLES && hasExtension("GL_EXT_robustness")) { + GLint value = 0; + glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_EXT, &value); + if (value == GL_LOSE_CONTEXT_ON_RESET_EXT) + m_format.setOption(QSurfaceFormat::ResetNotification); } } runGLChecks(); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 04433c7703a..697ede42d92 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -930,7 +930,7 @@ static inline bool canUseFastMatrixPath(const qreal cx, const qreal cy, const qs minc = std::min(minc, std::min(fx, fy)); maxc = std::max(maxc, std::max(fx, fy)); - return minc >= std::numeric_limits<int>::min() && maxc <= std::numeric_limits<int>::max(); + return minc >= std::numeric_limits<int>::min() && maxc <= qreal(std::numeric_limits<int>::max()); } template<TextureBlendType blendType, QPixelLayout::BPP bpp, typename T> @@ -5179,7 +5179,7 @@ static inline bool calculate_fixed_gradient_factors(int count, const QT_FT_Span const int gss = GRADIENT_STOPTABLE_SIZE - 1; qreal ryinc = linear.dy * data->m22 * gss * FIXPT_SIZE; qreal roff = (linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss * FIXPT_SIZE; - const int limit = std::numeric_limits<int>::max() - FIXPT_SIZE; + const qreal limit = qreal(std::numeric_limits<int>::max() - FIXPT_SIZE); if (count && (std::fabs(ryinc) < limit) && (std::fabs(roff) < limit) && (std::fabs(ryinc * spans->y + roff) < limit) && (std::fabs(ryinc * (spans + count - 1)->y + roff) < limit)) { diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp index e6f346dcdf2..17fb6491b75 100644 --- a/src/gui/painting/qpagelayout.cpp +++ b/src/gui/painting/qpagelayout.cpp @@ -606,7 +606,7 @@ bool QPageLayout::setLeftMargin(qreal leftMargin, OutOfBoundsPolicy outOfBoundsP if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp) leftMargin = qBound(d->m_minMargins.left(), leftMargin, d->m_maxMargins.left()); - if (qFuzzyCompare(leftMargin, d->m_margins.left())) + if (QtPrivate::fuzzyCompare(leftMargin, d->m_margins.left())) return true; if (d->m_mode == FullPageMode @@ -637,7 +637,7 @@ bool QPageLayout::setRightMargin(qreal rightMargin, OutOfBoundsPolicy outOfBound if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp) rightMargin = qBound(d->m_minMargins.right(), rightMargin, d->m_maxMargins.right()); - if (qFuzzyCompare(rightMargin, d->m_margins.right())) + if (QtPrivate::fuzzyCompare(rightMargin, d->m_margins.right())) return true; if (d->m_mode == FullPageMode @@ -668,7 +668,7 @@ bool QPageLayout::setTopMargin(qreal topMargin, OutOfBoundsPolicy outOfBoundsPol if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp) topMargin = qBound(d->m_minMargins.top(), topMargin, d->m_maxMargins.top()); - if (qFuzzyCompare(topMargin, d->m_margins.top())) + if (QtPrivate::fuzzyCompare(topMargin, d->m_margins.top())) return true; if (d->m_mode == FullPageMode @@ -699,7 +699,7 @@ bool QPageLayout::setBottomMargin(qreal bottomMargin, OutOfBoundsPolicy outOfBou if (d->m_mode == StandardMode && outOfBoundsPolicy == OutOfBoundsPolicy::Clamp) bottomMargin = qBound(d->m_minMargins.bottom(), bottomMargin, d->m_maxMargins.bottom()); - if (qFuzzyCompare(bottomMargin, d->m_margins.bottom())) + if (QtPrivate::fuzzyCompare(bottomMargin, d->m_margins.bottom())) return true; if (d->m_mode == FullPageMode diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 74321705ff5..047be5f1c3d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2952,9 +2952,9 @@ inline bool QRasterPaintEnginePrivate::isUnclipped(const QRectF &rect, int penWidth) const { const QRectF norm = rect.normalized(); - if (norm.left() <= INT_MIN || norm.top() <= INT_MIN - || norm.right() > INT_MAX || norm.bottom() > INT_MAX - || norm.width() > INT_MAX || norm.height() > INT_MAX) + if (norm.left() <= qreal(INT_MIN) || norm.top() <= qreal(INT_MIN) + || norm.right() > qreal(INT_MAX) || norm.bottom() > qreal(INT_MAX) + || norm.width() > qreal(INT_MAX) || norm.height() > qreal(INT_MAX)) return false; return isUnclipped(norm.toAlignedRect(), penWidth); } diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 7fa05f69232..0d4ce909daa 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -26,6 +26,8 @@ #include <Metal/Metal.h> +#include <utility> // for std::pair + QT_BEGIN_NAMESPACE /* @@ -1674,12 +1676,12 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind if (needsBufferSizeBuffer) { QMetalBuffer *bufD = nullptr; - QVarLengthArray<QPair<QMetalShader *, QRhiShaderResourceBinding::StageFlag>, 4> shaders; + QVarLengthArray<std::pair<QMetalShader *, QRhiShaderResourceBinding::StageFlag>, 4> shaders; if (compPsD) { bufD = compPsD->d->bufferSizeBuffer; Q_ASSERT(compPsD->d->cs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)); - shaders.append(qMakePair(&compPsD->d->cs, QRhiShaderResourceBinding::StageFlag::ComputeStage)); + shaders.append({&compPsD->d->cs, QRhiShaderResourceBinding::StageFlag::ComputeStage}); } else { bufD = gfxPsD->d->bufferSizeBuffer; if (gfxPsD->d->tess.enabled) { @@ -1706,24 +1708,24 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind == gfxPsD->d->tess.compVs[2].nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding]); if (gfxPsD->d->tess.compVs[0].nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) - shaders.append(qMakePair(&gfxPsD->d->tess.compVs[0], QRhiShaderResourceBinding::StageFlag::VertexStage)); + shaders.append({&gfxPsD->d->tess.compVs[0], QRhiShaderResourceBinding::StageFlag::VertexStage}); if (gfxPsD->d->tess.compTesc.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) - shaders.append(qMakePair(&gfxPsD->d->tess.compTesc, QRhiShaderResourceBinding::StageFlag::TessellationControlStage)); + shaders.append({&gfxPsD->d->tess.compTesc, QRhiShaderResourceBinding::StageFlag::TessellationControlStage}); if (gfxPsD->d->tess.vertTese.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) - shaders.append(qMakePair(&gfxPsD->d->tess.vertTese, QRhiShaderResourceBinding::StageFlag::TessellationEvaluationStage)); + shaders.append({&gfxPsD->d->tess.vertTese, QRhiShaderResourceBinding::StageFlag::TessellationEvaluationStage}); } else { if (gfxPsD->d->vs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) - shaders.append(qMakePair(&gfxPsD->d->vs, QRhiShaderResourceBinding::StageFlag::VertexStage)); + shaders.append({&gfxPsD->d->vs, QRhiShaderResourceBinding::StageFlag::VertexStage}); } if (gfxPsD->d->fs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) - shaders.append(qMakePair(&gfxPsD->d->fs, QRhiShaderResourceBinding::StageFlag::FragmentStage)); + shaders.append({&gfxPsD->d->fs, QRhiShaderResourceBinding::StageFlag::FragmentStage}); } quint32 offset = 0; - for (const QPair<QMetalShader *, QRhiShaderResourceBinding::StageFlag> &shader : shaders) { + for (const auto &shader : shaders) { const int binding = shader.first->nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding]; @@ -6030,7 +6032,7 @@ bool QMetalGraphicsPipeline::create() for (QMetalShader *shader : shaders) { if (shader->nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) { const int binding = shader->nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding]; - shader->nativeResourceBindingMap[binding] = qMakePair(binding, -1); + shader->nativeResourceBindingMap[binding] = {binding, -1}; int maxNativeBinding = 0; for (const QShaderDescription::StorageBlock &block : shader->desc.storageBlocks()) maxNativeBinding = qMax(maxNativeBinding, shader->nativeResourceBindingMap[block.binding].first); @@ -6148,7 +6150,7 @@ bool QMetalComputePipeline::create() // SPIRV-Cross buffer size buffers if (d->cs.nativeShaderInfo.extraBufferBindings.contains(QShaderPrivate::MslBufferSizeBufferBinding)) { const int binding = d->cs.nativeShaderInfo.extraBufferBindings[QShaderPrivate::MslBufferSizeBufferBinding]; - d->cs.nativeResourceBindingMap[binding] = qMakePair(binding, -1); + d->cs.nativeResourceBindingMap[binding] = {binding, -1}; } if (rhiD->d->shaderCache.count() >= QRhiMetal::MAX_SHADER_CACHE_ENTRIES) { diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 33e35ba6694..202e28263c2 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -682,6 +682,12 @@ bool QRhiVulkan::create(QRhi::Flags flags) if (devExts.contains("VK_KHR_fragment_shading_rate")) addToChain(&physDevFeaturesChainable, &fragmentShadingRateFeatures); #endif +#ifdef VK_EXT_device_fault + VkPhysicalDeviceFaultFeaturesEXT deviceFaultFeatures = {}; + deviceFaultFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT; + if (devExts.contains(VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) + addToChain(&physDevFeaturesChainable, &deviceFaultFeatures); +#endif #endif // Vulkan >=1.2 headers at build time, >=1.2 implementation at run time @@ -825,6 +831,13 @@ bool QRhiVulkan::create(QRhi::Flags flags) requestedDevExts.append(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME); #endif +#ifdef VK_EXT_device_fault + if (devExts.contains(VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) { + requestedDevExts.append(VK_EXT_DEVICE_FAULT_EXTENSION_NAME); + caps.deviceFault = true; + } +#endif + for (const QByteArray &ext : requestedDeviceExtensions) { if (!ext.isEmpty() && !requestedDevExts.contains(ext)) { if (devExts.contains(ext)) { @@ -910,6 +923,7 @@ bool QRhiVulkan::create(QRhi::Flags flags) // Here we have no way to tell if the extensions got enabled or not. // Pretend it's all there and supported. If getProcAddress fails, we'll // handle that gracefully. + caps.deviceFault = true; caps.vertexAttribDivisor = true; caps.renderPass2KHR = true; caps.depthStencilResolveKHR = true; @@ -1126,6 +1140,12 @@ bool QRhiVulkan::create(QRhi::Flags flags) } #endif +#ifdef VK_EXT_device_fault + if (caps.deviceFault) { + vkGetDeviceFaultInfoEXT = reinterpret_cast<PFN_vkGetDeviceFaultInfoEXT>(f->vkGetDeviceProcAddr(dev, "vkGetDeviceFaultInfoEXT")); + } +#endif + deviceLost = false; nativeHandlesStruct.physDev = physDev; @@ -2643,6 +2663,7 @@ QRhi::FrameOpResult QRhiVulkan::beginFrame(QRhiSwapChain *swapChain, QRhi::Begin } else { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkAcquireNextImageKHR()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -2803,6 +2824,7 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram } else if (err != VK_SUBOPTIMAL_KHR) { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkQueuePresentKHR()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -2862,6 +2884,7 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb) if (err != VK_SUCCESS) { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkAllocateCommandBuffers()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -2877,6 +2900,7 @@ QRhi::FrameOpResult QRhiVulkan::startPrimaryCommandBuffer(VkCommandBuffer *cb) if (err != VK_SUCCESS) { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkBeginCommandBuffer()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -2894,6 +2918,7 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer if (err != VK_SUCCESS) { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkEndCommandBuffer()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -2930,6 +2955,7 @@ QRhi::FrameOpResult QRhiVulkan::endAndSubmitPrimaryCommandBuffer(VkCommandBuffer if (err != VK_SUCCESS) { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkQueueSubmit()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -2951,6 +2977,7 @@ QRhi::FrameOpResult QRhiVulkan::waitCommandCompletion(int frameSlot) if (err != VK_SUCCESS) { if (err == VK_ERROR_DEVICE_LOST) { qWarning("Device loss detected in vkWaitForFences()"); + printExtraErrorInfo(err); deviceLost = true; return QRhi::FrameOpDeviceLost; } @@ -4079,10 +4106,87 @@ void QRhiVulkan::prepareUploadSubres(QVkTexture *texD, int layer, int level, void QRhiVulkan::printExtraErrorInfo(VkResult err) { + if (err == VK_ERROR_DEVICE_LOST) + printDeviceLossErrorInfo(); if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY) qWarning() << "Out of device memory, current allocator statistics are" << statistics(); } +void QRhiVulkan::printDeviceLossErrorInfo() const +{ +#ifdef VK_EXT_device_fault + if (!dev || !caps.deviceFault || !vkGetDeviceFaultInfoEXT) + return; + + VkDeviceFaultCountsEXT faultCounts{}; + faultCounts.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT; + faultCounts.pNext = nullptr; + + VkResult result = vkGetDeviceFaultInfoEXT(dev, &faultCounts, nullptr); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) { + qWarning("vkGetDeviceFaultInfoEXT failed with %d", result); + return; + } + faultCounts.vendorBinarySize = 0; + + QVarLengthArray<VkDeviceFaultAddressInfoEXT> addressInfos; + addressInfos.resize(faultCounts.addressInfoCount); + + QVarLengthArray<VkDeviceFaultVendorInfoEXT> vendorInfos; + vendorInfos.resize(faultCounts.vendorInfoCount); + + VkDeviceFaultInfoEXT info{}; + info.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT; + info.pNext = nullptr; + info.pAddressInfos = addressInfos.isEmpty() ? nullptr : addressInfos.data(); + info.pVendorInfos = vendorInfos.isEmpty() ? nullptr : vendorInfos.data(); + info.pVendorBinaryData = nullptr; + + result = vkGetDeviceFaultInfoEXT(dev, &faultCounts, &info); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) { + qWarning("vkGetDeviceFaultInfoEXT failed with %d", result); + return; + } + + const char *desc = info.description[0] ? info.description : "n/a"; + qWarning("VK_ERROR_DEVICE_LOST (VK_EXT_device_fault): %u address infos, %u vendor infos, %llu bytes vendor binary: %s", + faultCounts.addressInfoCount, + faultCounts.vendorInfoCount, + (unsigned long long)faultCounts.vendorBinarySize, + desc); + + for (uint32_t i = 0; i < faultCounts.addressInfoCount; ++i) { + const auto &a = addressInfos[i]; + auto addressTypeString = [](const VkDeviceFaultAddressTypeEXT type) { + switch (type) { + case VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT: return "NONE"; + case VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT: return "READ_INVALID"; + case VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT: return "WRITE_INVALID"; + case VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT: return "EXECUTE_INVALID"; + case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT: return "INSTRUCTION_POINTER_UNKNOWN"; + case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT: return "INSTRUCTION_POINTER_INVALID"; + case VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT: return "INSTRUCTION_POINTER_FAULT"; + default: return "UNKNOWN"; + }; + }; + qWarning(" AddressInfo[%02u]: type=%s addr=0x%llx precision=%llu", + i, + addressTypeString(a.addressType), + (unsigned long long)a.reportedAddress, + (unsigned long long)a.addressPrecision); + } + + for (uint32_t i = 0; i < faultCounts.vendorInfoCount; ++i) { + const auto &v = vendorInfos[i]; + qWarning(" VendorInfo[%02u]: code=%llu data=%llu desc=%s", + i, + (unsigned long long)v.vendorFaultCode, + (unsigned long long)v.vendorFaultData, + v.description); + } +#endif // VK_EXT_device_fault +} + void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates) { QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates); diff --git a/src/gui/rhi/qrhivulkan_p.h b/src/gui/rhi/qrhivulkan_p.h index 21044545ad2..eb07d8be448 100644 --- a/src/gui/rhi/qrhivulkan_p.h +++ b/src/gui/rhi/qrhivulkan_p.h @@ -882,6 +882,7 @@ public: void ensureCommandPoolForNewFrame(); double elapsedSecondsFromTimestamp(quint64 timestamp[2], bool *ok); void printExtraErrorInfo(VkResult err); + void printDeviceLossErrorInfo() const; QVulkanInstance *inst = nullptr; QWindow *maybeWindow = nullptr; @@ -942,11 +943,16 @@ public: PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR = nullptr; #endif +#ifdef VK_EXT_device_fault + PFN_vkGetDeviceFaultInfoEXT vkGetDeviceFaultInfoEXT = nullptr; +#endif + struct { bool compute = false; bool depthClamp = false; bool wideLines = false; bool debugUtils = false; + bool deviceFault = false; bool vertexAttribDivisor = false; bool texture3DSliceAs2D = false; bool tessellation = false; diff --git a/src/gui/text/freetype/qfontengine_ft.cpp b/src/gui/text/freetype/qfontengine_ft.cpp index 63d9c2893dc..e331a4cc815 100644 --- a/src/gui/text/freetype/qfontengine_ft.cpp +++ b/src/gui/text/freetype/qfontengine_ft.cpp @@ -1225,7 +1225,7 @@ static inline QTransform FTAffineToQTransform(const FT_Affine23 &matrix) } bool QFontEngineFT::traverseColr1(FT_OpaquePaint opaquePaint, - QSet<QPair<FT_Byte *, FT_Bool> > *loops, + QSet<std::pair<FT_Byte *, FT_Bool> > *loops, QColor foregroundColor, FT_Color *palette, ushort paletteCount, @@ -1233,7 +1233,7 @@ bool QFontEngineFT::traverseColr1(FT_OpaquePaint opaquePaint, { FT_Face face = freetype->face; - auto key = qMakePair(opaquePaint.p, opaquePaint.insert_root_transform); + auto key = std::pair{opaquePaint.p, opaquePaint.insert_root_transform}; if (loops->contains(key)) { qCWarning(lcColrv1) << "Cycle detected in COLRv1 graph"; return false; @@ -1680,7 +1680,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadColrv1Glyph(QGlyphSet *set, // Do a pass over the graph to find the bounds QColrPaintGraphRenderer boundingRectCalculator; boundingRectCalculator.beginCalculateBoundingBox(); - QSet<QPair<FT_Byte *, FT_Bool> > loops; + QSet<std::pair<FT_Byte *, FT_Bool> > loops; if (traverseColr1(opaquePaint, &loops, QColor{}, @@ -1735,7 +1735,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadColrv1Glyph(QGlyphSet *set, originalXform); // Render - QSet<QPair<FT_Byte *, FT_Bool> > loops; + QSet<std::pair<FT_Byte *, FT_Bool> > loops; if (!traverseColr1(opaquePaint, &loops, foregroundColor, diff --git a/src/gui/text/freetype/qfontengine_ft_p.h b/src/gui/text/freetype/qfontengine_ft_p.h index fc07693ef6a..13cd1bf2bfa 100644 --- a/src/gui/text/freetype/qfontengine_ft_p.h +++ b/src/gui/text/freetype/qfontengine_ft_p.h @@ -34,6 +34,8 @@ #include <string.h> #include <qpainterpath.h> +#include <utility> // for std::pair + QT_BEGIN_NAMESPACE class QFontEngineFTRawFont; @@ -333,7 +335,7 @@ private: bool fetchMetricsOnly) const; bool traverseColr1(FT_OpaquePaint paint, - QSet<QPair<FT_Byte *, FT_Bool> > *loops, + QSet<std::pair<FT_Byte *, FT_Bool> > *loops, QColor foregroundColor, FT_Color *palette, ushort paletteCount, diff --git a/src/gui/text/qcolrpaintgraphrenderer.cpp b/src/gui/text/qcolrpaintgraphrenderer.cpp index 9041e804753..bc439021eb1 100644 --- a/src/gui/text/qcolrpaintgraphrenderer.cpp +++ b/src/gui/text/qcolrpaintgraphrenderer.cpp @@ -180,7 +180,7 @@ void QColrPaintGraphRenderer::setConicalGradient(QPointF center, adaptedStops.reserve(gradientStops.size()); for (const QGradientStop &gradientStop : gradientStops) - adaptedStops.append(qMakePair(gradientStop.first * multiplier, gradientStop.second)); + adaptedStops.append({gradientStop.first * multiplier, gradientStop.second}); conicalGradient.setStops(adaptedStops); conicalGradient.setCoordinateMode(QGradient::LogicalMode); diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index c144820fa24..ba49d538c2c 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -31,6 +31,7 @@ #include <QtCore/QMutexLocker> #include <QtCore/QMutex> +#include <algorithm> #include <array> // #define QFONTCACHE_DEBUG @@ -1853,35 +1854,13 @@ bool QFont::operator<(const QFont &f) const int f2attrs = (d->underline << 3) + (d->overline << 2) + (d->strikeOut<<1) + d->kerning; if (f1attrs != f2attrs) return f1attrs < f2attrs; - if (d->features.size() != f.d->features.size()) - return f.d->features.size() < d->features.size(); - - { - auto it = d->features.constBegin(); - auto jt = f.d->features.constBegin(); - for (; it != d->features.constEnd(); ++it, ++jt) { - if (it.key() != jt.key()) - return jt.key() < it.key(); - if (it.value() != jt.value()) - return jt.value() < it.value(); - } - } - - if (r1.variableAxisValues.size() != r2.variableAxisValues.size()) - return r1.variableAxisValues.size() < r2.variableAxisValues.size(); - - { - auto it = r1.variableAxisValues.constBegin(); - auto jt = r2.variableAxisValues.constBegin(); - for (; it != r1.variableAxisValues.constEnd(); ++it, ++jt) { - if (it.key() != jt.key()) - return jt.key() < it.key(); - if (it.value() != jt.value()) - return jt.value() < it.value(); - } + if (d->features != f.d->features) { + return std::lexicographical_compare(f.d->features.keyValueBegin(), f.d->features.keyValueEnd(), + d->features.keyValueBegin(), d->features.keyValueEnd()); } - return false; + return std::lexicographical_compare(r1.variableAxisValues.keyValueBegin(), r1.variableAxisValues.keyValueEnd(), + r2.variableAxisValues.keyValueBegin(), r2.variableAxisValues.keyValueEnd()); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 0ad45b1f280..d41296291f6 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -402,7 +402,7 @@ bool QFontEngine::processHheaTable() const const qreal unitsPerEm = emSquareSize().toReal(); // Bail out if values are too large for QFixed - const auto limitForQFixed = std::numeric_limits<int>::max() / (fontDef.pixelSize * 64); + const auto limitForQFixed = qreal(std::numeric_limits<int>::max() / 64) / fontDef.pixelSize; if (ascent > limitForQFixed || descent > limitForQFixed || leading > limitForQFixed) return false; m_ascent = QFixed::fromReal(ascent * fontDef.pixelSize / unitsPerEm); @@ -470,7 +470,7 @@ bool QFontEngine::processOS2Table() const if (typoAscent == 0 && typoDescent == 0) return false; // Bail out if values are too large for QFixed - const auto limitForQFixed = std::numeric_limits<int>::max() / (fontDef.pixelSize * 64); + const auto limitForQFixed = qreal(std::numeric_limits<int>::max() / 64) / fontDef.pixelSize; if (typoAscent > limitForQFixed || typoDescent > limitForQFixed || typoLineGap > limitForQFixed) return false; @@ -481,7 +481,7 @@ bool QFontEngine::processOS2Table() const // Some fonts may have invalid OS/2 data. We detect this and bail out. if (winAscent == 0 && winDescent == 0) return false; - const auto limitForQFixed = std::numeric_limits<int>::max() / (fontDef.pixelSize * 64); + const auto limitForQFixed = qreal(std::numeric_limits<int>::max() / 64) / fontDef.pixelSize; if (winAscent > limitForQFixed || winDescent > limitForQFixed) return false; m_ascent = QFixed::fromReal(winAscent * fontDef.pixelSize / unitsPerEm); diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index eb0f6c3710c..4f01d09fed1 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1976,7 +1976,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const return; bool documentPaginated = d->pageSize.isValid() && !d->pageSize.isNull() - && d->pageSize.height() != INT_MAX; + && d->pageSize.height() != qreal(INT_MAX); // ### set page size to paginated size? QMarginsF m = printer->pageLayout().margins(QPageLayout::Millimeter); diff --git a/src/gui/text/windows/qwindowsfontdatabasebase.cpp b/src/gui/text/windows/qwindowsfontdatabasebase.cpp index 990f20fa447..055e616dbb2 100644 --- a/src/gui/text/windows/qwindowsfontdatabasebase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabasebase.cpp @@ -18,6 +18,8 @@ # include "qwindowsfontenginedirectwrite_p.h" #endif +#include <utility> // for std::pair + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -363,7 +365,7 @@ namespace { inline void addKey(const QByteArray &fontData, const QString &filename) { if (!m_fontDatas.contains(fontData.data())) - m_fontDatas.insert(fontData.data(), qMakePair(fontData, filename)); + m_fontDatas.insert(fontData.data(), {fontData, filename}); } HRESULT STDMETHODCALLTYPE GetFilePathLengthFromKey(void const* fontFileReferenceKey, @@ -433,7 +435,7 @@ namespace { private: ULONG m_referenceCount; - QHash<const void *, QPair<QByteArray, QString> > m_fontDatas; + QHash<const void *, std::pair<QByteArray, QString> > m_fontDatas; }; HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid, diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp index 3e10cdad44f..2f0ce3449d9 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp @@ -1074,7 +1074,7 @@ bool QWindowsFontEngineDirectWrite::traverseColr1(IDWritePaintReader *paintReade for (int i = 0; i < stopCount; ++i) { const D2D1_GRADIENT_STOP &stop = stops[i]; QColor color = QColor::fromRgbF(stop.color.r, stop.color.g, stop.color.b, stop.color.a); - ret.append(qMakePair(stop.position, color)); + ret.append({stop.position, color}); } return ret; diff --git a/src/network/access/qformdatabuilder.cpp b/src/network/access/qformdatabuilder.cpp index 470e285c6ad..debefd24634 100644 --- a/src/network/access/qformdatabuilder.cpp +++ b/src/network/access/qformdatabuilder.cpp @@ -9,6 +9,7 @@ #include "QtCore/qmimedatabase.h" #endif +#include <variant> #include <vector> QT_BEGIN_NAMESPACE diff --git a/src/network/access/qformdatabuilder.h b/src/network/access/qformdatabuilder.h index 7d667aea21c..3992776161d 100644 --- a/src/network/access/qformdatabuilder.h +++ b/src/network/access/qformdatabuilder.h @@ -15,7 +15,6 @@ #include <QtCore/qstring.h> #include <memory> -#include <variant> #ifndef Q_OS_WASM QT_REQUIRE_CONFIG(http); diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index f35b89d1aec..3f60c5b3925 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -259,7 +259,7 @@ public: QString peerVerifyName; - QTcpKeepAliveConfiguration tcpKeepAliveConfiguration; + QTcpKeepAliveConfiguration tcpKeepAliveConfiguration = {}; friend class QHttpNetworkConnectionChannel; }; diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h index f179d95ac17..5005f8c01c2 100644 --- a/src/network/access/qhttpthreaddelegate_p.h +++ b/src/network/access/qhttpthreaddelegate_p.h @@ -92,7 +92,7 @@ public: QString incomingErrorDetail; QHttp1Configuration http1Parameters; QHttp2Configuration http2Parameters; - QTcpKeepAliveConfiguration tcpKeepAliveParameters; + QTcpKeepAliveConfiguration tcpKeepAliveParameters = {}; protected: // The zerocopy download buffer, if used: diff --git a/src/network/access/qnetworkaccesscache.cpp b/src/network/access/qnetworkaccesscache.cpp index bb1bdd87a8a..6ff70cd546d 100644 --- a/src/network/access/qnetworkaccesscache.cpp +++ b/src/network/access/qnetworkaccesscache.cpp @@ -5,11 +5,6 @@ #include "qnetworkaccesscache_p.h" #include "QtCore/qpointer.h" #include "QtCore/qdeadlinetimer.h" -#include "qnetworkaccessmanager_p.h" -#include "qnetworkreply_p.h" -#include "qnetworkrequest.h" - -#include <vector> //#define DEBUG_ACCESSCACHE diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index c20cd43a2fd..6c44e42dbba 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -5,7 +5,6 @@ #include "qnetworkcookie.h" #include "qnetworkcookie_p.h" -#include "qnetworkrequest.h" #include "qnetworkreply.h" #include "QtCore/qbytearray.h" #include "QtCore/qdatetime.h" diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index adad12a4242..be05249c1b8 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -265,19 +265,26 @@ void QCocoaGLContext::updateSurfaceFormat() return value; }; - int colorSize = pixelFormatAttribute(NSOpenGLPFAColorSize); - colorSize /= 4; // The attribute includes the alpha component - m_format.setRedBufferSize(colorSize); - m_format.setGreenBufferSize(colorSize); - m_format.setBlueBufferSize(colorSize); + // Resolve color channel bits from GL, rather than NSOpenGLPFAColorSize, + // as the latter is not specific enough (combines all channels). + GLint redBits, greenBits, blueBits; + glGetIntegerv(GL_RED_BITS, &redBits); + glGetIntegerv(GL_GREEN_BITS, &greenBits); + glGetIntegerv(GL_BLUE_BITS, &blueBits); + m_format.setRedBufferSize(redBits); + m_format.setGreenBufferSize(greenBits); + m_format.setBlueBufferSize(blueBits); // Surfaces on macOS always have an alpha channel, but unless the user requested // one via setAlphaBufferSize(), which triggered setting NSOpenGLCPSurfaceOpacity // to make the surface non-opaque, we don't want to report back the actual alpha // size, as that will make the user believe the alpha channel can be used for // something useful, when in reality it can't, due to the surface being opaque. - if (m_format.alphaBufferSize() > 0) - m_format.setAlphaBufferSize(pixelFormatAttribute(NSOpenGLPFAAlphaSize)); + if (m_format.alphaBufferSize() > 0) { + GLint alphaBits; + glGetIntegerv(GL_ALPHA_BITS, &alphaBits); + m_format.setAlphaBufferSize(alphaBits); + } m_format.setDepthBufferSize(pixelFormatAttribute(NSOpenGLPFADepthSize)); m_format.setStencilBufferSize(pixelFormatAttribute(NSOpenGLPFAStencilSize)); diff --git a/src/plugins/platforms/wasm/qwasmdrag.cpp b/src/plugins/platforms/wasm/qwasmdrag.cpp index 757959e5694..6447d1e399f 100644 --- a/src/plugins/platforms/wasm/qwasmdrag.cpp +++ b/src/plugins/platforms/wasm/qwasmdrag.cpp @@ -94,15 +94,13 @@ Qt::DropAction QWasmDrag::drag(QDrag *drag) return Qt::IgnoreAction; Qt::DropAction dragResult = Qt::IgnoreAction; - if (qstdweb::haveJspi()) { + if (qstdweb::haveAsyncify()) { m_dragState = std::make_unique<DragState>(drag, window, [this]() { QSimpleDrag::cancelDrag(); }); - QSimpleDrag::drag(drag); - dragResult = m_dragState->dropAction; + dragResult = QSimpleDrag::drag(drag); m_dragState.reset(); - } - - if (dragResult == Qt::IgnoreAction) + } else { dragResult = QBasicDrag::drag(drag); + } return dragResult; } @@ -117,6 +115,7 @@ void QWasmDrag::onNativeDragStarted(DragEvent *event) event->cancelDragStart(); return; } + setExecutedDropAction(event->dropAction); // We have our own window if (shapedPixmapWindow()) @@ -145,8 +144,10 @@ void QWasmDrag::onNativeDragOver(DragEvent *event) event->mouseButton, event->modifiers); event->acceptDragOver(); if (dragResponse.isAccepted()) { + setExecutedDropAction(dragResponse.acceptedAction()); event->dataTransfer.setDropAction(dragResponse.acceptedAction()); } else { + setExecutedDropAction(Qt::DropAction::IgnoreAction); event->dataTransfer.setDropAction(Qt::DropAction::IgnoreAction); } } @@ -174,6 +175,7 @@ void QWasmDrag::onNativeDrop(DragEvent *event) // files, but the browser expects that accepted state is set before any // async calls. event->acceptDrop(); + setExecutedDropAction(event->dropAction); std::shared_ptr<DragState> dragState = m_dragState; const auto dropCallback = [dragState, wasmWindow, targetWindowPos, @@ -198,6 +200,7 @@ void QWasmDrag::onNativeDragFinished(DragEvent *event) { event->webEvent.call<void>("preventDefault"); m_dragState->dropAction = event->dropAction; + setExecutedDropAction(event->dropAction); m_dragState->quitEventLoopClosure(); } @@ -213,6 +216,8 @@ void QWasmDrag::onNativeDragEnter(DragEvent *event) if (m_dragState) m_dragState->dropAction = event->dropAction; + setExecutedDropAction(event->dropAction); + QDrag *drag = new QDrag(this); drag->setMimeData(new QMimeData()); drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); @@ -223,6 +228,7 @@ void QWasmDrag::onNativeDragLeave(DragEvent *event) event->webEvent.call<void>("preventDefault"); if (m_dragState) m_dragState->dropAction = event->dropAction; + setExecutedDropAction(event->dropAction); event->dataTransfer.setDropAction(Qt::DropAction::IgnoreAction); } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index f27943070d0..2be05625971 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -513,7 +513,6 @@ void QWaylandWindow::setGeometry(const QRect &r) mWindowDecoration->update(); QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(window(), geometry()); - mSentInitialResize = true; } // Wayland has no concept of areas being exposed or not, only the entire window, when our geometry changes, we need to flag the new area as exposed diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h index 9e1bd92af30..7dda16cc776 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow_p.h +++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h @@ -334,7 +334,6 @@ protected: int mFrameCallbackTimeout = 100; QVariantMap m_properties; - bool mSentInitialResize = false; QPoint mOffset; std::optional<qreal> mScale = std::nullopt; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b77e985c965..2816982b1a8 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1732,8 +1732,10 @@ void QWindowsWindow::destroyWindow() m_surface = nullptr; } #endif + DestroyWindow(m_data.hwndTitlebar); DestroyWindow(m_data.hwnd); context->removeWindow(m_data.hwnd); + m_data.hwndTitlebar = nullptr; m_data.hwnd = nullptr; } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 2c56603fef0..7d5f0155960 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2573,7 +2573,7 @@ void QXcbWindow::setOpacity(qreal level) if (!m_window) return; - quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * 0xffffffff); + quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * qreal(0xffffffff)); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp index 6fd857828d3..ff2d4bd845f 100644 --- a/src/plugins/styles/modernwindows/qwindows11style.cpp +++ b/src/plugins/styles/modernwindows/qwindows11style.cpp @@ -914,12 +914,17 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption break; case PE_IndicatorBranch: { if (option->state & State_Children) { + const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option); const bool isReverse = option->direction == Qt::RightToLeft; const bool isOpen = option->state & QStyle::State_Open; + const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); QFont f(d->assetFont); - f.setPointSize(6); + f.setPointSize(8); painter->setFont(f); - painter->setPen(option->palette.color(isOpen ? QPalette::Active : QPalette::Disabled, + if (view && view->alternatingRowColors() && vopt && vopt->state & State_Selected) + painter->setPen(winUI3Color(textOnAccentPrimary)); + else + painter->setPen(option->palette.color(isOpen ? QPalette::Active : QPalette::Disabled, QPalette::WindowText)); const auto ico = isOpen ? Icon::ChevronDownMed : (isReverse ? Icon::ChevronLeftMed @@ -1071,14 +1076,16 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption if (option->state & State_Selected && !highContrastTheme) { // keep in sync with CE_ItemViewItem QListView indicator painting - const auto col = option->palette.accent().color(); - painter->setBrush(col); - painter->setPen(col); - const auto xPos = isRtl ? rect.right() - 4.5f : rect.left() + 3.5f; - const auto yOfs = rect.height() / 4.; - QRectF r(QPointF(xPos, rect.y() + yOfs), - QPointF(xPos + 1, rect.y() + rect.height() - yOfs)); - painter->drawRoundedRect(r, 1, 1); + if (!qobject_cast<const QTableView *>(widget)) { + const auto col = option->palette.accent().color(); + painter->setBrush(col); + painter->setPen(col); + const auto xPos = isRtl ? rect.right() - 4.5f : rect.left() + 3.5f; + const auto yOfs = rect.height() / 4.; + QRectF r(QPointF(xPos, rect.y() + yOfs), + QPointF(xPos + 1, rect.y() + rect.height() - yOfs)); + painter->drawRoundedRect(r, 1, 1); + } } const bool isTreeDecoration = vopt->features.testFlag( @@ -1099,7 +1106,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption } const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); - painter->setBrush(view->alternatingRowColors() ? vopt->palette.highlight() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); + painter->setBrush(view->alternatingRowColors() && state & State_Selected ? calculateAccentColor(option) : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]); painter->setPen(Qt::NoPen); if (isFirst) { QPainterStateGuard psg(painter); @@ -1753,13 +1760,13 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op } } const bool highlightCurrent = vopt->state.testAnyFlags(State_Selected | State_MouseOver); + const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); if (highlightCurrent) { if (highContrastTheme) { painter->setBrush(vopt->palette.highlight()); } else { - const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(widget); - painter->setBrush(view && view->alternatingRowColors() - ? vopt->palette.highlight() + painter->setBrush(view && view->alternatingRowColors() && vopt->state & State_Selected + ? calculateAccentColor(option) : winUI3Color(subtleHighlightColor)); } } else { @@ -1815,8 +1822,13 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op vopt->icon.paint(painter, iconRect, vopt->decorationAlignment, mode, state); } - painter->setPen(highlightCurrent && highContrastTheme ? vopt->palette.base().color() - : vopt->palette.text().color()); + if (highlightCurrent && highContrastTheme) { + painter->setPen(vopt->palette.base().color()); + } else if ((view && view->alternatingRowColors() && highlightCurrent && vopt->state & State_Selected)) { + painter->setPen(winUI3Color(textOnAccentPrimary)); + } else { + painter->setPen(vopt->palette.text().color()); + } d->viewItemDrawText(painter, vopt, textRect); // paint a vertical marker for QListView diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 6e7077b383e..94c75ae6eb3 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -78,16 +78,18 @@ QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING) return nullptr; } - Generator::Generator(Moc *moc, ClassDef *classDef, const QList<QByteArray> &metaTypes, + Generator::Generator(Moc *moc, const ClassDef *classDef, const QList<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, - const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile, - bool requireCompleteTypes) + const QHash<QByteArray, QByteArray> &knownGadgets, + const QHash<QByteArray, QByteArray> &hashes, + FILE *outfile, bool requireCompleteTypes) : parser(moc), out(outfile), cdef(classDef), metaTypes(metaTypes), knownQObjectClasses(knownQObjectClasses), knownGadgets(knownGadgets), + hashes(hashes), requireCompleteTypes(requireCompleteTypes) { if (cdef->superclassList.size()) @@ -228,28 +230,11 @@ void Generator::generateCode() bool isQObject = (cdef->classname == "QObject"); bool isConstructible = !cdef->constructorList.isEmpty(); - // filter out undeclared enumerators and sets - { - QList<EnumDef> enumList; - for (EnumDef def : std::as_const(cdef->enumList)) { - if (cdef->enumDeclarations.contains(def.name)) { - enumList += def; - } - def.enumName = def.name; - QByteArray alias = cdef->flagAliases.value(def.name); - if (cdef->enumDeclarations.contains(alias)) { - def.name = alias; - def.flags |= cdef->enumDeclarations[alias]; - enumList += def; - } - } - cdef->enumList = enumList; - } - // // Register all strings used in data section // strreg(cdef->qualified); + strreg(hashes[cdef->qualified]); registerClassInfoStrings(); registerFunctionStrings(cdef->signalList); registerFunctionStrings(cdef->slotList); @@ -308,6 +293,8 @@ void Generator::generateCode() addEnums(); fprintf(out, " };\n"); + fprintf(out, " uint qt_metaObjectHashIndex = %d;\n", stridx(hashes[cdef->qualified])); + const char *uintDataParams = ""; if (isConstructible || !cdef->classInfoList.isEmpty()) { if (isConstructible) { @@ -340,7 +327,7 @@ void Generator::generateCode() if (!requireCompleteness) tagType = "qt_meta_tag_" + qualifiedClassNameIdentifier + "_t"; fprintf(out, " return QtMocHelpers::metaObjectData<%s, %s>(%s, qt_stringData,\n" - " qt_methods, qt_properties, qt_enums%s);\n" + " qt_methods, qt_properties, qt_enums, qt_metaObjectHashIndex%s);\n" "}\n", ownType, tagType.constData(), metaObjectFlags, uintDataParams); } diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h index 45df0783c2b..77be2fc6714 100644 --- a/src/tools/moc/generator.h +++ b/src/tools/moc/generator.h @@ -12,14 +12,15 @@ class Generator { Moc *parser = nullptr; FILE *out; - ClassDef *cdef; + const ClassDef *cdef; QList<uint> meta_data; public: - Generator(Moc *moc, ClassDef *classDef, const QList<QByteArray> &metaTypes, + Generator(Moc *moc, const ClassDef *classDef, const QList<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, - const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = nullptr, - bool requireCompleteTypes = false); + const QHash<QByteArray, QByteArray> &knownGadgets, + const QHash<QByteArray, QByteArray> &hashes, + FILE *outfile = nullptr, bool requireCompleteTypes = false); void generateCode(); qsizetype registeredStringsCount() { return strings.size(); } @@ -54,6 +55,7 @@ private: QList<QByteArray> metaTypes; QHash<QByteArray, QByteArray> knownQObjectClasses; QHash<QByteArray, QByteArray> knownGadgets; + QHash<QByteArray, QByteArray> hashes; bool requireCompleteTypes; }; diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index baa6690350d..7f05f34edb6 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -17,6 +17,10 @@ #include <private/qmetaobject_moc_p.h> #include <private/qduplicatetracker_p.h> +// This is a bootstrapped tool, so we can't rely on QCryptographicHash for the +// faster SHA1 implementations from OpenSSL. +#include "../../3rdparty/sha1/sha1.cpp" + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -1191,6 +1195,24 @@ static QByteArrayList requiredQtContainers(const QList<ClassDef> &classes) return required; } +QByteArray classDefJsonObjectHash(const QJsonObject &object) +{ + const QByteArray json = QJsonDocument(object).toJson(QJsonValue::JsonFormat::Compact); + QByteArray hash(20, 0); // SHA1 produces 160 bits of data + + { + Sha1State state; + sha1InitState(&state); + sha1Update(&state, reinterpret_cast<const uchar *>(json.constData()), json.size()); + sha1FinalizeState(&state); + sha1ToHash(&state, reinterpret_cast<uchar *>(hash.data())); + } + + static const char revisionPrefix[] = "0$"; + const QByteArray hashB64 = hash.toBase64(QByteArray::OmitTrailingEquals); + return revisionPrefix + hashB64; +} + void Moc::generate(FILE *out, FILE *jsonOutput) { QByteArrayView fn = strippedFileName(); @@ -1247,14 +1269,40 @@ void Moc::generate(FILE *out, FILE *jsonOutput) "#endif\n\n"); #endif + // filter out undeclared enumerators and sets + for (ClassDef &cdef : classList) { + QList<EnumDef> enumList; + for (EnumDef def : std::as_const(cdef.enumList)) { + if (cdef.enumDeclarations.contains(def.name)) { + enumList += def; + } + def.enumName = def.name; + QByteArray alias = cdef.flagAliases.value(def.name); + if (cdef.enumDeclarations.contains(alias)) { + def.name = alias; + def.flags |= cdef.enumDeclarations[alias]; + enumList += def; + } + } + cdef.enumList = enumList; + } + fprintf(out, "QT_WARNING_PUSH\n"); fprintf(out, "QT_WARNING_DISABLE_DEPRECATED\n"); fprintf(out, "QT_WARNING_DISABLE_GCC(\"-Wuseless-cast\")\n"); + QHash<QByteArray, QJsonObject> classDefJsonObjects; + QHash<QByteArray, QByteArray> metaObjectHashes; + for (const ClassDef &def : std::as_const(classList)) { + const QJsonObject jsonObject = def.toJson(); + classDefJsonObjects.insert(def.qualified, jsonObject); + metaObjectHashes.insert(def.qualified, classDefJsonObjectHash(jsonObject)); + } + fputs("", out); - for (ClassDef &def : classList) { - Generator generator(this, &def, metaTypes, knownQObjectClasses, knownGadgets, out, - requireCompleteTypes); + for (const ClassDef &def : std::as_const(classList)) { + Generator generator(this, &def, metaTypes, knownQObjectClasses, knownGadgets, + metaObjectHashes, out, requireCompleteTypes); generator.generateCode(); // generator.generateCode() should have already registered all strings @@ -1273,13 +1321,20 @@ void Moc::generate(FILE *out, FILE *jsonOutput) mocData["inputFile"_L1] = QLatin1StringView(fn.constData()); QJsonArray classesJsonFormatted; + QJsonObject hashesJsonObject; - for (const ClassDef &cdef: std::as_const(classList)) - classesJsonFormatted.append(cdef.toJson()); + for (const ClassDef &cdef : std::as_const(classList)) { + classesJsonFormatted.append(classDefJsonObjects[cdef.qualified]); + hashesJsonObject.insert(QString::fromLatin1(cdef.qualified), + QString::fromLatin1(metaObjectHashes[cdef.qualified])); + } if (!classesJsonFormatted.isEmpty()) mocData["classes"_L1] = classesJsonFormatted; + if (!hashesJsonObject.isEmpty()) + mocData["hashes"_L1] = hashesJsonObject; + QJsonDocument jsonDoc(mocData); fputs(jsonDoc.toJson().constData(), jsonOutput); } diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index d43b6ec4fb2..c47e3bee13c 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -412,7 +412,7 @@ qt_internal_extend_target(Widgets CONDITION QT_FEATURE_shortcut qt_internal_extend_target(Widgets CONDITION QT_FEATURE_tooltip SOURCES - kernel/qtooltip.cpp kernel/qtooltip.h + kernel/qtooltip.cpp kernel/qtooltip.h kernel/qtooltip_p.h ) qt_internal_extend_target(Widgets CONDITION QT_FEATURE_whatsthis diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index fa17c94a23f..3417d93d587 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -29,6 +29,7 @@ #include <qtooltip.h> #include <QtCore/qbasictimer.h> +#include <QtWidgets/private/qtooltip_p.h> QT_BEGIN_NAMESPACE @@ -93,57 +94,6 @@ using namespace Qt::StringLiterals; \sa QWidget::toolTip, QAction::toolTip */ -class QTipLabel : public QLabel -{ - Q_OBJECT -public: - QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime); - ~QTipLabel(); - static QTipLabel *instance; - - void adjustTooltipScreen(const QPoint &pos); - void updateSize(const QPoint &pos); - - bool eventFilter(QObject *, QEvent *) override; - - QBasicTimer hideTimer, expireTimer; - - bool fadingOut; - - void reuseTip(const QString &text, int msecDisplayTime, const QPoint &pos); - void hideTip(); - void hideTipImmediately(); - void setTipRect(QWidget *w, const QRect &r); - void restartExpireTimer(int msecDisplayTime); - bool tipChanged(const QPoint &pos, const QString &text, QObject *o); - void placeTip(const QPoint &pos, QWidget *w); - - static QScreen *getTipScreen(const QPoint &pos, QWidget *w); -protected: - void timerEvent(QTimerEvent *e) override; - void paintEvent(QPaintEvent *e) override; - void mouseMoveEvent(QMouseEvent *e) override; - void resizeEvent(QResizeEvent *e) override; - -#if QT_CONFIG(style_stylesheet) -public slots: - /** \internal - Cleanup the _q_stylesheet_parent property. - */ - void styleSheetParentDestroyed() { - setProperty("_q_stylesheet_parent", QVariant()); - styleSheetParent = nullptr; - } - -private: - QWidget *styleSheetParent; -#endif - -private: - QWidget *widget; - QRect rect; -}; - QTipLabel *QTipLabel::instance = nullptr; QTipLabel::QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime) @@ -152,6 +102,7 @@ QTipLabel::QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int mse , styleSheetParent(nullptr) #endif , widget(nullptr) + , fadingOut(false) { delete instance; instance = this; @@ -166,7 +117,6 @@ QTipLabel::QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int mse qApp->installEventFilter(this); setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, nullptr, this) / 255.0); setMouseTracking(true); - fadingOut = false; reuseTip(text, msecDisplayTime, pos); } @@ -433,6 +383,15 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o) return false; } +/** \internal + Cleanup the _q_stylesheet_parent property. + */ +void QTipLabel::styleSheetParentDestroyed() +{ + setProperty("_q_stylesheet_parent", QVariant()); + styleSheetParent = nullptr; +} + /*! Shows \a text as a tool tip, with the global position \a pos as the point of interest. The tool tip will be shown with a platform @@ -594,4 +553,4 @@ void QToolTip::setFont(const QFont &font) QT_END_NAMESPACE -#include "qtooltip.moc" +#include "moc_qtooltip_p.cpp" diff --git a/src/widgets/kernel/qtooltip_p.h b/src/widgets/kernel/qtooltip_p.h new file mode 100644 index 00000000000..51faaf58c34 --- /dev/null +++ b/src/widgets/kernel/qtooltip_p.h @@ -0,0 +1,74 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +// Qt-Security score:significant reason:default + +#ifndef QTOOLTIP_P_H +#define QTOOLTIP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of qlayout*.cpp, and qabstractlayout.cpp. This header +// file may change from version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QLabel> +#include <QString> +#include <QRect> +#include <QToolTip> + +QT_REQUIRE_CONFIG(tooltip); +QT_BEGIN_NAMESPACE + +class Q_WIDGETS_EXPORT QTipLabel final : public QLabel +{ + Q_OBJECT +public: + explicit QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime); + ~QTipLabel() override; + + void adjustTooltipScreen(const QPoint &pos); + void updateSize(const QPoint &pos); + + bool eventFilter(QObject *, QEvent *) override; + + void reuseTip(const QString &text, int msecDisplayTime, const QPoint &pos); + void hideTip(); + void hideTipImmediately(); + void setTipRect(QWidget *w, const QRect &r); + void restartExpireTimer(int msecDisplayTime); + bool tipChanged(const QPoint &pos, const QString &text, QObject *o); + void placeTip(const QPoint &pos, QWidget *w); + + static QScreen *getTipScreen(const QPoint &pos, QWidget *w); +protected: + void timerEvent(QTimerEvent *e) override; + void paintEvent(QPaintEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + +#if QT_CONFIG(style_stylesheet) +public Q_SLOTS: + void styleSheetParentDestroyed(); + +private: + QWidget *styleSheetParent; +#endif + +private: + friend class QToolTip; + + static QTipLabel *instance; + QBasicTimer hideTimer, expireTimer; + QWidget *widget; + QRect rect; + bool fadingOut; +}; + +QT_END_NAMESPACE + +#endif // QTOOLTIP_P_H diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 3575eb78ac4..9b6b96d911b 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -1537,8 +1537,12 @@ void QMenuPrivate::_q_actionTriggered() } activateCausedStack(list, action, QAction::Trigger, false); // if a widget action fires, we need to hide the menu explicitly - if (qobject_cast<QWidgetAction*>(action)) + if (qobject_cast<QWidgetAction*>(action)) { + // make sure QMenu::exec returns the triggered widget action + currentAction = action; + setSyncAction(); hideUpToMenuBar(); + } } } } |
