QtBase  v6.3.1
tst_qpair.cpp
Go to the documentation of this file.
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 <QTest>
30 
31 #include <QPair>
32 #include <QSize>
33 
34 class tst_QPair : public QObject
35 {
36  Q_OBJECT
37 private Q_SLOTS:
38  void pairOfReferences();
39  void structuredBindings();
40  void testConstexpr();
41  void testConversions();
42  void taskQTBUG_48780_pairContainingCArray();
43  void testDeductionRules();
44 };
45 
46 class C { C() {} ~C() {} Q_DECL_UNUSED_MEMBER char _[4]; };
47 class M { M() {} Q_DECL_UNUSED_MEMBER char _[4]; };
48 class P { Q_DECL_UNUSED_MEMBER char _[4]; };
49 
54 
55 // avoid the comma:
65 
66 static_assert( QTypeInfo<QPairCC>::isComplex);
67 static_assert( !QTypeInfo<QPairCC>::isRelocatable );
68 
69 static_assert( QTypeInfo<QPairCM>::isComplex);
70 static_assert( !QTypeInfo<QPairCM>::isRelocatable );
71 
72 static_assert( QTypeInfo<QPairCP>::isComplex);
73 static_assert( !QTypeInfo<QPairCP>::isRelocatable );
74 
75 static_assert( QTypeInfo<QPairMC>::isComplex);
76 static_assert( !QTypeInfo<QPairMC>::isRelocatable );
77 
78 static_assert( QTypeInfo<QPairMM>::isComplex);
79 static_assert( QTypeInfo<QPairMM>::isRelocatable );
80 
81 static_assert( QTypeInfo<QPairMP>::isComplex);
82 static_assert( QTypeInfo<QPairMP>::isRelocatable );
83 
84 static_assert( QTypeInfo<QPairPC>::isComplex);
85 static_assert( !QTypeInfo<QPairPC>::isRelocatable );
86 
87 static_assert( QTypeInfo<QPairPM>::isComplex);
88 static_assert( QTypeInfo<QPairPM>::isRelocatable );
89 
90 static_assert(!QTypeInfo<QPairPP>::isComplex);
91 static_assert( QTypeInfo<QPairPP>::isRelocatable );
92 
93 static_assert(!QTypeInfo<QPairPP>::isPointer);
94 
95 
96 void tst_QPair::pairOfReferences()
97 {
98  int i = 0;
99  QString s;
100 
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 
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 
125 void tst_QPair::structuredBindings()
126 {
127  using PV = QPair<int, QString>;
128  using PR = QPair<int&, const QString&>;
129 
130  {
131  PV pv = {42, "Hello"};
132  PR pr = {pv.first, pv.second};
133 
134  auto [fv, sv] = pv;
135 
136  fv = 24;
137  sv = "World";
138  QCOMPARE(fv, 24);
139  QCOMPARE(sv, "World");
140  QCOMPARE(pv.first, 42);
141  QCOMPARE(pv.second, "Hello");
142 
143  auto [fr, sr] = pr;
144 
145  fr = 2424;
146  // sr = "World"; // const
147  QCOMPARE(fr, 2424);
148  QCOMPARE(pv.first, 2424);
149  }
150 
151  {
152  PV pv = {42, "Hello"};
153  PR pr = {pv.first, pv.second};
154 
155  auto& [fv, sv] = pv;
156 
157  fv = 24;
158  sv = "World";
159  QCOMPARE(fv, 24);
160  QCOMPARE(sv, "World");
161  QCOMPARE(pv.first, 24);
162  QCOMPARE(pv.second, "World");
163 
164  auto& [fr, sr] = pr;
165 
166  fr = 4242;
167  //sr = "2World"; // const
168 
169  QCOMPARE(fr, 4242);
170  QCOMPARE(pr.first, 4242);
171  QCOMPARE(pv.first, 4242);
172  }
173 }
174 
175 void tst_QPair::testConstexpr()
176 {
177  constexpr QPair<int, double> pID = qMakePair(0, 0.0);
178  Q_UNUSED(pID);
179 
180  constexpr QPair<double, double> pDD = qMakePair(0.0, 0.0);
181  constexpr QPair<double, double> pDD2 = qMakePair(0, 0.0); // involes (rvalue) conversion ctor
182  constexpr bool equal = pDD2 == pDD;
183  QVERIFY(equal);
184 
185  constexpr QPair<QSize, int> pSI = qMakePair(QSize(4, 5), 6);
186  Q_UNUSED(pSI);
187 }
188 
189 void tst_QPair::testConversions()
190 {
191  // construction from lvalue:
192  {
193  const QPair<int, double> rhs(42, 4.5);
194  const QPair<int, int> pii = rhs;
195  QCOMPARE(pii.first, 42);
196  QCOMPARE(pii.second, 4);
197 
198  const QPair<int, float> pif = rhs;
199  QCOMPARE(pif.first, 42);
200  QCOMPARE(pif.second, 4.5f);
201  }
202 
203  // assignment from lvalue:
204  {
205  const QPair<int, double> rhs(42, 4.5);
206  QPair<int, int> pii;
207  pii = rhs;
208  QCOMPARE(pii.first, 42);
209  QCOMPARE(pii.second, 4);
210 
211  QPair<int, float> pif;
212  pif = rhs;
213  QCOMPARE(pif.first, 42);
214  QCOMPARE(pif.second, 4.5f);
215  }
216 
217  // construction from rvalue:
218  {
219 #define rhs qMakePair(42, 4.5)
220  const QPair<int, int> pii = rhs;
221  QCOMPARE(pii.first, 42);
222  QCOMPARE(pii.second, 4);
223 
224  const QPair<int, float> pif = rhs;
225  QCOMPARE(pif.first, 42);
226  QCOMPARE(pif.second, 4.5f);
227 #undef rhs
228  }
229 
230  // assignment from rvalue:
231  {
232 #define rhs qMakePair(42, 4.5)
233  QPair<int, int> pii;
234  pii = rhs;
235  QCOMPARE(pii.first, 42);
236  QCOMPARE(pii.second, 4);
237 
238  QPair<int, float> pif;
239  pif = rhs;
240  QCOMPARE(pif.first, 42);
241  QCOMPARE(pif.second, 4.5f);
242 #undef rhs
243  }
244 }
245 
246 void tst_QPair::taskQTBUG_48780_pairContainingCArray()
247 {
248  // compile-only:
249  QPair<int[2], int> pair;
250  pair.first[0] = 0;
251  pair.first[1] = 1;
252  pair.second = 2;
253  Q_UNUSED(pair);
254 }
255 
256 void tst_QPair::testDeductionRules()
257 {
258 #if defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201907L
259  QPair p1{1, 2};
260  static_assert(std::is_same<decltype(p1)::first_type, decltype(1)>::value);
261  static_assert(std::is_same<decltype(p1)::second_type, decltype(2)>::value);
262  QCOMPARE(p1.first, 1);
263  QCOMPARE(p1.second, 2);
264 
265  QPair p2{QString("string"), 2};
266  static_assert(std::is_same<decltype(p2)::first_type, QString>::value);
267  static_assert(std::is_same<decltype(p2)::second_type, decltype(2)>::value);
268  QCOMPARE(p2.first, "string");
269  QCOMPARE(p2.second, 2);
270 
271  QPair p3(p2);
272  static_assert(std::is_same<decltype(p3)::first_type, decltype(p2)::first_type>::value);
273  static_assert(std::is_same<decltype(p3)::second_type, decltype(p2)::second_type>::value);
274  QCOMPARE(p3.first, "string");
275  QCOMPARE(p3.second, 2);
276 #else
277  QSKIP("Unsupported (requires C++20's CTAD for aliases)");
278 #endif
279 }
280 
282 #include "tst_qpair.moc"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
C()=default
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
The QString class provides a Unicode character string.
Definition: qstring.h:388
QPixmap p2
QPixmap p1
[0]
QCOMPARE(spy.count(), 1)
#define QString()
Definition: parse-defines.h:51
#define Q_DECL_UNUSED_MEMBER
std::pair< T1, T2 > QPair
Definition: qcontainerfwd.h:56
EGLOutputLayerEXT EGLint EGLAttrib value
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition: qpair.h:55
#define QTEST_APPLESS_MAIN(TestObject)
Definition: qtest.h:632
#define QSKIP(statement,...)
Definition: qtestcase.h:222
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define Q_SLOTS
Definition: qtmetamacros.h:80
@ Q_PRIMITIVE_TYPE
Definition: qtypeinfo.h:155
@ Q_RELOCATABLE_TYPE
Definition: qtypeinfo.h:156
Q_UNUSED(salary)
[21]
#define rhs
QPair< C, M > QPairCM
Definition: tst_qpair.cpp:57
QPair< M, P > QPairMP
Definition: tst_qpair.cpp:61
QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(M, Q_RELOCATABLE_TYPE)
QPair< M, M > QPairMM
Definition: tst_qpair.cpp:60
QPair< P, M > QPairPM
Definition: tst_qpair.cpp:63
QPair< P, C > QPairPC
Definition: tst_qpair.cpp:62
QT_END_NAMESPACE typedef QPair< C, C > QPairCC
Definition: tst_qpair.cpp:56
QPair< M, C > QPairMC
Definition: tst_qpair.cpp:59
QPair< P, P > QPairPP
Definition: tst_qpair.cpp:64
QPair< C, P > QPairCP
Definition: tst_qpair.cpp:58