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 | */ |
40 | class tst_QExplicitlySharedDataPointer : public QObject |
41 | { |
42 | Q_OBJECT |
43 | |
44 | private 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 | |
54 | class MyClass : public QSharedData |
55 | { |
56 | public: |
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 | |
71 | class Base : public QSharedData |
72 | { |
73 | public: |
74 | virtual ~Base() { } |
75 | virtual Base *clone() { return new Base(*this); } |
76 | virtual bool isBase() const { return true; } |
77 | }; |
78 | |
79 | class Derived : public Base |
80 | { |
81 | public: |
82 | virtual Base *clone() { return new Derived(*this); } |
83 | virtual bool isBase() const { return false; } |
84 | }; |
85 | |
86 | QT_BEGIN_NAMESPACE |
87 | template<> Base *QExplicitlySharedDataPointer<Base>::clone() |
88 | { |
89 | return d->clone(); |
90 | } |
91 | QT_END_NAMESPACE |
92 | |
93 | void 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 | |
108 | void 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 | |
127 | void tst_QExplicitlySharedDataPointer::copyConstructor() const |
128 | { |
129 | const QExplicitlySharedDataPointer<const MyClass> pointer(new MyClass()); |
130 | const QExplicitlySharedDataPointer<const MyClass> copy(pointer); |
131 | } |
132 | |
133 | void 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 | |
156 | void 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 | |
208 | void 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 | |
229 | void 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 | |
248 | QTEST_MAIN(tst_QExplicitlySharedDataPointer) |
249 | |
250 | #include "tst_qexplicitlyshareddatapointer.moc" |
251 | // vim: et:ts=4:sw=4:sts=4 |
252 |