1/****************************************************************************
2**
3** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
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#include <QtTest/QtTest>
30
31#include <QPair>
32#include <QSize>
33
34class tst_QPair : public QObject
35{
36 Q_OBJECT
37private Q_SLOTS:
38 void pairOfReferences();
39 void testConstexpr();
40 void testConversions();
41 void taskQTBUG_48780_pairContainingCArray();
42 void testDeducationRules();
43};
44
45class C { C() {} char _[4]; };
46class M { M() {} char _[4]; };
47class P { char _[4]; };
48
49QT_BEGIN_NAMESPACE
50Q_DECLARE_TYPEINFO(M, Q_MOVABLE_TYPE);
51Q_DECLARE_TYPEINFO(P, Q_PRIMITIVE_TYPE);
52QT_END_NAMESPACE
53
54// avoid the comma:
55typedef QPair<C,C> QPairCC;
56typedef QPair<C,M> QPairCM;
57typedef QPair<C,P> QPairCP;
58typedef QPair<M,C> QPairMC;
59typedef QPair<M,M> QPairMM;
60typedef QPair<M,P> QPairMP;
61typedef QPair<P,C> QPairPC;
62typedef QPair<P,M> QPairPM;
63typedef QPair<P,P> QPairPP;
64
65Q_STATIC_ASSERT( QTypeInfo<QPairCC>::isComplex);
66Q_STATIC_ASSERT( QTypeInfo<QPairCC>::isStatic );
67
68Q_STATIC_ASSERT( QTypeInfo<QPairCM>::isComplex);
69Q_STATIC_ASSERT( QTypeInfo<QPairCM>::isStatic );
70
71Q_STATIC_ASSERT( QTypeInfo<QPairCP>::isComplex);
72Q_STATIC_ASSERT( QTypeInfo<QPairCP>::isStatic );
73
74Q_STATIC_ASSERT( QTypeInfo<QPairMC>::isComplex);
75Q_STATIC_ASSERT( QTypeInfo<QPairMC>::isStatic );
76
77Q_STATIC_ASSERT( QTypeInfo<QPairMM>::isComplex);
78Q_STATIC_ASSERT(!QTypeInfo<QPairMM>::isStatic );
79
80Q_STATIC_ASSERT( QTypeInfo<QPairMP>::isComplex);
81Q_STATIC_ASSERT(!QTypeInfo<QPairMP>::isStatic );
82
83Q_STATIC_ASSERT( QTypeInfo<QPairPC>::isComplex);
84Q_STATIC_ASSERT( QTypeInfo<QPairPC>::isStatic );
85
86Q_STATIC_ASSERT( QTypeInfo<QPairPM>::isComplex);
87Q_STATIC_ASSERT(!QTypeInfo<QPairPM>::isStatic );
88
89Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isComplex);
90Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isStatic );
91
92Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isDummy );
93Q_STATIC_ASSERT(!QTypeInfo<QPairPP>::isPointer);
94
95
96void tst_QPair::pairOfReferences()
97{
98 int i = 0;
99 QString s;
100
101 QPair<int&, QString&> p(i, s);
102
103 p.first = 1;
104 QCOMPARE(i, 1);
105
106 i = 2;
107 QCOMPARE(p.first, 2);
108
109 p.second = QLatin1String("Hello");
110 QCOMPARE(s, QLatin1String("Hello"));
111
112 s = QLatin1String("olleH");
113 QCOMPARE(p.second, QLatin1String("olleH"));
114
115 QPair<int&, QString&> q = p;
116 q.first = 3;
117 QCOMPARE(i, 3);
118 QCOMPARE(p.first, 3);
119
120 q.second = QLatin1String("World");
121 QCOMPARE(s, QLatin1String("World"));
122 QCOMPARE(p.second, QLatin1String("World"));
123}
124
125void tst_QPair::testConstexpr()
126{
127 Q_CONSTEXPR QPair<int, double> pID = qMakePair(x: 0, y: 0.0);
128 Q_UNUSED(pID);
129
130 Q_CONSTEXPR QPair<double, double> pDD = qMakePair(x: 0.0, y: 0.0);
131 Q_CONSTEXPR QPair<double, double> pDD2 = qMakePair(x: 0, y: 0.0); // involes (rvalue) conversion ctor
132 Q_CONSTEXPR bool equal = pDD2 == pDD;
133 QVERIFY(equal);
134
135 Q_CONSTEXPR QPair<QSize, int> pSI = qMakePair(x: QSize(4, 5), y: 6);
136 Q_UNUSED(pSI);
137}
138
139void tst_QPair::testConversions()
140{
141 // construction from lvalue:
142 {
143 const QPair<int, double> rhs(42, 4.5);
144 const QPair<int, int> pii = rhs;
145 QCOMPARE(pii.first, 42);
146 QCOMPARE(pii.second, 4);
147
148 const QPair<int, float> pif = rhs;
149 QCOMPARE(pif.first, 42);
150 QCOMPARE(pif.second, 4.5f);
151 }
152
153 // assignment from lvalue:
154 {
155 const QPair<int, double> rhs(42, 4.5);
156 QPair<int, int> pii;
157 pii = rhs;
158 QCOMPARE(pii.first, 42);
159 QCOMPARE(pii.second, 4);
160
161 QPair<int, float> pif;
162 pif = rhs;
163 QCOMPARE(pif.first, 42);
164 QCOMPARE(pif.second, 4.5f);
165 }
166
167 // construction from rvalue:
168 {
169#define rhs qMakePair(42, 4.5)
170 const QPair<int, int> pii = rhs;
171 QCOMPARE(pii.first, 42);
172 QCOMPARE(pii.second, 4);
173
174 const QPair<int, float> pif = rhs;
175 QCOMPARE(pif.first, 42);
176 QCOMPARE(pif.second, 4.5f);
177#undef rhs
178 }
179
180 // assignment from rvalue:
181 {
182#define rhs qMakePair(42, 4.5)
183 QPair<int, int> pii;
184 pii = rhs;
185 QCOMPARE(pii.first, 42);
186 QCOMPARE(pii.second, 4);
187
188 QPair<int, float> pif;
189 pif = rhs;
190 QCOMPARE(pif.first, 42);
191 QCOMPARE(pif.second, 4.5f);
192#undef rhs
193 }
194}
195
196void tst_QPair::taskQTBUG_48780_pairContainingCArray()
197{
198 // compile-only:
199 QPair<int[2], int> pair;
200 pair.first[0] = 0;
201 pair.first[1] = 1;
202 pair.second = 2;
203 Q_UNUSED(pair);
204}
205
206void tst_QPair::testDeducationRules()
207{
208#if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201606
209 QPair p1{1, 2};
210 static_assert(std::is_same<decltype(p1)::first_type, decltype(1)>::value);
211 static_assert(std::is_same<decltype(p1)::second_type, decltype(2)>::value);
212 QCOMPARE(p1.first, 1);
213 QCOMPARE(p1.second, 2);
214
215 QPair p2{QString("string"), 2};
216 static_assert(std::is_same<decltype(p2)::first_type, QString>::value);
217 static_assert(std::is_same<decltype(p2)::second_type, decltype(2)>::value);
218 QCOMPARE(p2.first, "string");
219 QCOMPARE(p2.second, 2);
220
221 QPair p3(p2);
222 static_assert(std::is_same<decltype(p3)::first_type, decltype(p2)::first_type>::value);
223 static_assert(std::is_same<decltype(p3)::second_type, decltype(p2)::second_type>::value);
224 QCOMPARE(p3.first, "string");
225 QCOMPARE(p3.second, 2);
226#else
227 QSKIP("Unsupported");
228#endif
229}
230
231QTEST_APPLESS_MAIN(tst_QPair)
232#include "tst_qpair.moc"
233

source code of qtbase/tests/auto/corelib/tools/qpair/tst_qpair.cpp