1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QPOINT_H
5#define QPOINT_H
6
7#include <QtCore/qnamespace.h>
8
9#include <QtCore/q20type_traits.h>
10#include <QtCore/q23utility.h>
11
12#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
13struct CGPoint;
14#endif
15
16QT_BEGIN_NAMESPACE
17
18QT_ENABLE_P0846_SEMANTICS_FOR(get)
19
20class QPointF;
21
22class QPoint
23{
24public:
25 constexpr QPoint() noexcept;
26 constexpr QPoint(int xpos, int ypos) noexcept;
27
28 constexpr inline bool isNull() const noexcept;
29
30 constexpr inline int x() const noexcept;
31 constexpr inline int y() const noexcept;
32 constexpr inline void setX(int x) noexcept;
33 constexpr inline void setY(int y) noexcept;
34
35 constexpr inline int manhattanLength() const;
36
37 constexpr QPoint transposed() const noexcept { return {yp, xp}; }
38
39 constexpr inline int &rx() noexcept;
40 constexpr inline int &ry() noexcept;
41
42 constexpr inline QPoint &operator+=(const QPoint &p);
43 constexpr inline QPoint &operator-=(const QPoint &p);
44
45 constexpr inline QPoint &operator*=(float factor);
46 constexpr inline QPoint &operator*=(double factor);
47 constexpr inline QPoint &operator*=(int factor);
48
49 constexpr inline QPoint &operator/=(qreal divisor);
50
51 constexpr static inline int dotProduct(const QPoint &p1, const QPoint &p2)
52 { return p1.xp * p2.xp + p1.yp * p2.yp; }
53
54 friend constexpr inline bool operator==(const QPoint &p1, const QPoint &p2) noexcept
55 { return p1.xp == p2.xp && p1.yp == p2.yp; }
56 friend constexpr inline bool operator!=(const QPoint &p1, const QPoint &p2) noexcept
57 { return p1.xp != p2.xp || p1.yp != p2.yp; }
58 friend constexpr inline QPoint operator+(const QPoint &p1, const QPoint &p2) noexcept
59 { return QPoint(p1.xp + p2.xp, p1.yp + p2.yp); }
60 friend constexpr inline QPoint operator-(const QPoint &p1, const QPoint &p2) noexcept
61 { return QPoint(p1.xp - p2.xp, p1.yp - p2.yp); }
62 friend constexpr inline QPoint operator*(const QPoint &p, float factor)
63 { return QPoint(qRound(f: p.xp * factor), qRound(f: p.yp * factor)); }
64 friend constexpr inline QPoint operator*(const QPoint &p, double factor)
65 { return QPoint(qRound(d: p.xp * factor), qRound(d: p.yp * factor)); }
66 friend constexpr inline QPoint operator*(const QPoint &p, int factor) noexcept
67 { return QPoint(p.xp * factor, p.yp * factor); }
68 friend constexpr inline QPoint operator*(float factor, const QPoint &p)
69 { return QPoint(qRound(f: p.xp * factor), qRound(f: p.yp * factor)); }
70 friend constexpr inline QPoint operator*(double factor, const QPoint &p)
71 { return QPoint(qRound(d: p.xp * factor), qRound(d: p.yp * factor)); }
72 friend constexpr inline QPoint operator*(int factor, const QPoint &p) noexcept
73 { return QPoint(p.xp * factor, p.yp * factor); }
74 friend constexpr inline QPoint operator+(const QPoint &p) noexcept
75 { return p; }
76 friend constexpr inline QPoint operator-(const QPoint &p) noexcept
77 { return QPoint(-p.xp, -p.yp); }
78 friend constexpr inline QPoint operator/(const QPoint &p, qreal c)
79 { return QPoint(qRound(d: p.xp / c), qRound(d: p.yp / c)); }
80
81#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
82 [[nodiscard]] Q_CORE_EXPORT CGPoint toCGPoint() const noexcept;
83#endif
84 [[nodiscard]] constexpr inline QPointF toPointF() const noexcept;
85
86private:
87 friend class QTransform;
88 int xp;
89 int yp;
90
91 template <std::size_t I,
92 typename P,
93 std::enable_if_t<(I < 2), bool> = true,
94 std::enable_if_t<std::is_same_v<q20::remove_cvref_t<P>, QPoint>, bool> = true>
95 friend constexpr decltype(auto) get(P &&p) noexcept
96 {
97 if constexpr (I == 0)
98 return q23::forward_like<P>(p.xp);
99 else if constexpr (I == 1)
100 return q23::forward_like<P>(p.yp);
101 }
102};
103
104Q_DECLARE_TYPEINFO(QPoint, Q_PRIMITIVE_TYPE);
105
106/*****************************************************************************
107 QPoint stream functions
108 *****************************************************************************/
109#ifndef QT_NO_DATASTREAM
110Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPoint &);
111Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPoint &);
112#endif
113
114/*****************************************************************************
115 QPoint inline functions
116 *****************************************************************************/
117
118constexpr inline QPoint::QPoint() noexcept : xp(0), yp(0) {}
119
120constexpr inline QPoint::QPoint(int xpos, int ypos) noexcept : xp(xpos), yp(ypos) {}
121
122constexpr inline bool QPoint::isNull() const noexcept
123{
124 return xp == 0 && yp == 0;
125}
126
127constexpr inline int QPoint::x() const noexcept
128{
129 return xp;
130}
131
132constexpr inline int QPoint::y() const noexcept
133{
134 return yp;
135}
136
137constexpr inline void QPoint::setX(int xpos) noexcept
138{
139 xp = xpos;
140}
141
142constexpr inline void QPoint::setY(int ypos) noexcept
143{
144 yp = ypos;
145}
146
147inline int constexpr QPoint::manhattanLength() const
148{
149 return qAbs(t: x()) + qAbs(t: y());
150}
151
152constexpr inline int &QPoint::rx() noexcept
153{
154 return xp;
155}
156
157constexpr inline int &QPoint::ry() noexcept
158{
159 return yp;
160}
161
162constexpr inline QPoint &QPoint::operator+=(const QPoint &p)
163{
164 xp += p.xp;
165 yp += p.yp;
166 return *this;
167}
168
169constexpr inline QPoint &QPoint::operator-=(const QPoint &p)
170{
171 xp -= p.xp;
172 yp -= p.yp;
173 return *this;
174}
175
176constexpr inline QPoint &QPoint::operator*=(float factor)
177{
178 xp = qRound(f: xp * factor);
179 yp = qRound(f: yp * factor);
180 return *this;
181}
182
183constexpr inline QPoint &QPoint::operator*=(double factor)
184{
185 xp = qRound(d: xp * factor);
186 yp = qRound(d: yp * factor);
187 return *this;
188}
189
190constexpr inline QPoint &QPoint::operator*=(int factor)
191{
192 xp = xp * factor;
193 yp = yp * factor;
194 return *this;
195}
196
197constexpr inline QPoint &QPoint::operator/=(qreal c)
198{
199 xp = qRound(d: xp / c);
200 yp = qRound(d: yp / c);
201 return *this;
202}
203
204#ifndef QT_NO_DEBUG_STREAM
205Q_CORE_EXPORT QDebug operator<<(QDebug, const QPoint &);
206#endif
207
208Q_CORE_EXPORT size_t qHash(QPoint key, size_t seed = 0) noexcept;
209
210
211
212
213class QPointF
214{
215public:
216 constexpr QPointF() noexcept;
217 constexpr QPointF(const QPoint &p) noexcept;
218 constexpr QPointF(qreal xpos, qreal ypos) noexcept;
219
220 constexpr inline qreal manhattanLength() const;
221
222 inline bool isNull() const noexcept;
223
224 constexpr inline qreal x() const noexcept;
225 constexpr inline qreal y() const noexcept;
226 constexpr inline void setX(qreal x) noexcept;
227 constexpr inline void setY(qreal y) noexcept;
228
229 constexpr QPointF transposed() const noexcept { return {yp, xp}; }
230
231 constexpr inline qreal &rx() noexcept;
232 constexpr inline qreal &ry() noexcept;
233
234 constexpr inline QPointF &operator+=(const QPointF &p);
235 constexpr inline QPointF &operator-=(const QPointF &p);
236 constexpr inline QPointF &operator*=(qreal c);
237 constexpr inline QPointF &operator/=(qreal c);
238
239 constexpr static inline qreal dotProduct(const QPointF &p1, const QPointF &p2)
240 {
241 return p1.xp * p2.xp + p1.yp * p2.yp;
242 }
243
244 QT_WARNING_PUSH
245 QT_WARNING_DISABLE_FLOAT_COMPARE
246 friend constexpr inline bool operator==(const QPointF &p1, const QPointF &p2)
247 {
248 return ((!p1.xp || !p2.xp) ? qFuzzyIsNull(d: p1.xp - p2.xp) : qFuzzyCompare(p1: p1.xp, p2: p2.xp))
249 && ((!p1.yp || !p2.yp) ? qFuzzyIsNull(d: p1.yp - p2.yp) : qFuzzyCompare(p1: p1.yp, p2: p2.yp));
250 }
251 friend constexpr inline bool operator!=(const QPointF &p1, const QPointF &p2)
252 {
253 return !(p1 == p2);
254 }
255 QT_WARNING_POP
256
257 friend constexpr inline QPointF operator+(const QPointF &p1, const QPointF &p2)
258 { return QPointF(p1.xp + p2.xp, p1.yp + p2.yp); }
259 friend constexpr inline QPointF operator-(const QPointF &p1, const QPointF &p2)
260 { return QPointF(p1.xp - p2.xp, p1.yp - p2.yp); }
261 friend constexpr inline QPointF operator*(const QPointF &p, qreal c)
262 { return QPointF(p.xp * c, p.yp * c); }
263 friend constexpr inline QPointF operator*(qreal c, const QPointF &p)
264 { return QPointF(p.xp * c, p.yp * c); }
265 friend constexpr inline QPointF operator+(const QPointF &p)
266 { return p; }
267 friend constexpr inline QPointF operator-(const QPointF &p)
268 { return QPointF(-p.xp, -p.yp); }
269 friend constexpr inline QPointF operator/(const QPointF &p, qreal divisor)
270 {
271 Q_ASSERT(divisor < 0 || divisor > 0);
272 return QPointF(p.xp / divisor, p.yp / divisor);
273 }
274
275 constexpr QPoint toPoint() const;
276
277#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
278 [[nodiscard]] Q_CORE_EXPORT static QPointF fromCGPoint(CGPoint point) noexcept;
279 [[nodiscard]] Q_CORE_EXPORT CGPoint toCGPoint() const noexcept;
280#endif
281
282private:
283 friend class QTransform;
284
285 qreal xp;
286 qreal yp;
287
288 template <std::size_t I,
289 typename P,
290 std::enable_if_t<(I < 2), bool> = true,
291 std::enable_if_t<std::is_same_v<q20::remove_cvref_t<P>, QPointF>, bool> = true>
292 friend constexpr decltype(auto) get(P &&p) noexcept
293 {
294 if constexpr (I == 0)
295 return q23::forward_like<P>(p.xp);
296 else if constexpr (I == 1)
297 return q23::forward_like<P>(p.yp);
298 }
299};
300
301Q_DECLARE_TYPEINFO(QPointF, Q_PRIMITIVE_TYPE);
302
303size_t qHash(QPointF, size_t seed = 0) = delete;
304
305/*****************************************************************************
306 QPointF stream functions
307 *****************************************************************************/
308#ifndef QT_NO_DATASTREAM
309Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QPointF &);
310Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QPointF &);
311#endif
312
313/*****************************************************************************
314 QPointF inline functions
315 *****************************************************************************/
316
317constexpr inline QPointF::QPointF() noexcept : xp(0), yp(0) { }
318
319constexpr inline QPointF::QPointF(qreal xpos, qreal ypos) noexcept : xp(xpos), yp(ypos) { }
320
321constexpr inline QPointF::QPointF(const QPoint &p) noexcept : xp(p.x()), yp(p.y()) { }
322
323constexpr inline qreal QPointF::manhattanLength() const
324{
325 return qAbs(t: x()) + qAbs(t: y());
326}
327
328inline bool QPointF::isNull() const noexcept
329{
330 return qIsNull(d: xp) && qIsNull(d: yp);
331}
332
333constexpr inline qreal QPointF::x() const noexcept
334{
335 return xp;
336}
337
338constexpr inline qreal QPointF::y() const noexcept
339{
340 return yp;
341}
342
343constexpr inline void QPointF::setX(qreal xpos) noexcept
344{
345 xp = xpos;
346}
347
348constexpr inline void QPointF::setY(qreal ypos) noexcept
349{
350 yp = ypos;
351}
352
353constexpr inline qreal &QPointF::rx() noexcept
354{
355 return xp;
356}
357
358constexpr inline qreal &QPointF::ry() noexcept
359{
360 return yp;
361}
362
363constexpr inline QPointF &QPointF::operator+=(const QPointF &p)
364{
365 xp += p.xp;
366 yp += p.yp;
367 return *this;
368}
369
370constexpr inline QPointF &QPointF::operator-=(const QPointF &p)
371{
372 xp -= p.xp;
373 yp -= p.yp;
374 return *this;
375}
376
377constexpr inline QPointF &QPointF::operator*=(qreal c)
378{
379 xp *= c;
380 yp *= c;
381 return *this;
382}
383
384constexpr inline QPointF &QPointF::operator/=(qreal divisor)
385{
386 Q_ASSERT(divisor > 0 || divisor < 0);
387 xp /= divisor;
388 yp /= divisor;
389 return *this;
390}
391
392constexpr QPointF QPoint::toPointF() const noexcept { return *this; }
393
394constexpr inline QPoint QPointF::toPoint() const
395{
396 return QPoint(qRound(d: xp), qRound(d: yp));
397}
398
399#ifndef QT_NO_DEBUG_STREAM
400Q_CORE_EXPORT QDebug operator<<(QDebug d, const QPointF &p);
401#endif
402
403QT_END_NAMESPACE
404
405/*****************************************************************************
406 QPoint/QPointF tuple protocol
407 *****************************************************************************/
408
409namespace std {
410 template <>
411 class tuple_size<QT_PREPEND_NAMESPACE(QPoint)> : public integral_constant<size_t, 2> {};
412 template <>
413 class tuple_element<0, QT_PREPEND_NAMESPACE(QPoint)> { public: using type = int; };
414 template <>
415 class tuple_element<1, QT_PREPEND_NAMESPACE(QPoint)> { public: using type = int; };
416
417 template <>
418 class tuple_size<QT_PREPEND_NAMESPACE(QPointF)> : public integral_constant<size_t, 2> {};
419 template <>
420 class tuple_element<0, QT_PREPEND_NAMESPACE(QPointF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
421 template <>
422 class tuple_element<1, QT_PREPEND_NAMESPACE(QPointF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); };
423}
424
425#endif // QPOINT_H
426

source code of qtbase/src/corelib/tools/qpoint.h