From 7f3539202fc900c53950dd6fa59cf8d9b6171af3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 6 Oct 2022 07:31:11 +0200 Subject: [PATCH] Short live q20::exchange()! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have weaned ourselves off of qExchange(), which, however, has C++23 semantics (is constexpr and noexcept), while we only require C++17 atm. At the same time, we have more and more uses of a constexpr exchange(), iow: the C++20 extension. We have the qNN namespaces for this, so let's use it: Add q20::exchange(), with C++20 semantics (constexpr, not noexcept), and use it to port the only remaining qExchange() user (since ported to 2×std::move() to make the header compatible with QT_NO_QEXCHANGE), QScopedValueRollback. No user requires the C++23 noexcept on the function (compilers will figure it out, because the std::exchange is fully inline), and we can't provide a q23::exchange() even if we needed to, because the author of P2401 forgot to ask to update the value of __cpp_lib_exchange_function... Conflict resolution for 6.8: - worked around missing a313caca239638b384018aec18906de44aab2171, by back-porting the relevant subset of it Fixes: QTBUG-133038 Change-Id: I003df445001d1c5ab02402119c5e5106aa156263 Reviewed-by: Thiago Macieira (cherry picked from commit b5ed7fb203335cef7b7b4f70f4130b07166cecf2) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit cebb2dd0681f7e4f8a838730a2b15e0c7384c711) Reviewed-by: Ivan Solovev --- src/corelib/CMakeLists.txt | 1 + src/corelib/global/q20utility.h | 46 ++++++++++++++++++++++++ src/corelib/global/q23utility.h | 2 +- src/corelib/tools/qscopedvaluerollback.h | 5 +-- 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/corelib/global/q20utility.h diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 1b771e67a61..faf9a349f12 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -96,6 +96,7 @@ qt_internal_add_module(Core global/q20map.h global/q20memory.h global/q20type_traits.h + global/q20utility.h global/q20vector.h global/q23functional.h global/q23utility.cpp # remove once we have a user that tests this diff --git a/src/corelib/global/q20utility.h b/src/corelib/global/q20utility.h new file mode 100644 index 00000000000..9d33500c934 --- /dev/null +++ b/src/corelib/global/q20utility.h @@ -0,0 +1,46 @@ +// Copyright (C) 2024 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 + +#ifndef Q20UTILITY_H +#define Q20UTILITY_H + +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. Types and functions defined in this +// file can reliably be replaced by their std counterparts, once available. +// You may use these definitions in your own code, but be aware that we +// will remove them once Qt depends on the C++ version that supports +// them in namespace std. There will be NO deprecation warning, the +// definitions will JUST go away. +// +// If you can't agree to these terms, don't use these definitions! +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +// like C++20 std::exchange (ie. constexpr, not yet noexcept) +namespace q20 { +#ifdef __cpp_lib_constexpr_algorithms +using std::exchange; +#else +template +constexpr T exchange(T& obj, U&& newValue) +{ + T old = std::move(obj); + obj = std::forward(newValue); + return old; +} +#endif +} + +QT_END_NAMESPACE + +#endif /* Q20UTILITY_H */ diff --git a/src/corelib/global/q23utility.h b/src/corelib/global/q23utility.h index 9ae5389b56e..3ac5d23e321 100644 --- a/src/corelib/global/q23utility.h +++ b/src/corelib/global/q23utility.h @@ -5,7 +5,7 @@ #include -#include +#include // // W A R N I N G diff --git a/src/corelib/tools/qscopedvaluerollback.h b/src/corelib/tools/qscopedvaluerollback.h index 0ae3efd0c0f..d79366bcc51 100644 --- a/src/corelib/tools/qscopedvaluerollback.h +++ b/src/corelib/tools/qscopedvaluerollback.h @@ -6,6 +6,8 @@ #include +#include + QT_BEGIN_NAMESPACE template @@ -20,9 +22,8 @@ public: Q_NODISCARD_CTOR explicit constexpr QScopedValueRollback(T &var, T value) - : varRef(var), oldValue(std::move(var)) // ### C++20: std::exchange(var, std::move(value)) + : varRef(var), oldValue(q20::exchange(var, std::move(value))) { - var = std::move(value); } #if __cpp_constexpr >= 201907L