QPoint(F): add support for structured binding

QPoint(F) are "naturally" destructurable in their x/y
counterparts (hello Mac/Carbon users, we don't live in 1999
any more, it's x and then y, and not vice versa...).

[ChangeLog][QtCore][QPoint] QPoint is usable in a structured
binding.

[ChangeLog][QtCore][QPointF] QPointF is usable in a structured
binding.

Change-Id: I8718a4e80be4ce03f37f012034f1fba009304b32
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Giuseppe D'Angelo 2020-03-19 17:57:05 +01:00
parent 7d5ba1c17e
commit fb6b7869e8
3 changed files with 163 additions and 0 deletions

View File

@ -115,6 +115,18 @@ private:
friend class QTransform;
int xp;
int yp;
template <std::size_t I,
typename P,
std::enable_if_t<(I < 2), bool> = true,
std::enable_if_t<std::is_same_v<std::decay_t<P>, QPoint>, bool> = true>
friend constexpr decltype(auto) get(P &&p) noexcept
{
if constexpr (I == 0)
return (std::forward<P>(p).xp);
else if constexpr (I == 1)
return (std::forward<P>(p).yp);
}
};
Q_DECLARE_TYPEINFO(QPoint, Q_MOVABLE_TYPE);
@ -297,6 +309,18 @@ private:
qreal xp;
qreal yp;
template <std::size_t I,
typename P,
std::enable_if_t<(I < 2), bool> = true,
std::enable_if_t<std::is_same_v<std::decay_t<P>, QPointF>, bool> = true>
friend constexpr decltype(auto) get(P &&p) noexcept
{
if constexpr (I == 0)
return (std::forward<P>(p).xp);
else if constexpr (I == 1)
return (std::forward<P>(p).yp);
}
};
Q_DECLARE_TYPEINFO(QPointF, Q_MOVABLE_TYPE);
@ -398,4 +422,24 @@ Q_CORE_EXPORT QDebug operator<<(QDebug d, const QPointF &p);
QT_END_NAMESPACE
/*****************************************************************************
QPoint/QPointF tuple protocol
*****************************************************************************/
namespace std {
template <>
class tuple_size<QT_PREPEND_NAMESPACE(QPoint)> : public integral_constant<size_t, 2> {};
template <>
class tuple_element<0, QT_PREPEND_NAMESPACE(QPoint)> { public: using type = int; };
template <>
class tuple_element<1, QT_PREPEND_NAMESPACE(QPoint)> { public: using type = int; };
template <>
class tuple_size<QT_PREPEND_NAMESPACE(QPointF)> : public integral_constant<size_t, 2> {};
template <>
class tuple_element<0, QT_PREPEND_NAMESPACE(QPointF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
template <>
class tuple_element<1, QT_PREPEND_NAMESPACE(QPointF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
}
#endif // QPOINT_H

View File

@ -75,6 +75,8 @@ private slots:
void stream_data();
void stream();
#endif
void structuredBinding();
};
void tst_QPoint::isNull()
@ -381,5 +383,62 @@ void tst_QPoint::stream()
}
#endif
void tst_QPoint::structuredBinding()
{
{
QPoint p(1, 2);
auto [x, y] = p;
QCOMPARE(x, 1);
QCOMPARE(y, 2);
p.setX(42);
QCOMPARE(x, 1);
QCOMPARE(y, 2);
p.setY(-123);
QCOMPARE(x, 1);
QCOMPARE(y, 2);
}
{
QPoint p(1, 2);
auto &[x, y] = p;
QCOMPARE(x, 1);
QCOMPARE(y, 2);
x = 42;
QCOMPARE(x, 42);
QCOMPARE(p.x(), 42);
QCOMPARE(p.rx(), 42);
QCOMPARE(y, 2);
QCOMPARE(p.y(), 2);
QCOMPARE(p.ry(), 2);
y = -123;
QCOMPARE(x, 42);
QCOMPARE(p.x(), 42);
QCOMPARE(p.rx(), 42);
QCOMPARE(y, -123);
QCOMPARE(p.y(), -123);
QCOMPARE(p.ry(), -123);
p.setX(0);
QCOMPARE(x, 0);
QCOMPARE(p.x(), 0);
QCOMPARE(p.rx(), 0);
QCOMPARE(y, -123);
QCOMPARE(p.y(), -123);
QCOMPARE(p.ry(), -123);
p.ry() = 10;
QCOMPARE(x, 0);
QCOMPARE(p.x(), 0);
QCOMPARE(p.rx(), 0);
QCOMPARE(y, 10);
QCOMPARE(p.y(), 10);
QCOMPARE(p.ry(), 10);
}
}
QTEST_MAIN(tst_QPoint)
#include "tst_qpoint.moc"

View File

@ -86,6 +86,8 @@ private slots:
void stream();
#endif
void structuredBinding();
private:
const qreal QREAL_MIN;
const qreal QREAL_MAX;
@ -462,5 +464,63 @@ void tst_QPointF::compare()
QVERIFY(QPointF(1.9543e-14, -32.0) == QPointF(0.0, -32.0));
}
void tst_QPointF::structuredBinding()
{
{
QPointF p(1.5, 2.25);
auto [x, y] = p;
QCOMPARE(x, 1.5);
QCOMPARE(y, 2.25);
p.setX(42);
QCOMPARE(x, 1.5);
QCOMPARE(y, 2.25);
p.setY(-123);
QCOMPARE(x, 1.5);
QCOMPARE(y, 2.25);
}
{
QPointF p(1.5, 2.25);
auto &[x, y] = p;
QCOMPARE(x, 1.5);
QCOMPARE(y, 2.25);
x = 42.0;
QCOMPARE(x, 42.0);
QCOMPARE(p.x(), 42.0);
QCOMPARE(p.rx(), 42.0);
QCOMPARE(y, 2.25);
QCOMPARE(p.y(), 2.25);
QCOMPARE(p.ry(), 2.25);
y = -123.5;
QCOMPARE(x, 42.0);
QCOMPARE(p.x(), 42.0);
QCOMPARE(p.rx(), 42.0);
QCOMPARE(y, -123.5);
QCOMPARE(p.y(), -123.5);
QCOMPARE(p.ry(), -123.5);
p.setX(0.0);
QCOMPARE(x, 0.0);
QCOMPARE(p.x(), 0.0);
QCOMPARE(p.rx(), 0.0);
QCOMPARE(y, -123.5);
QCOMPARE(p.y(), -123.5);
QCOMPARE(p.ry(), -123.5);
p.ry() = 10.5;
QCOMPARE(x, 0.0);
QCOMPARE(p.x(), 0.0);
QCOMPARE(p.rx(), 0.0);
QCOMPARE(y, 10.5);
QCOMPARE(p.y(), 10.5);
QCOMPARE(p.ry(), 10.5);
}
}
QTEST_MAIN(tst_QPointF)
#include "tst_qpointf.moc"