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)