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 QMARGINS_H |
5 | #define QMARGINS_H |
6 | |
7 | #include <QtCore/qnamespace.h> |
8 | |
9 | #include <QtCore/q20type_traits.h> |
10 | #include <QtCore/q23utility.h> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | QT_ENABLE_P0846_SEMANTICS_FOR(get) |
15 | |
16 | class QMarginsF; |
17 | |
18 | /***************************************************************************** |
19 | QMargins class |
20 | *****************************************************************************/ |
21 | |
22 | class QMargins |
23 | { |
24 | public: |
25 | constexpr QMargins() noexcept; |
26 | constexpr QMargins(int left, int top, int right, int bottom) noexcept; |
27 | |
28 | constexpr bool isNull() const noexcept; |
29 | |
30 | constexpr int left() const noexcept; |
31 | constexpr int top() const noexcept; |
32 | constexpr int right() const noexcept; |
33 | constexpr int bottom() const noexcept; |
34 | |
35 | constexpr void setLeft(int left) noexcept; |
36 | constexpr void setTop(int top) noexcept; |
37 | constexpr void setRight(int right) noexcept; |
38 | constexpr void setBottom(int bottom) noexcept; |
39 | |
40 | constexpr QMargins &operator+=(const QMargins &margins) noexcept; |
41 | constexpr QMargins &operator-=(const QMargins &margins) noexcept; |
42 | constexpr QMargins &operator+=(int) noexcept; |
43 | constexpr QMargins &operator-=(int) noexcept; |
44 | constexpr QMargins &operator*=(int) noexcept; |
45 | constexpr QMargins &operator/=(int); |
46 | constexpr QMargins &operator*=(qreal) noexcept; |
47 | constexpr QMargins &operator/=(qreal); |
48 | |
49 | [[nodiscard]] constexpr inline QMarginsF toMarginsF() const noexcept; |
50 | |
51 | private: |
52 | int m_left; |
53 | int m_top; |
54 | int m_right; |
55 | int m_bottom; |
56 | |
57 | friend constexpr inline bool operator==(const QMargins &m1, const QMargins &m2) noexcept |
58 | { |
59 | return |
60 | m1.m_left == m2.m_left && |
61 | m1.m_top == m2.m_top && |
62 | m1.m_right == m2.m_right && |
63 | m1.m_bottom == m2.m_bottom; |
64 | } |
65 | |
66 | friend constexpr inline bool operator!=(const QMargins &m1, const QMargins &m2) noexcept |
67 | { |
68 | return !(m1 == m2); |
69 | } |
70 | |
71 | template <std::size_t I, |
72 | typename M, |
73 | std::enable_if_t<(I < 4), bool> = true, |
74 | std::enable_if_t<std::is_same_v<q20::remove_cvref_t<M>, QMargins>, bool> = true> |
75 | friend constexpr decltype(auto) get(M &&m) noexcept |
76 | { |
77 | if constexpr (I == 0) |
78 | return q23::forward_like<M>(m.m_left); |
79 | else if constexpr (I == 1) |
80 | return q23::forward_like<M>(m.m_top); |
81 | else if constexpr (I == 2) |
82 | return q23::forward_like<M>(m.m_right); |
83 | else if constexpr (I == 3) |
84 | return q23::forward_like<M>(m.m_bottom); |
85 | } |
86 | }; |
87 | |
88 | Q_DECLARE_TYPEINFO(QMargins, Q_RELOCATABLE_TYPE); |
89 | |
90 | /***************************************************************************** |
91 | QMargins stream functions |
92 | *****************************************************************************/ |
93 | #ifndef QT_NO_DATASTREAM |
94 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QMargins &); |
95 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QMargins &); |
96 | #endif |
97 | |
98 | /***************************************************************************** |
99 | QMargins inline functions |
100 | *****************************************************************************/ |
101 | |
102 | constexpr inline QMargins::QMargins() noexcept : m_left(0), m_top(0), m_right(0), m_bottom(0) {} |
103 | |
104 | constexpr inline QMargins::QMargins(int aleft, int atop, int aright, int abottom) noexcept |
105 | : m_left(aleft), m_top(atop), m_right(aright), m_bottom(abottom) {} |
106 | |
107 | constexpr inline bool QMargins::isNull() const noexcept |
108 | { return m_left==0 && m_top==0 && m_right==0 && m_bottom==0; } |
109 | |
110 | constexpr inline int QMargins::left() const noexcept |
111 | { return m_left; } |
112 | |
113 | constexpr inline int QMargins::top() const noexcept |
114 | { return m_top; } |
115 | |
116 | constexpr inline int QMargins::right() const noexcept |
117 | { return m_right; } |
118 | |
119 | constexpr inline int QMargins::bottom() const noexcept |
120 | { return m_bottom; } |
121 | |
122 | |
123 | constexpr inline void QMargins::setLeft(int aleft) noexcept |
124 | { m_left = aleft; } |
125 | |
126 | constexpr inline void QMargins::setTop(int atop) noexcept |
127 | { m_top = atop; } |
128 | |
129 | constexpr inline void QMargins::setRight(int aright) noexcept |
130 | { m_right = aright; } |
131 | |
132 | constexpr inline void QMargins::setBottom(int abottom) noexcept |
133 | { m_bottom = abottom; } |
134 | |
135 | constexpr inline QMargins operator+(const QMargins &m1, const QMargins &m2) noexcept |
136 | { |
137 | return QMargins(m1.left() + m2.left(), m1.top() + m2.top(), |
138 | m1.right() + m2.right(), m1.bottom() + m2.bottom()); |
139 | } |
140 | |
141 | constexpr inline QMargins operator-(const QMargins &m1, const QMargins &m2) noexcept |
142 | { |
143 | return QMargins(m1.left() - m2.left(), m1.top() - m2.top(), |
144 | m1.right() - m2.right(), m1.bottom() - m2.bottom()); |
145 | } |
146 | |
147 | constexpr inline QMargins operator+(const QMargins &lhs, int rhs) noexcept |
148 | { |
149 | return QMargins(lhs.left() + rhs, lhs.top() + rhs, |
150 | lhs.right() + rhs, lhs.bottom() + rhs); |
151 | } |
152 | |
153 | constexpr inline QMargins operator+(int lhs, const QMargins &rhs) noexcept |
154 | { |
155 | return QMargins(rhs.left() + lhs, rhs.top() + lhs, |
156 | rhs.right() + lhs, rhs.bottom() + lhs); |
157 | } |
158 | |
159 | constexpr inline QMargins operator-(const QMargins &lhs, int rhs) noexcept |
160 | { |
161 | return QMargins(lhs.left() - rhs, lhs.top() - rhs, |
162 | lhs.right() - rhs, lhs.bottom() - rhs); |
163 | } |
164 | |
165 | constexpr inline QMargins operator*(const QMargins &margins, int factor) noexcept |
166 | { |
167 | return QMargins(margins.left() * factor, margins.top() * factor, |
168 | margins.right() * factor, margins.bottom() * factor); |
169 | } |
170 | |
171 | constexpr inline QMargins operator*(int factor, const QMargins &margins) noexcept |
172 | { |
173 | return QMargins(margins.left() * factor, margins.top() * factor, |
174 | margins.right() * factor, margins.bottom() * factor); |
175 | } |
176 | |
177 | constexpr inline QMargins operator*(const QMargins &margins, qreal factor) noexcept |
178 | { |
179 | return QMargins(qRound(d: margins.left() * factor), qRound(d: margins.top() * factor), |
180 | qRound(d: margins.right() * factor), qRound(d: margins.bottom() * factor)); |
181 | } |
182 | |
183 | constexpr inline QMargins operator*(qreal factor, const QMargins &margins) noexcept |
184 | { |
185 | return QMargins(qRound(d: margins.left() * factor), qRound(d: margins.top() * factor), |
186 | qRound(d: margins.right() * factor), qRound(d: margins.bottom() * factor)); |
187 | } |
188 | |
189 | constexpr inline QMargins operator/(const QMargins &margins, int divisor) |
190 | { |
191 | return QMargins(margins.left() / divisor, margins.top() / divisor, |
192 | margins.right() / divisor, margins.bottom() / divisor); |
193 | } |
194 | |
195 | constexpr inline QMargins operator/(const QMargins &margins, qreal divisor) |
196 | { |
197 | return QMargins(qRound(d: margins.left() / divisor), qRound(d: margins.top() / divisor), |
198 | qRound(d: margins.right() / divisor), qRound(d: margins.bottom() / divisor)); |
199 | } |
200 | |
201 | constexpr inline QMargins operator|(const QMargins &m1, const QMargins &m2) noexcept |
202 | { |
203 | return QMargins(qMax(a: m1.left(), b: m2.left()), qMax(a: m1.top(), b: m2.top()), |
204 | qMax(a: m1.right(), b: m2.right()), qMax(a: m1.bottom(), b: m2.bottom())); |
205 | } |
206 | |
207 | constexpr inline QMargins &QMargins::operator+=(const QMargins &margins) noexcept |
208 | { |
209 | return *this = *this + margins; |
210 | } |
211 | |
212 | constexpr inline QMargins &QMargins::operator-=(const QMargins &margins) noexcept |
213 | { |
214 | return *this = *this - margins; |
215 | } |
216 | |
217 | constexpr inline QMargins &QMargins::operator+=(int margin) noexcept |
218 | { |
219 | m_left += margin; |
220 | m_top += margin; |
221 | m_right += margin; |
222 | m_bottom += margin; |
223 | return *this; |
224 | } |
225 | |
226 | constexpr inline QMargins &QMargins::operator-=(int margin) noexcept |
227 | { |
228 | m_left -= margin; |
229 | m_top -= margin; |
230 | m_right -= margin; |
231 | m_bottom -= margin; |
232 | return *this; |
233 | } |
234 | |
235 | constexpr inline QMargins &QMargins::operator*=(int factor) noexcept |
236 | { |
237 | return *this = *this * factor; |
238 | } |
239 | |
240 | constexpr inline QMargins &QMargins::operator/=(int divisor) |
241 | { |
242 | return *this = *this / divisor; |
243 | } |
244 | |
245 | constexpr inline QMargins &QMargins::operator*=(qreal factor) noexcept |
246 | { |
247 | return *this = *this * factor; |
248 | } |
249 | |
250 | constexpr inline QMargins &QMargins::operator/=(qreal divisor) |
251 | { |
252 | return *this = *this / divisor; |
253 | } |
254 | |
255 | constexpr inline QMargins operator+(const QMargins &margins) noexcept |
256 | { |
257 | return margins; |
258 | } |
259 | |
260 | constexpr inline QMargins operator-(const QMargins &margins) noexcept |
261 | { |
262 | return QMargins(-margins.left(), -margins.top(), -margins.right(), -margins.bottom()); |
263 | } |
264 | |
265 | #ifndef QT_NO_DEBUG_STREAM |
266 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QMargins &); |
267 | #endif |
268 | |
269 | /***************************************************************************** |
270 | QMarginsF class |
271 | *****************************************************************************/ |
272 | |
273 | class QMarginsF |
274 | { |
275 | public: |
276 | constexpr QMarginsF() noexcept; |
277 | constexpr QMarginsF(qreal left, qreal top, qreal right, qreal bottom) noexcept; |
278 | constexpr QMarginsF(const QMargins &margins) noexcept; |
279 | |
280 | constexpr bool isNull() const noexcept; |
281 | |
282 | constexpr qreal left() const noexcept; |
283 | constexpr qreal top() const noexcept; |
284 | constexpr qreal right() const noexcept; |
285 | constexpr qreal bottom() const noexcept; |
286 | |
287 | constexpr void setLeft(qreal aleft) noexcept; |
288 | constexpr void setTop(qreal atop) noexcept; |
289 | constexpr void setRight(qreal aright) noexcept; |
290 | constexpr void setBottom(qreal abottom) noexcept; |
291 | |
292 | constexpr QMarginsF &operator+=(const QMarginsF &margins) noexcept; |
293 | constexpr QMarginsF &operator-=(const QMarginsF &margins) noexcept; |
294 | constexpr QMarginsF &operator+=(qreal addend) noexcept; |
295 | constexpr QMarginsF &operator-=(qreal subtrahend) noexcept; |
296 | constexpr QMarginsF &operator*=(qreal factor) noexcept; |
297 | constexpr QMarginsF &operator/=(qreal divisor); |
298 | |
299 | constexpr inline QMargins toMargins() const noexcept; |
300 | |
301 | private: |
302 | qreal m_left; |
303 | qreal m_top; |
304 | qreal m_right; |
305 | qreal m_bottom; |
306 | |
307 | friend constexpr inline bool operator==(const QMarginsF &lhs, const QMarginsF &rhs) noexcept |
308 | { |
309 | return qFuzzyCompare(p1: lhs.left(), p2: rhs.left()) |
310 | && qFuzzyCompare(p1: lhs.top(), p2: rhs.top()) |
311 | && qFuzzyCompare(p1: lhs.right(), p2: rhs.right()) |
312 | && qFuzzyCompare(p1: lhs.bottom(), p2: rhs.bottom()); |
313 | } |
314 | |
315 | friend constexpr inline bool operator!=(const QMarginsF &lhs, const QMarginsF &rhs) noexcept |
316 | { |
317 | return !(lhs == rhs); |
318 | } |
319 | |
320 | template <std::size_t I, |
321 | typename M, |
322 | std::enable_if_t<(I < 4), bool> = true, |
323 | std::enable_if_t<std::is_same_v<q20::remove_cvref_t<M>, QMarginsF>, bool> = true> |
324 | friend constexpr decltype(auto) get(M &&m) noexcept |
325 | { |
326 | if constexpr (I == 0) |
327 | return q23::forward_like<M>(m.m_left); |
328 | else if constexpr (I == 1) |
329 | return q23::forward_like<M>(m.m_top); |
330 | else if constexpr (I == 2) |
331 | return q23::forward_like<M>(m.m_right); |
332 | else if constexpr (I == 3) |
333 | return q23::forward_like<M>(m.m_bottom); |
334 | } |
335 | }; |
336 | |
337 | Q_DECLARE_TYPEINFO(QMarginsF, Q_RELOCATABLE_TYPE); |
338 | |
339 | /***************************************************************************** |
340 | QMarginsF stream functions |
341 | *****************************************************************************/ |
342 | |
343 | #ifndef QT_NO_DATASTREAM |
344 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QMarginsF &); |
345 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QMarginsF &); |
346 | #endif |
347 | |
348 | /***************************************************************************** |
349 | QMarginsF inline functions |
350 | *****************************************************************************/ |
351 | |
352 | constexpr inline QMarginsF::QMarginsF() noexcept |
353 | : m_left(0), m_top(0), m_right(0), m_bottom(0) {} |
354 | |
355 | constexpr inline QMarginsF::QMarginsF(qreal aleft, qreal atop, qreal aright, qreal abottom) noexcept |
356 | : m_left(aleft), m_top(atop), m_right(aright), m_bottom(abottom) {} |
357 | |
358 | constexpr inline QMarginsF::QMarginsF(const QMargins &margins) noexcept |
359 | : m_left(margins.left()), m_top(margins.top()), m_right(margins.right()), m_bottom(margins.bottom()) {} |
360 | |
361 | constexpr inline bool QMarginsF::isNull() const noexcept |
362 | { return qFuzzyIsNull(d: m_left) && qFuzzyIsNull(d: m_top) && qFuzzyIsNull(d: m_right) && qFuzzyIsNull(d: m_bottom); } |
363 | |
364 | constexpr inline qreal QMarginsF::left() const noexcept |
365 | { return m_left; } |
366 | |
367 | constexpr inline qreal QMarginsF::top() const noexcept |
368 | { return m_top; } |
369 | |
370 | constexpr inline qreal QMarginsF::right() const noexcept |
371 | { return m_right; } |
372 | |
373 | constexpr inline qreal QMarginsF::bottom() const noexcept |
374 | { return m_bottom; } |
375 | |
376 | |
377 | constexpr inline void QMarginsF::setLeft(qreal aleft) noexcept |
378 | { m_left = aleft; } |
379 | |
380 | constexpr inline void QMarginsF::setTop(qreal atop) noexcept |
381 | { m_top = atop; } |
382 | |
383 | constexpr inline void QMarginsF::setRight(qreal aright) noexcept |
384 | { m_right = aright; } |
385 | |
386 | constexpr inline void QMarginsF::setBottom(qreal abottom) noexcept |
387 | { m_bottom = abottom; } |
388 | |
389 | constexpr inline QMarginsF operator+(const QMarginsF &lhs, const QMarginsF &rhs) noexcept |
390 | { |
391 | return QMarginsF(lhs.left() + rhs.left(), lhs.top() + rhs.top(), |
392 | lhs.right() + rhs.right(), lhs.bottom() + rhs.bottom()); |
393 | } |
394 | |
395 | constexpr inline QMarginsF operator-(const QMarginsF &lhs, const QMarginsF &rhs) noexcept |
396 | { |
397 | return QMarginsF(lhs.left() - rhs.left(), lhs.top() - rhs.top(), |
398 | lhs.right() - rhs.right(), lhs.bottom() - rhs.bottom()); |
399 | } |
400 | |
401 | constexpr inline QMarginsF operator+(const QMarginsF &lhs, qreal rhs) noexcept |
402 | { |
403 | return QMarginsF(lhs.left() + rhs, lhs.top() + rhs, |
404 | lhs.right() + rhs, lhs.bottom() + rhs); |
405 | } |
406 | |
407 | constexpr inline QMarginsF operator+(qreal lhs, const QMarginsF &rhs) noexcept |
408 | { |
409 | return QMarginsF(rhs.left() + lhs, rhs.top() + lhs, |
410 | rhs.right() + lhs, rhs.bottom() + lhs); |
411 | } |
412 | |
413 | constexpr inline QMarginsF operator-(const QMarginsF &lhs, qreal rhs) noexcept |
414 | { |
415 | return QMarginsF(lhs.left() - rhs, lhs.top() - rhs, |
416 | lhs.right() - rhs, lhs.bottom() - rhs); |
417 | } |
418 | |
419 | constexpr inline QMarginsF operator*(const QMarginsF &lhs, qreal rhs) noexcept |
420 | { |
421 | return QMarginsF(lhs.left() * rhs, lhs.top() * rhs, |
422 | lhs.right() * rhs, lhs.bottom() * rhs); |
423 | } |
424 | |
425 | constexpr inline QMarginsF operator*(qreal lhs, const QMarginsF &rhs) noexcept |
426 | { |
427 | return QMarginsF(rhs.left() * lhs, rhs.top() * lhs, |
428 | rhs.right() * lhs, rhs.bottom() * lhs); |
429 | } |
430 | |
431 | constexpr inline QMarginsF operator/(const QMarginsF &lhs, qreal divisor) |
432 | { |
433 | Q_ASSERT(divisor < 0 || divisor > 0); |
434 | return QMarginsF(lhs.left() / divisor, lhs.top() / divisor, |
435 | lhs.right() / divisor, lhs.bottom() / divisor); |
436 | } |
437 | |
438 | constexpr inline QMarginsF operator|(const QMarginsF &m1, const QMarginsF &m2) noexcept |
439 | { |
440 | return QMarginsF(qMax(a: m1.left(), b: m2.left()), qMax(a: m1.top(), b: m2.top()), |
441 | qMax(a: m1.right(), b: m2.right()), qMax(a: m1.bottom(), b: m2.bottom())); |
442 | } |
443 | |
444 | constexpr inline QMarginsF &QMarginsF::operator+=(const QMarginsF &margins) noexcept |
445 | { |
446 | return *this = *this + margins; |
447 | } |
448 | |
449 | constexpr inline QMarginsF &QMarginsF::operator-=(const QMarginsF &margins) noexcept |
450 | { |
451 | return *this = *this - margins; |
452 | } |
453 | |
454 | constexpr inline QMarginsF &QMarginsF::operator+=(qreal addend) noexcept |
455 | { |
456 | m_left += addend; |
457 | m_top += addend; |
458 | m_right += addend; |
459 | m_bottom += addend; |
460 | return *this; |
461 | } |
462 | |
463 | constexpr inline QMarginsF &QMarginsF::operator-=(qreal subtrahend) noexcept |
464 | { |
465 | m_left -= subtrahend; |
466 | m_top -= subtrahend; |
467 | m_right -= subtrahend; |
468 | m_bottom -= subtrahend; |
469 | return *this; |
470 | } |
471 | |
472 | constexpr inline QMarginsF &QMarginsF::operator*=(qreal factor) noexcept |
473 | { |
474 | return *this = *this * factor; |
475 | } |
476 | |
477 | constexpr inline QMarginsF &QMarginsF::operator/=(qreal divisor) |
478 | { |
479 | return *this = *this / divisor; |
480 | } |
481 | |
482 | constexpr inline QMarginsF operator+(const QMarginsF &margins) noexcept |
483 | { |
484 | return margins; |
485 | } |
486 | |
487 | constexpr inline QMarginsF operator-(const QMarginsF &margins) noexcept |
488 | { |
489 | return QMarginsF(-margins.left(), -margins.top(), -margins.right(), -margins.bottom()); |
490 | } |
491 | |
492 | constexpr QMarginsF QMargins::toMarginsF() const noexcept { return *this; } |
493 | |
494 | constexpr inline QMargins QMarginsF::toMargins() const noexcept |
495 | { |
496 | return QMargins(qRound(d: m_left), qRound(d: m_top), qRound(d: m_right), qRound(d: m_bottom)); |
497 | } |
498 | |
499 | #ifndef QT_NO_DEBUG_STREAM |
500 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QMarginsF &); |
501 | #endif |
502 | |
503 | QT_END_NAMESPACE |
504 | |
505 | /***************************************************************************** |
506 | QMargins/QMarginsF tuple protocol |
507 | *****************************************************************************/ |
508 | |
509 | namespace std { |
510 | template <> |
511 | class tuple_size<QT_PREPEND_NAMESPACE(QMargins)> : public integral_constant<size_t, 4> {}; |
512 | template <> |
513 | class tuple_element<0, QT_PREPEND_NAMESPACE(QMargins)> { public: using type = int; }; |
514 | template <> |
515 | class tuple_element<1, QT_PREPEND_NAMESPACE(QMargins)> { public: using type = int; }; |
516 | template <> |
517 | class tuple_element<2, QT_PREPEND_NAMESPACE(QMargins)> { public: using type = int; }; |
518 | template <> |
519 | class tuple_element<3, QT_PREPEND_NAMESPACE(QMargins)> { public: using type = int; }; |
520 | |
521 | template <> |
522 | class tuple_size<QT_PREPEND_NAMESPACE(QMarginsF)> : public integral_constant<size_t, 4> {}; |
523 | template <> |
524 | class tuple_element<0, QT_PREPEND_NAMESPACE(QMarginsF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); }; |
525 | template <> |
526 | class tuple_element<1, QT_PREPEND_NAMESPACE(QMarginsF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); }; |
527 | template <> |
528 | class tuple_element<2, QT_PREPEND_NAMESPACE(QMarginsF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); }; |
529 | template <> |
530 | class tuple_element<3, QT_PREPEND_NAMESPACE(QMarginsF)> { public: using type = QT_PREPEND_NAMESPACE(qreal); }; |
531 | } |
532 | |
533 | #endif // QMARGINS_H |
534 | |