summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2021-02-24 19:44:09 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2021-02-25 16:08:44 +0100
commit0e22001a3bb070d4e9956e89543ec0e5ac6f23f8 (patch)
tree54904ff96f88f3bebb98e59b308d30daf9cb02d3 /src
parent2af45d0cee253a6bc4e6807076445439cc69c2ce (diff)
Add more support for structured bindings
After QPoint(F), it's now the time of QSize(F) and QVectorND, which can be unambiguously decomposed. [ChangeLog][QtCore][QSize] QSize is now usable in a structured binding declaration. [ChangeLog][QtCore][QSizeF] QSizeF is now usable in a structured binding declaration. [ChangeLog][QtGui][QVector2D] QVector2D is now usable in a structured binding declaration. [ChangeLog][QtGui][QVector3D] QVector3D is now usable in a structured binding declaration. [ChangeLog][QtGui][QVector4D] QVector4D is now usable in a structured binding declaration. Change-Id: I67bb152f4210f2be27607179cd2ec522174cc483 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qsize.h44
-rw-r--r--src/gui/math3d/qvectornd.h79
2 files changed, 123 insertions, 0 deletions
diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h
index 23b4396d79..bab193031c 100644
--- a/src/corelib/tools/qsize.h
+++ b/src/corelib/tools/qsize.h
@@ -112,6 +112,18 @@ public:
private:
int wd;
int ht;
+
+ template <std::size_t I,
+ typename S,
+ std::enable_if_t<(I < 2), bool> = true,
+ std::enable_if_t<std::is_same_v<std::decay_t<S>, QSize>, bool> = true>
+ friend constexpr decltype(auto) get(S &&s) noexcept
+ {
+ if constexpr (I == 0)
+ return (std::forward<S>(s).wd);
+ else if constexpr (I == 1)
+ return (std::forward<S>(s).ht);
+ }
};
Q_DECLARE_TYPEINFO(QSize, Q_RELOCATABLE_TYPE);
@@ -289,6 +301,18 @@ public:
private:
qreal wd;
qreal ht;
+
+ template <std::size_t I,
+ typename S,
+ std::enable_if_t<(I < 2), bool> = true,
+ std::enable_if_t<std::is_same_v<std::decay_t<S>, QSizeF>, bool> = true>
+ friend constexpr decltype(auto) get(S &&s) noexcept
+ {
+ if constexpr (I == 0)
+ return (std::forward<S>(s).wd);
+ else if constexpr (I == 1)
+ return (std::forward<S>(s).ht);
+ }
};
Q_DECLARE_TYPEINFO(QSizeF, Q_RELOCATABLE_TYPE);
@@ -402,4 +426,24 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QSizeF &);
QT_END_NAMESPACE
+/*****************************************************************************
+ QSize/QSizeF tuple protocol
+ *****************************************************************************/
+
+namespace std {
+ template <>
+ class tuple_size<QT_PREPEND_NAMESPACE(QSize)> : public integral_constant<size_t, 2> {};
+ template <>
+ class tuple_element<0, QT_PREPEND_NAMESPACE(QSize)> { public: using type = int; };
+ template <>
+ class tuple_element<1, QT_PREPEND_NAMESPACE(QSize)> { public: using type = int; };
+
+ template <>
+ class tuple_size<QT_PREPEND_NAMESPACE(QSizeF)> : public integral_constant<size_t, 2> {};
+ template <>
+ class tuple_element<0, QT_PREPEND_NAMESPACE(QSizeF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
+ template <>
+ class tuple_element<1, QT_PREPEND_NAMESPACE(QSizeF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
+}
+
#endif // QSIZE_H
diff --git a/src/gui/math3d/qvectornd.h b/src/gui/math3d/qvectornd.h
index 153f3743d8..dec98bd936 100644
--- a/src/gui/math3d/qvectornd.h
+++ b/src/gui/math3d/qvectornd.h
@@ -177,6 +177,18 @@ private:
friend class QVector3D;
friend class QVector4D;
+
+ template <std::size_t I,
+ typename V,
+ std::enable_if_t<(I < 2), bool> = true,
+ std::enable_if_t<std::is_same_v<std::decay_t<V>, QVector2D>, bool> = true>
+ friend constexpr decltype(auto) get(V &&vec) noexcept
+ {
+ if constexpr (I == 0)
+ return (std::forward<V>(vec).v[0]);
+ else if constexpr (I == 1)
+ return (std::forward<V>(vec).v[1]);
+ }
};
Q_DECLARE_TYPEINFO(QVector2D, Q_PRIMITIVE_TYPE);
@@ -327,6 +339,20 @@ private:
friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix);
friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector);
#endif
+
+ template <std::size_t I,
+ typename V,
+ std::enable_if_t<(I < 3), bool> = true,
+ std::enable_if_t<std::is_same_v<std::decay_t<V>, QVector3D>, bool> = true>
+ friend constexpr decltype(auto) get(V &&vec) noexcept
+ {
+ if constexpr (I == 0)
+ return (std::forward<V>(vec).v[0]);
+ else if constexpr (I == 1)
+ return (std::forward<V>(vec).v[1]);
+ else if constexpr (I == 2)
+ return (std::forward<V>(vec).v[2]);
+ }
};
Q_DECLARE_TYPEINFO(QVector3D, Q_PRIMITIVE_TYPE);
@@ -470,6 +496,22 @@ private:
friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix);
friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector);
#endif
+
+ template <std::size_t I,
+ typename V,
+ std::enable_if_t<(I < 4), bool> = true,
+ std::enable_if_t<std::is_same_v<std::decay_t<V>, QVector4D>, bool> = true>
+ friend constexpr decltype(auto) get(V &&vec) noexcept
+ {
+ if constexpr (I == 0)
+ return (std::forward<V>(vec).v[0]);
+ else if constexpr (I == 1)
+ return (std::forward<V>(vec).v[1]);
+ else if constexpr (I == 2)
+ return (std::forward<V>(vec).v[2]);
+ else if constexpr (I == 3)
+ return (std::forward<V>(vec).v[3]);
+ }
};
Q_DECLARE_TYPEINFO(QVector4D, Q_PRIMITIVE_TYPE);
@@ -1050,4 +1092,41 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector4D &);
QT_END_NAMESPACE
+/***************************** Tuple protocol *****************************/
+
+namespace std {
+#ifndef QT_NO_VECTOR2D
+ template <>
+ class tuple_size<QT_PREPEND_NAMESPACE(QVector2D)> : public integral_constant<size_t, 2> {};
+ template <>
+ class tuple_element<0, QT_PREPEND_NAMESPACE(QVector2D)> { public: using type = float; };
+ template <>
+ class tuple_element<1, QT_PREPEND_NAMESPACE(QVector2D)> { public: using type = float; };
+#endif // QT_NO_VECTOR2D
+
+#ifndef QT_NO_VECTOR3D
+ template <>
+ class tuple_size<QT_PREPEND_NAMESPACE(QVector3D)> : public integral_constant<size_t, 3> {};
+ template <>
+ class tuple_element<0, QT_PREPEND_NAMESPACE(QVector3D)> { public: using type = float; };
+ template <>
+ class tuple_element<1, QT_PREPEND_NAMESPACE(QVector3D)> { public: using type = float; };
+ template <>
+ class tuple_element<2, QT_PREPEND_NAMESPACE(QVector3D)> { public: using type = float; };
+#endif // QT_NO_VECTOR3D
+
+#ifndef QT_NO_VECTOR4D
+ template <>
+ class tuple_size<QT_PREPEND_NAMESPACE(QVector4D)> : public integral_constant<size_t, 4> {};
+ template <>
+ class tuple_element<0, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
+ template <>
+ class tuple_element<1, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
+ template <>
+ class tuple_element<2, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
+ template <>
+ class tuple_element<3, QT_PREPEND_NAMESPACE(QVector4D)> { public: using type = float; };
+#endif // QT_NO_VECTOR4D
+}
+
#endif // QVECTORND_H