From df1db826cb93132c05215be8f1451327d0323b4b Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Wed, 6 Jul 2022 16:49:35 +0200 Subject: [PATCH] Move qMin/qMax/qBound() to a separate qminmax.h header Also replaced qMin() uses in qnumeric.h with QtPrivate::min(). Including qassert.h in qminmax.h leads to indirect include of qglobal.h (through qcompilerdetection.h), which in turn leads to qMin() declaration not being available at the point the compiler sees qFuzzyCompare() definitions in qnumeric.h. This makes the headersclean build fail. Task-number: QTBUG-99313 Change-Id: I824422698b06f94a4a62e2f19d4507c87f90334e Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot --- src/corelib/CMakeLists.txt | 1 + src/corelib/global/qglobal.cpp | 37 -------------- src/corelib/global/qglobal.h | 68 +------------------------ src/corelib/global/qminmax.h | 88 +++++++++++++++++++++++++++++++++ src/corelib/global/qminmax.qdoc | 39 +++++++++++++++ src/corelib/global/qnumeric.h | 10 +++- 6 files changed, 137 insertions(+), 106 deletions(-) create mode 100644 src/corelib/global/qminmax.h create mode 100644 src/corelib/global/qminmax.qdoc diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 575bb1b0f41..5f8fc1c3135 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -64,6 +64,7 @@ qt_internal_add_module(Core global/qlibraryinfo.cpp global/qlibraryinfo.h global/qlibraryinfo_p.h global/qlogging.cpp global/qlogging.h global/qlogging_p.h global/qmalloc.cpp + global/qminmax.h global/qnamespace.h # this header is specified on purpose so AUTOMOC processes it global/qnativeinterface.h global/qnativeinterface_p.h global/qnumeric.cpp global/qnumeric.h global/qnumeric_p.h diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index d8d618e92ba..9805195d763 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -861,43 +861,6 @@ using namespace Qt::StringLiterals; \snippet code/src_corelib_global_qglobal.cpp 12B */ -/*! \fn template const T &qMin(const T &a, const T &b) - \relates - - Returns the minimum of \a a and \a b. - - Example: - - \snippet code/src_corelib_global_qglobal.cpp 13 - - \sa qMax(), qBound() -*/ - -/*! \fn template const T &qMax(const T &a, const T &b) - \relates - - Returns the maximum of \a a and \a b. - - Example: - - \snippet code/src_corelib_global_qglobal.cpp 14 - - \sa qMin(), qBound() -*/ - -/*! \fn template const T &qBound(const T &min, const T &val, const T &max) - \relates - - Returns \a val bounded by \a min and \a max. This is equivalent - to qMax(\a min, qMin(\a val, \a max)). - - Example: - - \snippet code/src_corelib_global_qglobal.cpp 15 - - \sa qMin(), qMax() -*/ - /*! \macro QT_VERSION_STR \relates diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 82c6e5e0376..54ce2ff6fa6 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -446,73 +446,6 @@ typedef void (*QFunctionPointer)(); # define Q_UNIMPLEMENTED() qWarning("Unimplemented code.") #endif -namespace QTypeTraits { - -namespace detail { -template && std::is_arithmetic_v && - std::is_floating_point_v == std::is_floating_point_v && - std::is_signed_v == std::is_signed_v && - !std::is_same_v && !std::is_same_v && - !std::is_same_v && !std::is_same_v>> -struct Promoted -{ - using type = decltype(T() + U()); -}; -} - -template -using Promoted = typename detail::Promoted::type; - -} - -template -constexpr inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; } -template -constexpr inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; } -template -constexpr inline const T &qBound(const T &min, const T &val, const T &max) -{ - Q_ASSERT(!(max < min)); - return qMax(min, qMin(max, val)); -} -template -constexpr inline QTypeTraits::Promoted qMin(const T &a, const U &b) -{ - using P = QTypeTraits::Promoted; - P _a = a; - P _b = b; - return (_a < _b) ? _a : _b; -} -template -constexpr inline QTypeTraits::Promoted qMax(const T &a, const U &b) -{ - using P = QTypeTraits::Promoted; - P _a = a; - P _b = b; - return (_a < _b) ? _b : _a; -} -template -constexpr inline QTypeTraits::Promoted qBound(const T &min, const U &val, const T &max) -{ - Q_ASSERT(!(max < min)); - return qMax(min, qMin(max, val)); -} -template -constexpr inline QTypeTraits::Promoted qBound(const T &min, const T &val, const U &max) -{ - using P = QTypeTraits::Promoted; - Q_ASSERT(!(P(max) < P(min))); - return qMax(min, qMin(max, val)); -} -template -constexpr inline QTypeTraits::Promoted qBound(const U &min, const T &val, const T &max) -{ - using P = QTypeTraits::Promoted; - Q_ASSERT(!(P(max) < P(min))); - return qMax(min, qMin(max, val)); -} - /* Compilers which follow outdated template instantiation rules require a class to have a comparison operator to exist when @@ -704,6 +637,7 @@ QT_END_NAMESPACE #include #include #include +#include #include #include #include diff --git a/src/corelib/global/qminmax.h b/src/corelib/global/qminmax.h new file mode 100644 index 00000000000..e6fb62bf9d8 --- /dev/null +++ b/src/corelib/global/qminmax.h @@ -0,0 +1,88 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QMINMAX_H +#define QMINMAX_H + +#if 0 +#pragma qt_class(QtMinMax) +#pragma qt_sync_stop_processing +#endif + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +namespace QTypeTraits { + +namespace detail { +template && std::is_arithmetic_v && + std::is_floating_point_v == std::is_floating_point_v && + std::is_signed_v == std::is_signed_v && + !std::is_same_v && !std::is_same_v && + !std::is_same_v && !std::is_same_v>> +struct Promoted +{ + using type = decltype(T() + U()); +}; +} + +template +using Promoted = typename detail::Promoted::type; + +} + +template +constexpr inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; } +template +constexpr inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; } +template +constexpr inline const T &qBound(const T &min, const T &val, const T &max) +{ + Q_ASSERT(!(max < min)); + return qMax(min, qMin(max, val)); +} +template +constexpr inline QTypeTraits::Promoted qMin(const T &a, const U &b) +{ + using P = QTypeTraits::Promoted; + P _a = a; + P _b = b; + return (_a < _b) ? _a : _b; +} +template +constexpr inline QTypeTraits::Promoted qMax(const T &a, const U &b) +{ + using P = QTypeTraits::Promoted; + P _a = a; + P _b = b; + return (_a < _b) ? _b : _a; +} +template +constexpr inline QTypeTraits::Promoted qBound(const T &min, const U &val, const T &max) +{ + Q_ASSERT(!(max < min)); + return qMax(min, qMin(max, val)); +} +template +constexpr inline QTypeTraits::Promoted qBound(const T &min, const T &val, const U &max) +{ + using P = QTypeTraits::Promoted; + Q_ASSERT(!(P(max) < P(min))); + return qMax(min, qMin(max, val)); +} +template +constexpr inline QTypeTraits::Promoted qBound(const U &min, const T &val, const T &max) +{ + using P = QTypeTraits::Promoted; + Q_ASSERT(!(P(max) < P(min))); + return qMax(min, qMin(max, val)); +} + +QT_END_NAMESPACE + +#endif // QMINMAX_H diff --git a/src/corelib/global/qminmax.qdoc b/src/corelib/global/qminmax.qdoc new file mode 100644 index 00000000000..36f680b4c7b --- /dev/null +++ b/src/corelib/global/qminmax.qdoc @@ -0,0 +1,39 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! \fn template const T &qMin(const T &a, const T &b) + \relates + + Returns the minimum of \a a and \a b. + + Example: + + \snippet code/src_corelib_global_qglobal.cpp 13 + + \sa qMax(), qBound() +*/ + +/*! \fn template const T &qMax(const T &a, const T &b) + \relates + + Returns the maximum of \a a and \a b. + + Example: + + \snippet code/src_corelib_global_qglobal.cpp 14 + + \sa qMin(), qBound() +*/ + +/*! \fn template const T &qBound(const T &min, const T &val, const T &max) + \relates + + Returns \a val bounded by \a min and \a max. This is equivalent + to qMax(\a min, qMin(\a val, \a max)). + + Example: + + \snippet code/src_corelib_global_qglobal.cpp 15 + + \sa qMin(), qMax() +*/ diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h index 24fa782f06e..9ecbbc712a3 100644 --- a/src/corelib/global/qnumeric.h +++ b/src/corelib/global/qnumeric.h @@ -9,6 +9,7 @@ #endif #include + #include #include #include @@ -356,14 +357,19 @@ constexpr inline qint64 qRound64(float d) { return d >= 0.0f ? qint64(d + 0.5f) : qint64(d - 0.5f); } #endif +namespace QtPrivate { +template +constexpr inline const T &min(const T &a, const T &b) { return (a < b) ? a : b; } +} + [[nodiscard]] constexpr bool qFuzzyCompare(double p1, double p2) { - return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2))); + return (qAbs(p1 - p2) * 1000000000000. <= QtPrivate::min(qAbs(p1), qAbs(p2))); } [[nodiscard]] constexpr bool qFuzzyCompare(float p1, float p2) { - return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2))); + return (qAbs(p1 - p2) * 100000.f <= QtPrivate::min(qAbs(p1), qAbs(p2))); } [[nodiscard]] constexpr bool qFuzzyIsNull(double d)