diff options
Diffstat (limited to 'tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp')
-rw-r--r-- | tests/auto/corelib/global/q20/memory/tst_q20_memory.cpp | 161 |
1 files changed, 161 insertions, 0 deletions
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..22dbb09e7c --- /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 + + +#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" + |