1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31#include <QtCore/QSharedData>
32
33/*!
34 \class tst_QExplicitlySharedDataPointer
35 \internal
36 \since 4.4
37 \brief Tests class QExplicitlySharedDataPointer.
38
39 */
40class tst_QExplicitlySharedDataPointer : public QObject
41{
42 Q_OBJECT
43
44private Q_SLOTS:
45 void pointerOperatorOnConst() const;
46 void pointerOperatorOnMutable() const;
47 void copyConstructor() const;
48 void clone() const;
49 void data() const;
50 void reset() const;
51 void swap() const;
52};
53
54class MyClass : public QSharedData
55{
56public:
57 void mutating()
58 {
59 }
60
61 void notMutating() const
62 {
63 }
64
65 MyClass &operator=(const MyClass &)
66 {
67 return *this;
68 }
69};
70
71class Base : public QSharedData
72{
73public:
74 virtual ~Base() { }
75 virtual Base *clone() { return new Base(*this); }
76 virtual bool isBase() const { return true; }
77};
78
79class Derived : public Base
80{
81public:
82 virtual Base *clone() { return new Derived(*this); }
83 virtual bool isBase() const { return false; }
84};
85
86QT_BEGIN_NAMESPACE
87template<> Base *QExplicitlySharedDataPointer<Base>::clone()
88{
89 return d->clone();
90}
91QT_END_NAMESPACE
92
93void tst_QExplicitlySharedDataPointer::pointerOperatorOnConst() const
94{
95 /* Pointer itself is const. */
96 {
97 const QExplicitlySharedDataPointer<const MyClass> pointer(new MyClass());
98 pointer->notMutating();
99 }
100
101 /* Pointer itself is mutable. */
102 {
103 QExplicitlySharedDataPointer<const MyClass> pointer(new MyClass());
104 pointer->notMutating();
105 }
106}
107
108void tst_QExplicitlySharedDataPointer::pointerOperatorOnMutable() const
109{
110 /* Pointer itself is const. */
111 {
112 const QExplicitlySharedDataPointer<MyClass> pointer(new MyClass());
113 pointer->notMutating();
114 pointer->mutating();
115 *pointer = MyClass();
116 }
117
118 /* Pointer itself is mutable. */
119 {
120 const QExplicitlySharedDataPointer<MyClass> pointer(new MyClass());
121 pointer->notMutating();
122 pointer->mutating();
123 *pointer = MyClass();
124 }
125}
126
127void tst_QExplicitlySharedDataPointer::copyConstructor() const
128{
129 const QExplicitlySharedDataPointer<const MyClass> pointer(new MyClass());
130 const QExplicitlySharedDataPointer<const MyClass> copy(pointer);
131}
132
133void tst_QExplicitlySharedDataPointer::clone() const
134{
135 /* holding a base element */
136 {
137 QExplicitlySharedDataPointer<Base> pointer(new Base);
138 QVERIFY(pointer->isBase());
139
140 QExplicitlySharedDataPointer<Base> copy(pointer);
141 pointer.detach();
142 QVERIFY(pointer->isBase());
143 }
144
145 /* holding a derived element */
146 {
147 QExplicitlySharedDataPointer<Base> pointer(new Derived);
148 QVERIFY(!pointer->isBase());
149
150 QExplicitlySharedDataPointer<Base> copy(pointer);
151 pointer.detach();
152 QVERIFY(!pointer->isBase());
153 }
154}
155
156void tst_QExplicitlySharedDataPointer::data() const
157{
158 /* Check default value. */
159 {
160 QExplicitlySharedDataPointer<const MyClass> pointer;
161 QCOMPARE(pointer.data(), static_cast<const MyClass *>(0));
162 QVERIFY(pointer == nullptr);
163 QVERIFY(nullptr == pointer);
164 }
165
166 /* On const pointer. Must not mutate the pointer. */
167 {
168 const QExplicitlySharedDataPointer<const MyClass> pointer(new MyClass());
169 pointer.data();
170
171 /* Check that this cast is possible. */
172 static_cast<const MyClass *>(pointer.data());
173
174 QVERIFY(! (pointer == nullptr));
175 QVERIFY(! (nullptr == pointer));
176 }
177
178 /* On mutatable pointer. Must not mutate the pointer. */
179 {
180 QExplicitlySharedDataPointer<const MyClass> pointer(new MyClass());
181 pointer.data();
182
183 /* Check that this cast is possible. */
184 static_cast<const MyClass *>(pointer.data());
185 }
186
187 /* Must not mutate the pointer. */
188 {
189 const QExplicitlySharedDataPointer<MyClass> pointer(new MyClass());
190 pointer.data();
191
192 /* Check that these casts are possible. */
193 static_cast<MyClass *>(pointer.data());
194 static_cast<const MyClass *>(pointer.data());
195 }
196
197 /* Must not mutate the pointer. */
198 {
199 QExplicitlySharedDataPointer<MyClass> pointer(new MyClass());
200 pointer.data();
201
202 /* Check that these casts are possible. */
203 static_cast<MyClass *>(pointer.data());
204 static_cast<const MyClass *>(pointer.data());
205 }
206}
207
208void tst_QExplicitlySharedDataPointer::reset() const
209{
210 /* Do reset on a single ref count. */
211 {
212 QExplicitlySharedDataPointer<MyClass> pointer(new MyClass());
213 QVERIFY(pointer.data() != 0);
214
215 pointer.reset();
216 QCOMPARE(pointer.data(), static_cast<MyClass *>(0));
217 }
218
219 /* Do reset on a default constructed object. */
220 {
221 QExplicitlySharedDataPointer<MyClass> pointer;
222 QCOMPARE(pointer.data(), static_cast<MyClass *>(0));
223
224 pointer.reset();
225 QCOMPARE(pointer.data(), static_cast<MyClass *>(0));
226 }
227}
228
229void tst_QExplicitlySharedDataPointer::swap() const
230{
231 QExplicitlySharedDataPointer<MyClass> p1(0), p2(new MyClass());
232 QVERIFY(!p1.data());
233 QVERIFY(p2.data());
234
235 p1.swap(other&: p2);
236 QVERIFY(p1.data());
237 QVERIFY(!p2.data());
238
239 p1.swap(other&: p2);
240 QVERIFY(!p1.data());
241 QVERIFY(p2.data());
242
243 qSwap(value1&: p1, value2&: p2);
244 QVERIFY(p1.data());
245 QVERIFY(!p2.data());
246}
247
248QTEST_MAIN(tst_QExplicitlySharedDataPointer)
249
250#include "tst_qexplicitlyshareddatapointer.moc"
251// vim: et:ts=4:sw=4:sts=4
252

source code of qtbase/tests/auto/corelib/tools/qexplicitlyshareddatapointer/tst_qexplicitlyshareddatapointer.cpp