summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2023-01-09 11:06:45 +0100
committerMarc Mutz <marc.mutz@qt.io>2023-03-31 13:10:12 +0100
commite2b2bb7ff19d889ac5582a80a90861819c213591 (patch)
treee0989160986d4e9930fb9fc68c73c81158d0f224 /tests/auto/corelib/global
parenta1dd9a9f7719b9e6e4cd00330967a33f1b429e70 (diff)
Short live q20::to_address!
An implementation of C++20 std::to_address, a prerequesite for QSpan<>. The test cases are inspired by libstdc++'s test suite, just to avoid missing some cases, but the to_address implementation is white-room. Fixes: QTBUG-108430 Change-Id: I4c092fdd7a56c0b279068e341bbf91a725ca3b1f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/global')
-rw-r--r--tests/auto/corelib/global/CMakeLists.txt1
-rw-r--r--tests/auto/corelib/global/q20/CMakeLists.txt1
-rw-r--r--tests/auto/corelib/global/q20/memory/CMakeLists.txt10
-rw-r--r--tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp161
4 files changed, 173 insertions, 0 deletions
diff --git a/tests/auto/corelib/global/CMakeLists.txt b/tests/auto/corelib/global/CMakeLists.txt
index 68574c396d..2204f82ba3 100644
--- a/tests/auto/corelib/global/CMakeLists.txt
+++ b/tests/auto/corelib/global/CMakeLists.txt
@@ -21,3 +21,4 @@ add_subdirectory(qglobalstatic)
add_subdirectory(qhooks)
add_subdirectory(qoperatingsystemversion)
add_subdirectory(qxp)
+add_subdirectory(q20)
diff --git a/tests/auto/corelib/global/q20/CMakeLists.txt b/tests/auto/corelib/global/q20/CMakeLists.txt
new file mode 100644
index 0000000000..bd28f8b999
--- /dev/null
+++ b/tests/auto/corelib/global/q20/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(memory)
diff --git a/tests/auto/corelib/global/q20/memory/CMakeLists.txt b/tests/auto/corelib/global/q20/memory/CMakeLists.txt
new file mode 100644
index 0000000000..f928f75b7a
--- /dev/null
+++ b/tests/auto/corelib/global/q20/memory/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_test(tst_q20_memory
+ EXCEPTIONS
+ SOURCES
+ tst_q20_memory.cpp
+ LIBRARIES
+ Qt::Core
+)
diff --git a/tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp b/tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp
new file mode 100644
index 0000000000..e6da7b5cf8
--- /dev/null
+++ b/tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp
@@ -0,0 +1,161 @@
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+
+#include <q20memory.h>
+#include <QtCore/q20memory.h>
+
+#include <QTest>
+#include <QObject>
+#include <QExplicitlySharedDataPointer>
+#include <QSharedDataPointer>
+
+struct Private : QSharedData {};
+
+class tst_q20_memory : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void raw();
+ void smart();
+ void recursion();
+ void usesPointerTraits();
+ void prefersPointerTraits();
+
+private Q_SLOTS:
+ void to_address_broken_const_propagation_QExplicitlySharedDataPointer()
+ { to_address_broken_const_propagation<QExplicitlySharedDataPointer<Private>>(); }
+ void to_address_broken_const_propagation_QSharedDataPointer()
+ { to_address_broken_const_propagation<QSharedDataPointer<Private>>(); }
+ void to_address_broken_const_propagation_shared_ptr()
+ { to_address_broken_const_propagation<std::shared_ptr<Private>>(); }
+ void to_address_broken_const_propagation_unique_ptr()
+ { to_address_broken_const_propagation<std::unique_ptr<Private>>(); }
+
+private:
+ template <typename Pointer>
+ void to_address_broken_const_propagation();
+};
+
+void tst_q20_memory::raw()
+{
+ auto i = 0;
+ auto p = &i;
+ QVERIFY(q20::to_address(p) == &i);
+}
+
+template <typename T>
+class MinimalPtr {
+public:
+ using element_type = T;
+
+ explicit MinimalPtr(T *d) : d(d) {}
+
+ T *operator->() const noexcept { return d; }
+
+private:
+ T *d;
+};
+
+void tst_q20_memory::smart()
+{
+ int i;
+ MinimalPtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename T>
+class RecursivePtr {
+public:
+ using element_type = T;
+
+ explicit RecursivePtr(T *d) : d(d) {}
+
+ MinimalPtr<T> operator->() const noexcept { return d; }
+
+private:
+ MinimalPtr<T> d;
+};
+
+void tst_q20_memory::recursion()
+{
+ int i;
+ RecursivePtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename T>
+class NoDerefOperatorPtr {
+public:
+ using element_type = T;
+
+ explicit NoDerefOperatorPtr(T *d) : d(d) {}
+
+ T *get() const noexcept { return d; }
+
+private:
+ T *d;
+};
+
+namespace std {
+template <typename T>
+struct pointer_traits<NoDerefOperatorPtr<T>>
+{
+ static T *to_address(const NoDerefOperatorPtr<T> &ptr) noexcept { return ptr.get(); }
+};
+} // namespace std
+
+void tst_q20_memory::usesPointerTraits()
+{
+ int i;
+ NoDerefOperatorPtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename T>
+class PrefersPointerTraitsPtr
+{
+public:
+ using element_type = T;
+
+ explicit PrefersPointerTraitsPtr(T *d) : d(d) {}
+
+ T *operator->() const noexcept { return nullptr; }
+
+ T *get() const noexcept { return d; }
+
+private:
+ T *d;
+};
+
+namespace std {
+template <typename T>
+struct pointer_traits<PrefersPointerTraitsPtr<T>>
+{
+ static T *to_address(const PrefersPointerTraitsPtr<T> &p) noexcept { return p.get(); }
+};
+} // namespace std
+
+void tst_q20_memory::prefersPointerTraits()
+{
+ int i;
+ PrefersPointerTraitsPtr ptr(&i);
+ QCOMPARE_EQ(q20::to_address(ptr), &i);
+}
+
+template <typename Pointer>
+void tst_q20_memory::to_address_broken_const_propagation()
+{
+ Pointer p(nullptr);
+ QCOMPARE_EQ(q20::to_address(p), nullptr);
+ p = Pointer{new Private()};
+ QCOMPARE_EQ(q20::to_address(p), p.operator->());
+ static_assert(std::is_same_v<decltype(q20::to_address(p)),
+ decltype(std::as_const(p).operator->())>);
+}
+
+QTEST_GUILESS_MAIN(tst_q20_memory)
+#include "tst_q20_memory.moc"
+