summaryrefslogtreecommitdiffstats
path: root/src/corelib/global
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global')
-rw-r--r--src/corelib/global/qassert.cpp30
-rw-r--r--src/corelib/global/qcompare.cpp140
-rw-r--r--src/corelib/global/qcomparehelpers.h225
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h2
-rw-r--r--src/corelib/global/qexceptionhandling.h6
-rw-r--r--src/corelib/global/qglobal.cpp14
-rw-r--r--src/corelib/global/qglobal.h3
-rw-r--r--src/corelib/global/qlibraryinfo.cpp180
-rw-r--r--src/corelib/global/qlibraryinfo.h1
-rw-r--r--src/corelib/global/qlibraryinfo_p.h1
-rw-r--r--src/corelib/global/qlogging.cpp10
-rw-r--r--src/corelib/global/qlogging.h3
-rw-r--r--src/corelib/global/qminmax.h23
-rw-r--r--src/corelib/global/qnamespace.h10
-rw-r--r--src/corelib/global/qnamespace.qdoc27
-rw-r--r--src/corelib/global/qnativeinterface_p.h2
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp6
-rw-r--r--src/corelib/global/qoperatingsystemversion.h1
-rw-r--r--src/corelib/global/qtconfigmacros.h2
-rw-r--r--src/corelib/global/qtdeprecationdefinitions.h.in28
-rw-r--r--src/corelib/global/qtdeprecationmarkers.h23
-rw-r--r--src/corelib/global/qttypetraits.h209
-rw-r--r--src/corelib/global/qtypeinfo.h195
-rw-r--r--src/corelib/global/qversiontagging.h2
24 files changed, 770 insertions, 373 deletions
diff --git a/src/corelib/global/qassert.cpp b/src/corelib/global/qassert.cpp
index 6a29cbfa21..7c0064ac2f 100644
--- a/src/corelib/global/qassert.cpp
+++ b/src/corelib/global/qassert.cpp
@@ -195,36 +195,6 @@ void qBadAlloc()
*/
/*!
- \macro QT_TERMINATE_ON_EXCEPTION(expr)
- \relates <QtGlobal>
- \internal
-
- In general, use of the Q_DECL_NOEXCEPT macro is preferred over
- Q_DECL_NOTHROW, because it exhibits well-defined behavior and
- supports the more powerful Q_DECL_NOEXCEPT_EXPR variant. However,
- use of Q_DECL_NOTHROW has the advantage that Windows builds
- benefit on a wide range or compiler versions that do not yet
- support the C++11 noexcept feature.
-
- It may therefore be beneficial to use Q_DECL_NOTHROW and emulate
- the C++11 behavior manually with an embedded try/catch.
-
- Qt provides the QT_TERMINATE_ON_EXCEPTION(expr) macro for this
- purpose. It either expands to \c expr (if Qt is compiled without
- exception support or the compiler supports C++11 noexcept
- semantics) or to
- \snippet code/src_corelib_global_qglobal.cpp qterminate
- otherwise.
-
- Since this macro expands to just \c expr if the compiler supports
- C++11 noexcept, expecting the compiler to take over responsibility
- of calling std::terminate() in that case, it should not be used
- outside Q_DECL_NOTHROW functions.
-
- \sa Q_DECL_NOEXCEPT, Q_DECL_NOTHROW, qTerminate()
-*/
-
-/*!
\macro void Q_UNREACHABLE()
\relates <QtAssert>
\since 5.0
diff --git a/src/corelib/global/qcompare.cpp b/src/corelib/global/qcompare.cpp
index ac220b8434..4df6146b10 100644
--- a/src/corelib/global/qcompare.cpp
+++ b/src/corelib/global/qcompare.cpp
@@ -149,6 +149,7 @@ CHECK(strong, equivalent);
/*!
\class Qt::strong_ordering
\inmodule QtCore
+ \inheaderfile QtCompare
\brief Qt::strong_ordering represents a comparison where equivalent values are
indistinguishable.
\sa Qt::weak_ordering, Qt::partial_ordering, {Comparison types overview}
@@ -334,6 +335,7 @@ CHECK(strong, equivalent);
/*!
\class Qt::weak_ordering
\inmodule QtCore
+ \inheaderfile QtCompare
\brief Qt::weak_ordering represents a comparison where equivalent values are
still distinguishable.
\sa Qt::strong_ordering, Qt::partial_ordering, {Comparison types overview}
@@ -484,6 +486,7 @@ CHECK(strong, equivalent);
/*!
\class Qt::partial_ordering
\inmodule QtCore
+ \inheaderfile QtCompare
\brief Qt::partial_ordering represents the result of a comparison that allows
for unordered results.
\sa Qt::strong_ordering, Qt::weak_ordering, {Comparison types overview}
@@ -1271,9 +1274,12 @@ CHECK(strong, equivalent);
\l Qt::partial_ordering::unordered is returned.
*/
+#if QT_DEPRECATED_SINCE(6, 8)
/*!
\fn template <typename LeftType, typename RightType, Qt::if_compatible_pointers<LeftType, RightType> = true> Qt::compareThreeWay(const LeftType *lhs, const RightType *rhs)
\since 6.7
+ \deprecated [6.8] Wrap the pointers into Qt::totally_ordered_wrapper and
+ use the respective Qt::compareThreeWay() overload instead.
\relates <QtCompare>
\overload
@@ -1286,6 +1292,7 @@ CHECK(strong, equivalent);
Returns an instance of \l Qt::strong_ordering that represents the relation
between \a lhs and \a rhs.
*/
+#endif // QT_DEPRECATED_SINCE(6, 8)
/*!
\fn template <class Enum, Qt::if_enum<Enum> = true> Qt::compareThreeWay(Enum lhs, Enum rhs)
@@ -1306,6 +1313,86 @@ CHECK(strong, equivalent);
*/
/*!
+ \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, Qt::totally_ordered_wrapper<U*> rhs)
+ \since 6.8
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of pointers that are wrapped into
+ \l Qt::totally_ordered_wrapper. Uses
+ \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
+ {strict total order over pointers} when doing the comparison.
+
+ \note This function participates in overload resolution if \c T and \c U
+ are the same type, or base and derived types.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, U *rhs)
+ \since 6.8
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of a pointer wrapped into
+ \l Qt::totally_ordered_wrapper with a normal pointer. Uses
+ \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
+ {strict total order over pointers} when doing the comparison.
+
+ \note This function participates in overload resolution if \c T and \c U
+ are the same type, or base and derived types.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <typename T, typename U, Qt::if_compatible_pointers<T, U> = true> Qt::compareThreeWay(U *lhs, Qt::totally_ordered_wrapper<T*> rhs)
+ \since 6.8
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of a normal pointer with a pointer wrapped
+ into \l Qt::totally_ordered_wrapper. Uses
+ \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
+ {strict total order over pointers} when doing the comparison.
+
+ \note This function participates in overload resolution if \c T and \c U
+ are the same type, or base and derived types.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <typename T> Qt::compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs)
+ \since 6.8
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of a pointer wrapped into
+ \l Qt::totally_ordered_wrapper with \c {std::nullptr_t}.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
+ \fn template <typename T> Qt::compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs)
+ \since 6.8
+ \relates <QtCompare>
+ \overload
+
+ Implements three-way comparison of \c {std::nullptr_t} with a pointer
+ wrapped into \l Qt::totally_ordered_wrapper.
+
+ Returns an instance of \l Qt::strong_ordering that represents the relation
+ between \a lhs and \a rhs.
+*/
+
+/*!
\fn template <typename LeftType, typename RightType> qCompareThreeWay(const LeftType &lhs, const RightType &rhs)
\since 6.7
\relates <QtCompare>
@@ -1354,4 +1441,57 @@ CHECK(strong, equivalent);
\sa Qt::partial_ordering, Qt::weak_ordering, Qt::strong_ordering
*/
+/*!
+ \class Qt::totally_ordered_wrapper
+ \inmodule QtCore
+ \inheaderfile QtCompare
+ \brief Qt::totally_ordered_wrapper is a wrapper type that provides strict
+ total order for the wrapped types.
+ \since 6.8
+
+ One of its primary usecases is to prevent \e {Undefined Behavior} (UB) when
+ comparing pointers.
+
+ Consider the following simple class:
+
+ \code
+ template <typename T>
+ struct PointerWrapperBad {
+ int val;
+ T *ptr;
+ };
+ \endcode
+
+ Lexicographical comparison of the two instances of the \c PointerWrapperBad
+ type would result in UB, because it will call \c {operator<()} or
+ \c {operator<=>()} on the \c {ptr} members.
+
+ To fix it, use the new wrapper type:
+
+ \code
+ template <typename T>
+ struct PointerWrapperGood {
+ int val;
+ Qt::totally_ordered_wrapper<T *> ptr;
+
+ friend bool
+ operator==(PointerWrapperGood lhs, PointerWrapperGood rhs) noexcept = default;
+ friend auto
+ operator<=>(PointerWrapperGood lhs, PointerWrapperGood rhs) noexecpt = default;
+ };
+ \endcode
+
+ The \c {operator<()} and (if available) \c {operator<=>()} operators for
+ the \c {Qt::totally_ordered_wrapper} type use the
+ \l {https://en.cppreference.com/w/cpp/utility/functional/less}{std::less}
+ and \l {https://en.cppreference.com/w/cpp/utility/compare/compare_three_way}
+ {std::compare_three_way} function objects respectively, providing
+ \l {https://en.cppreference.com/w/cpp/language/operator_comparison#Pointer_total_order}
+ {strict total order over pointers} when doing the comparison.
+
+ As a result, the relational operators for \c {PointerWrapperGood::ptr}
+ member will be well-defined, and we can even \c {=default} the relational
+ operators for the \c {PointerWrapperGood} class, like it's shown above.
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qcomparehelpers.h b/src/corelib/global/qcomparehelpers.h
index 0e43ac296b..2da7fbd825 100644
--- a/src/corelib/global/qcomparehelpers.h
+++ b/src/corelib/global/qcomparehelpers.h
@@ -16,6 +16,7 @@
#include <QtCore/qoverload.h>
#include <QtCore/qttypetraits.h>
+#include <QtCore/qtypeinfo.h>
#include <QtCore/qtypes.h>
#ifdef __cpp_lib_three_way_comparison
@@ -23,7 +24,7 @@
#endif
#include <QtCore/q20type_traits.h>
-#include <functional> // std::less
+#include <functional> // std::less, std::hash
QT_BEGIN_NAMESPACE
@@ -145,8 +146,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ \
const auto r = compareThreeWay(rhs, lhs); \
- if (r > 0) return std::strong_ordering::less; \
- if (r < 0) return std::strong_ordering::greater; \
+ if (is_gt(r)) return std::strong_ordering::less; \
+ if (is_lt(r)) return std::strong_ordering::greater; \
return r; \
}
@@ -157,8 +158,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ \
const auto r = compareThreeWay(rhs, lhs); \
- if (r > 0) return std::weak_ordering::less; \
- if (r < 0) return std::weak_ordering::greater; \
+ if (is_gt(r)) return std::weak_ordering::less; \
+ if (is_lt(r)) return std::weak_ordering::greater; \
return r; \
}
@@ -169,8 +170,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ \
const auto r = compareThreeWay(rhs, lhs); \
- if (r > 0) return std::partial_ordering::less; \
- if (r < 0) return std::partial_ordering::greater; \
+ if (is_gt(r)) return std::partial_ordering::less; \
+ if (is_lt(r)) return std::partial_ordering::greater; \
return r; \
}
@@ -218,19 +219,19 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
Attributes \
friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
- { return compareThreeWay(lhs, rhs) < 0; } \
+ { return is_lt(compareThreeWay(lhs, rhs)); } \
Attributes \
friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
- { return compareThreeWay(lhs, rhs) > 0; } \
+ { return is_gt(compareThreeWay(lhs, rhs)); } \
Attributes \
friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
- { return compareThreeWay(lhs, rhs) <= 0; } \
+ { return is_lteq(compareThreeWay(lhs, rhs)); } \
Attributes \
friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
- { return compareThreeWay(lhs, rhs) >= 0; }
+ { return is_gteq(compareThreeWay(lhs, rhs)); }
#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
@@ -255,19 +256,19 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
Attributes \
friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
- { return compareThreeWay(rhs, lhs) > 0; } \
+ { return is_gt(compareThreeWay(rhs, lhs)); } \
Attributes \
friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
- { return compareThreeWay(rhs, lhs) < 0; } \
+ { return is_lt(compareThreeWay(rhs, lhs)); } \
Attributes \
friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
- { return compareThreeWay(rhs, lhs) >= 0; } \
+ { return is_gteq(compareThreeWay(rhs, lhs)); } \
Attributes \
friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
- { return compareThreeWay(rhs, lhs) <= 0; }
+ { return is_lteq(compareThreeWay(rhs, lhs)); }
#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
@@ -450,6 +451,26 @@ constexpr bool IsFloatType_v<QtPrivate::NativeFloat16Type> = true;
} // namespace QtPrivate
+namespace QtOrderingPrivate {
+
+template <typename T, typename U>
+constexpr Qt::strong_ordering
+strongOrderingCompareDefaultImpl(T lhs, U rhs) noexcept
+{
+#ifdef __cpp_lib_three_way_comparison
+ return lhs <=> rhs;
+#else
+ if (lhs == rhs)
+ return Qt::strong_ordering::equivalent;
+ else if (lhs < rhs)
+ return Qt::strong_ordering::less;
+ else
+ return Qt::strong_ordering::greater;
+#endif // __cpp_lib_three_way_comparison
+}
+
+} // namespace QtOrderingPrivate
+
namespace Qt {
template <typename T>
@@ -526,8 +547,11 @@ constexpr Qt::partial_ordering compareThreeWay(FloatType lhs, IntType rhs) noexc
return compareThreeWay(lhs, FloatType(rhs));
}
+#if QT_DEPRECATED_SINCE(6, 8)
+
template <typename LeftType, typename RightType,
if_compatible_pointers<LeftType, RightType> = true>
+QT_DEPRECATED_VERSION_X_6_8("Wrap the pointers into Qt::totally_ordered_wrapper and use the respective overload instead.")
constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightType *rhs) noexcept
{
#ifdef __cpp_lib_three_way_comparison
@@ -543,25 +567,194 @@ constexpr Qt::strong_ordering compareThreeWay(const LeftType *lhs, const RightTy
}
template <typename T>
+QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
constexpr Qt::strong_ordering compareThreeWay(const T *lhs, std::nullptr_t rhs) noexcept
{
return compareThreeWay(lhs, static_cast<const T *>(rhs));
}
template <typename T>
+QT_DEPRECATED_VERSION_X_6_8("Wrap the pointer into Qt::totally_ordered_wrapper and use the respective overload instead.")
constexpr Qt::strong_ordering compareThreeWay(std::nullptr_t lhs, const T *rhs) noexcept
{
return compareThreeWay(static_cast<const T *>(lhs), rhs);
}
+#endif // QT_DEPRECATED_SINCE(6, 8)
+
template <class Enum, if_enum<Enum> = true>
constexpr Qt::strong_ordering compareThreeWay(Enum lhs, Enum rhs) noexcept
{
return compareThreeWay(qToUnderlying(lhs), qToUnderlying(rhs));
}
-
} // namespace Qt
+namespace QtOrderingPrivate {
+
+template <typename Head, typename...Tail, std::size_t...Is>
+constexpr std::tuple<Tail...> qt_tuple_pop_front_impl(const std::tuple<Head, Tail...> &t,
+ std::index_sequence<Is...>) noexcept
+{
+ return std::tuple<Tail...>(std::get<Is + 1>(t)...);
+}
+
+template <typename Head, typename...Tail>
+constexpr std::tuple<Tail...> qt_tuple_pop_front(const std::tuple<Head, Tail...> &t) noexcept
+{
+ return qt_tuple_pop_front_impl(t, std::index_sequence_for<Tail...>{});
+}
+
+template <typename LhsHead, typename...LhsTail, typename RhsHead, typename...RhsTail>
+constexpr auto compareThreeWayMulti(const std::tuple<LhsHead, LhsTail...> &lhs, // ie. not empty
+ const std::tuple<RhsHead, RhsTail...> &rhs) noexcept
+{
+ static_assert(sizeof...(LhsTail) == sizeof...(RhsTail),
+ // expanded together below, but provide a nicer error message:
+ "The tuple arguments have to have the same size.");
+
+ using Qt::compareThreeWay;
+ using R = std::common_type_t<
+ decltype(compareThreeWay(std::declval<LhsHead>(), std::declval<RhsHead>())),
+ decltype(compareThreeWay(std::declval<LhsTail>(), std::declval<RhsTail>()))...
+ >;
+
+ const auto &l = std::get<0>(lhs);
+ const auto &r = std::get<0>(rhs);
+ static_assert(noexcept(compareThreeWay(l, r)),
+ "This function requires all relational operators to be noexcept.");
+ const auto res = compareThreeWay(l, r);
+ if constexpr (sizeof...(LhsTail) > 0) {
+ if (is_eq(res))
+ return R{compareThreeWayMulti(qt_tuple_pop_front(lhs), qt_tuple_pop_front(rhs))};
+ }
+ return R{res};
+}
+
+} //QtOrderingPrivate
+
+namespace Qt {
+// A wrapper class that adapts the wrappee to use the strongly-ordered
+// <functional> function objects for implementing the relational operators.
+// Mostly useful to avoid UB on pointers (which it currently mandates P to be),
+// because all the comparison helpers (incl. std::compare_three_way on
+// std::tuple<T*>!) will use the language-level operators.
+//
+template <typename P>
+class totally_ordered_wrapper
+{
+ static_assert(std::is_pointer_v<P>);
+ using T = std::remove_pointer_t<P>;
+
+ P ptr;
+public:
+ totally_ordered_wrapper() noexcept = default;
+ Q_IMPLICIT constexpr totally_ordered_wrapper(std::nullptr_t)
+ // requires std::is_pointer_v<P>
+ : totally_ordered_wrapper(P{nullptr}) {}
+ explicit constexpr totally_ordered_wrapper(P p) noexcept : ptr(p) {}
+
+ constexpr P get() const noexcept { return ptr; }
+ constexpr void reset(P p) noexcept { ptr = p; }
+ constexpr P operator->() const noexcept { return get(); }
+ constexpr T& operator*() const noexcept { return *get(); }
+
+ explicit constexpr operator bool() const noexcept { return get(); }
+
+private:
+ // TODO: Replace the constraints with std::common_type_t<P, U> when
+ // a bug in VxWorks is fixed!
+ template <typename T, typename U>
+ using if_compatible_types =
+ std::enable_if_t<std::conjunction_v<std::is_pointer<T>,
+ std::is_pointer<U>,
+ std::disjunction<std::is_convertible<T, U>,
+ std::is_convertible<U, T>>>,
+ bool>;
+
+#define MAKE_RELOP(Ret, op, Op) \
+ template <typename U = P, if_compatible_types<P, U> = true> \
+ friend constexpr Ret operator op (const totally_ordered_wrapper<P> &lhs, const totally_ordered_wrapper<U> &rhs) noexcept \
+ { return std:: Op {}(lhs.ptr, rhs.get()); } \
+ template <typename U = P, if_compatible_types<P, U> = true> \
+ friend constexpr Ret operator op (const totally_ordered_wrapper<P> &lhs, const U &rhs) noexcept \
+ { return std:: Op {}(lhs.ptr, rhs ); } \
+ template <typename U = P, if_compatible_types<P, U> = true> \
+ friend constexpr Ret operator op (const U &lhs, const totally_ordered_wrapper<P> &rhs) noexcept \
+ { return std:: Op {}(lhs, rhs.ptr); } \
+ friend constexpr Ret operator op (const totally_ordered_wrapper &lhs, std::nullptr_t) noexcept \
+ { return std:: Op {}(lhs.ptr, P(nullptr)); } \
+ friend constexpr Ret operator op (std::nullptr_t, const totally_ordered_wrapper &rhs) noexcept \
+ { return std:: Op {}(P(nullptr), rhs.ptr); } \
+ /* end */
+ MAKE_RELOP(bool, ==, equal_to<>)
+ MAKE_RELOP(bool, !=, not_equal_to<>)
+ MAKE_RELOP(bool, < , less<>)
+ MAKE_RELOP(bool, <=, less_equal<>)
+ MAKE_RELOP(bool, > , greater<>)
+ MAKE_RELOP(bool, >=, greater_equal<>)
+#ifdef __cpp_lib_three_way_comparison
+ MAKE_RELOP(auto, <=>, compare_three_way)
+#endif
+#undef MAKE_RELOP
+ friend void qt_ptr_swap(totally_ordered_wrapper &lhs, totally_ordered_wrapper &rhs) noexcept
+ { qt_ptr_swap(lhs.ptr, rhs.ptr); }
+ friend void swap(totally_ordered_wrapper &lhs, totally_ordered_wrapper &rhs) noexcept
+ { qt_ptr_swap(lhs, rhs); }
+ friend size_t qHash(totally_ordered_wrapper key, size_t seed = 0) noexcept
+ { return qHash(key.ptr, seed); }
+};
+
+template <typename T, typename U, if_compatible_pointers<T, U> = true>
+constexpr Qt::strong_ordering
+compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, Qt::totally_ordered_wrapper<U*> rhs) noexcept
+{
+ return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
+}
+
+template <typename T, typename U, if_compatible_pointers<T, U> = true>
+constexpr Qt::strong_ordering
+compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, U *rhs) noexcept
+{
+ return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
+}
+
+template <typename T, typename U, if_compatible_pointers<T, U> = true>
+constexpr Qt::strong_ordering
+compareThreeWay(U *lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
+{
+ return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
+}
+
+template <typename T>
+constexpr Qt::strong_ordering
+compareThreeWay(Qt::totally_ordered_wrapper<T*> lhs, std::nullptr_t rhs) noexcept
+{
+ return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
+}
+
+template <typename T>
+constexpr Qt::strong_ordering
+compareThreeWay(std::nullptr_t lhs, Qt::totally_ordered_wrapper<T*> rhs) noexcept
+{
+ return QtOrderingPrivate::strongOrderingCompareDefaultImpl(lhs, rhs);
+}
+
+} //Qt
+
+template <typename P>
+class QTypeInfo<Qt::totally_ordered_wrapper<P>> : public QTypeInfo<P> {};
+
QT_END_NAMESPACE
+namespace std {
+ template <typename P>
+ struct hash<QT_PREPEND_NAMESPACE(Qt::totally_ordered_wrapper)<P>>
+ {
+ using argument_type = QT_PREPEND_NAMESPACE(Qt::totally_ordered_wrapper)<P>;
+ using result_type = size_t;
+ constexpr result_type operator()(argument_type w) const noexcept
+ { return std::hash<P>{}(w.get()); }
+ };
+}
+
#endif // QCOMPAREHELPERS_H
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 4d80f23786..c2fe4661f6 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -72,6 +72,8 @@
# define QT_FEATURE_linkat -1
#endif
#define QT_FEATURE_lttng -1
+#define QT_FEATURE_memmem -1
+#define QT_FEATURE_memrchr -1
#define QT_NO_QOBJECT
#define QT_FEATURE_process -1
#define QT_FEATURE_regularexpression 1
diff --git a/src/corelib/global/qexceptionhandling.h b/src/corelib/global/qexceptionhandling.h
index 76c6185c3e..7ffd0798f6 100644
--- a/src/corelib/global/qexceptionhandling.h
+++ b/src/corelib/global/qexceptionhandling.h
@@ -28,17 +28,11 @@ Q_NORETURN Q_DECL_COLD_FUNCTION Q_CORE_EXPORT void qTerminate() noexcept;
# define QT_CATCH(A) else
# define QT_THROW(A) qt_noop()
# define QT_RETHROW qt_noop()
-# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
#else
# define QT_TRY try
# define QT_CATCH(A) catch (A)
# define QT_THROW(A) throw A
# define QT_RETHROW throw
-# ifdef Q_COMPILER_NOEXCEPT
-# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
-# else
-# define QT_TERMINATE_ON_EXCEPTION(expr) do { try { expr; } catch (...) { qTerminate(); } } while (false)
-# endif
#endif
QT_END_NAMESPACE
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 222c008f8a..6ce7f97580 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -63,6 +63,7 @@ using namespace Qt::StringLiterals;
\row \li <QFlags> \li Type-safe way of combining enum values
\row \li \l <QForeach> \li Qt's implementation of foreach and forever loops
\row \li \l <QFunctionPointer> \li Typedef for a pointer-to-function type
+ \row \li \l <QApplicationStatic> \li For Q_APPLICATION_STATIC
\row \li <QGlobalStatic> \li Thread-safe initialization of global static objects
\row \li \l <QOverload> \li Helpers for resolving member function overloads
\row \li <QSysInfo> \li A helper class to get system information
@@ -170,6 +171,19 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
}
/*!
+ \macro QT_NO_KEYWORDS
+ \relates <QtGlobal>
+
+ Define this macro to disable the Qt-specific keywords that are usually enabled,
+ such as \c signals and \c slots. Use \c Q_SIGNALS and \c Q_SLOTS instead.
+
+ Libraries should define this macro to make sure that they don't use the generic
+ keywords without the \c Q_ prefix in their public headers.
+
+ \sa QT_NO_FOREACH
+*/
+
+/*!
\macro QT_NAMESPACE
\internal
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 1009057bad..2d70e82370 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -67,8 +67,9 @@
#include <QtCore/qtresource.h>
#include <QtCore/qttranslation.h>
#include <QtCore/qttypetraits.h>
+#if QT_CONFIG(version_tagging)
#include <QtCore/qversiontagging.h>
-
+#endif
#endif /* __cplusplus */
#endif /* QGLOBAL_H */
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 1b03733d2a..e09d2c72e1 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -516,79 +516,122 @@ QLibraryInfoPrivate::LocationInfo QLibraryInfoPrivate::locationInfo(QLibraryInfo
/*!
\since 6.0
Returns the path specified by \a p.
+
+ If there is more than one path listed in qt.conf, it will
+ only return the first one.
+ \sa paths
*/
QString QLibraryInfo::path(LibraryPath p)
{
return QLibraryInfoPrivate::path(p);
}
+/*!
+ \since 6.8
+ Returns all paths specificied by \a p.
-/*
- Returns the path specified by \a p.
-
- The usage mode can be set to UsedFromQtBinDir to enable special handling for executables that
- live in <install-prefix>/bin.
+ \sa path
*/
-QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMode)
+QStringList QLibraryInfo::paths(LibraryPath p)
+{
+ return QLibraryInfoPrivate::paths(p);
+}
+
+static bool keepQtBuildDefaults()
+{
+#if QT_CONFIG(settings)
+ QSettings *config = QLibraryInfoPrivate::configuration();
+ Q_ASSERT(config != nullptr);
+ return config->value("Config/MergeQtConf", false).toBool();
+#else
+ return false;
+#endif
+}
+
+#if QT_CONFIG(settings)
+static QString normalizePath(QString ret)
+{
+ qsizetype startIndex = 0;
+ /* We support placeholders of the form $(<ENV_VAR>) in qt.conf.
+ The loop below tries to find all such placeholders, and replaces
+ them with the actual value of the ENV_VAR environment variable
+ */
+ while (true) {
+ startIndex = ret.indexOf(u'$', startIndex);
+ if (startIndex < 0)
+ break;
+ if (ret.size() < startIndex + 3)
+ break;
+ if (ret.at(startIndex + 1) != u'(') {
+ startIndex++;
+ continue;
+ }
+ qsizetype endIndex = ret.indexOf(u')', startIndex + 2);
+ if (endIndex < 0)
+ break;
+ auto envVarName = QStringView{ret}.sliced(startIndex + 2, endIndex - startIndex - 2);
+ QString value = qEnvironmentVariable(envVarName.toLocal8Bit().constData());
+ ret.replace(startIndex, endIndex - startIndex + 1, value);
+ startIndex += value.size();
+ }
+ return QDir::fromNativeSeparators(ret);
+};
+
+static QVariant libraryPathToValue(QLibraryInfo::LibraryPath loc)
+{
+ QVariant value;
+ auto li = QLibraryInfoPrivate::locationInfo(loc);
+ if (li.key.isNull())
+ return value;
+ QSettings *config = QLibraryInfoPrivate::configuration();
+ Q_ASSERT(config != nullptr);
+ // if keepQtBuildDefaults returns true,
+ // we only consider explicit values listed in qt.conf
+ QVariant defaultValue = keepQtBuildDefaults()
+ ? QVariant()
+ : QVariant(li.defaultValue);
+ config->beginGroup("Paths"_L1);
+ auto cleanup = qScopeGuard([&]() { config->endGroup(); });
+ if (li.fallbackKey.isNull()) {
+ value = config->value(li.key, defaultValue);
+ } else {
+ value = config->value(li.key);
+ if (!value.isValid())
+ value = config->value(li.fallbackKey, defaultValue);
+ }
+ return value;
+}
+#endif // settings
+
+QStringList QLibraryInfoPrivate::paths(QLibraryInfo::LibraryPath p,
+ UsageMode usageMode)
{
const QLibraryInfo::LibraryPath loc = p;
- QString ret;
+ QList<QString> ret;
bool fromConf = false;
#if QT_CONFIG(settings)
if (havePaths()) {
fromConf = true;
- auto li = QLibraryInfoPrivate::locationInfo(loc);
- if (!li.key.isNull()) {
- QSettings *config = QLibraryInfoPrivate::configuration();
- Q_ASSERT(config != nullptr);
- config->beginGroup("Paths"_L1);
-
- if (li.fallbackKey.isNull()) {
- ret = config->value(li.key, li.defaultValue).toString();
- } else {
- QVariant v = config->value(li.key);
- if (!v.isValid())
- v = config->value(li.fallbackKey, li.defaultValue);
- ret = v.toString();
- }
-
- qsizetype startIndex = 0;
- /* We support placeholders of the form $(<ENV_VAR>) in qt.conf.
- The loop below tries to find all such placeholders, and replaces
- them with the actual value of the ENV_VAR environment variable
- */
- while (true) {
- startIndex = ret.indexOf(u'$', startIndex);
- if (startIndex < 0)
- break;
- if (ret.size() < startIndex + 3)
- break;
- if (ret.at(startIndex + 1) != u'(') {
- startIndex++;
- continue;
- }
- qsizetype endIndex = ret.indexOf(u')', startIndex + 2);
- if (endIndex < 0)
- break;
- auto envVarName = QStringView{ret}.mid(startIndex + 2, endIndex - startIndex - 2);
- QString value = QString::fromLocal8Bit(qgetenv(envVarName.toLocal8Bit().constData()));
- ret.replace(startIndex, endIndex - startIndex + 1, value);
- startIndex += value.size();
- }
-
- config->endGroup();
+ QVariant value = libraryPathToValue(loc);
+ if (value.isValid()) {
- ret = QDir::fromNativeSeparators(ret);
+ if (auto *asList = get_if<QList<QString>>(&value))
+ ret = std::move(*asList);
+ else
+ ret = QList<QString>({ std::move(value).toString()});
+ for (qsizetype i = 0, end = ret.size(); i < end; ++i)
+ ret[i] = normalizePath(ret[i]);
}
}
#endif // settings
- if (!fromConf) {
+ if (!fromConf || keepQtBuildDefaults()) {
+ QString noConfResult;
if (loc == QLibraryInfo::PrefixPath) {
- ret = getPrefix(usageMode);
+ noConfResult = getPrefix(usageMode);
} else if (int(loc) <= qt_configure_strs.count()) {
- ret = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1));
+ noConfResult = QString::fromLocal8Bit(qt_configure_strs.viewAt(loc - 1));
#ifndef Q_OS_WIN // On Windows we use the registry
} else if (loc == QLibraryInfo::SettingsPath) {
// Use of volatile is a hack to discourage compilers from calling
@@ -596,24 +639,39 @@ QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMo
// compile-time, as Qt installers binary-patch the path, replacing
// the dummy path seen at compile-time, typically changing length.
const char *volatile path = QT_CONFIGURE_SETTINGS_PATH;
- ret = QString::fromLocal8Bit(path);
+ noConfResult = QString::fromLocal8Bit(path);
#endif
}
+ if (!noConfResult.isEmpty())
+ ret.push_back(std::move(noConfResult));
}
+ if (ret.isEmpty())
+ return ret;
- if (!ret.isEmpty() && QDir::isRelativePath(ret)) {
- QString baseDir;
- if (loc == QLibraryInfo::PrefixPath) {
- baseDir = prefixFromAppDirHelper();
- } else {
- // we make any other path absolute to the prefix directory
- baseDir = path(QLibraryInfo::PrefixPath, usageMode);
- }
- ret = QDir::cleanPath(baseDir + u'/' + ret);
+ QString baseDir;
+ if (loc == QLibraryInfo::PrefixPath) {
+ baseDir = prefixFromAppDirHelper();
+ } else {
+ // we make any other path absolute to the prefix directory
+ baseDir = QLibraryInfoPrivate::path(QLibraryInfo::PrefixPath, usageMode);
}
+ for (qsizetype i = 0, end = ret.size(); i < end; ++i)
+ if (QDir::isRelativePath(ret[i]))
+ ret[i] = QDir::cleanPath(baseDir + u'/' + std::move(ret[i]));
return ret;
}
+/*
+ Returns the path specified by \a p.
+
+ The usage mode can be set to UsedFromQtBinDir to enable special handling for executables that
+ live in <install-prefix>/bin.
+ */
+QString QLibraryInfoPrivate::path(QLibraryInfo::LibraryPath p, UsageMode usageMode)
+{
+ return paths(p, usageMode).value(0, QString());
+}
+
/*!
Returns additional arguments to the platform plugin matching
\a platformName which can be specified as a string list using
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index d4e8f8b050..6cac6c83b0 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -42,6 +42,7 @@ public:
SettingsPath = 100
};
static QString path(LibraryPath p);
+ static QStringList paths(LibraryPath p);
#if QT_DEPRECATED_SINCE(6, 0)
using LibraryLocation = LibraryPath;
QT_DEPRECATED_VERSION_X_6_0("Use path()")
diff --git a/src/corelib/global/qlibraryinfo_p.h b/src/corelib/global/qlibraryinfo_p.h
index 4b471b932e..b9ca6b4d18 100644
--- a/src/corelib/global/qlibraryinfo_p.h
+++ b/src/corelib/global/qlibraryinfo_p.h
@@ -50,6 +50,7 @@ public:
};
static QString path(QLibraryInfo::LibraryPath p, UsageMode usageMode = RegularUsage);
+ static QList<QString> paths(QLibraryInfo::LibraryPath p, UsageMode usageMode = RegularUsage);
};
QT_END_NAMESPACE
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index dec16e4a77..efeec37094 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -834,7 +834,7 @@ void QMessageLogger::fatal(const QLoggingCategory &cat, const char *msg, ...) co
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ qt_message(QtFatalMsg, ctxt, msg, ap);
va_end(ap);
#ifndef Q_CC_MSVC_ONLY
@@ -858,7 +858,7 @@ void QMessageLogger::fatal(QMessageLogger::CategoryFunction catFunc,
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ qt_message(QtFatalMsg, ctxt, msg, ap);
va_end(ap);
#ifndef Q_CC_MSVC_ONLY
@@ -877,7 +877,7 @@ void QMessageLogger::fatal(const char *msg, ...) const noexcept
QInternalMessageLogContext ctxt(context);
va_list ap;
va_start(ap, msg); // use variable arg list
- QT_TERMINATE_ON_EXCEPTION(qt_message(QtFatalMsg, ctxt, msg, ap));
+ qt_message(QtFatalMsg, ctxt, msg, ap);
va_end(ap);
#ifndef Q_CC_MSVC_ONLY
@@ -2621,7 +2621,7 @@ QMessageLogContext &QMessageLogContext::copyContextFrom(const QMessageLogContext
This enum describes the messages that can be sent to a message
handler (QtMessageHandler). You can use the enum to identify and
associate the various message types with the appropriate
- actions.
+ actions. Its values are, in order of increasing severity:
\value QtDebugMsg
A message generated by the qDebug() function.
@@ -2635,8 +2635,6 @@ QMessageLogContext &QMessageLogContext::copyContextFrom(const QMessageLogContext
A message generated by the qFatal() function.
\omitvalue QtSystemMsg
- \c QtInfoMsg was added in Qt 5.5.
-
\sa QtMessageHandler, qInstallMessageHandler()
*/
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index aa0ab93a2d..b4ec1a1235 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -28,10 +28,11 @@ class QNoDebug;
enum QtMsgType {
QtDebugMsg,
+ QT7_ONLY(QtInfoMsg,)
QtWarningMsg,
QtCriticalMsg,
QtFatalMsg,
- QtInfoMsg,
+ QT6_ONLY(QtInfoMsg,)
#if QT_DEPRECATED_SINCE(6, 7)
QtSystemMsg Q_DECL_ENUMERATOR_DEPRECATED_X("Use QtCriticalMsg instead.") = QtCriticalMsg
#endif
diff --git a/src/corelib/global/qminmax.h b/src/corelib/global/qminmax.h
index e6fb62bf9d..fca13e047e 100644
--- a/src/corelib/global/qminmax.h
+++ b/src/corelib/global/qminmax.h
@@ -11,31 +11,10 @@
#include <QtCore/qassert.h>
#include <QtCore/qtconfigmacros.h>
-
-#include <type_traits>
+#include <QtCore/qttypetraits.h>
QT_BEGIN_NAMESPACE
-namespace QTypeTraits {
-
-namespace detail {
-template<typename T, typename U,
- typename = std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U> &&
- std::is_floating_point_v<T> == std::is_floating_point_v<U> &&
- std::is_signed_v<T> == std::is_signed_v<U> &&
- !std::is_same_v<T, bool> && !std::is_same_v<U, bool> &&
- !std::is_same_v<T, char> && !std::is_same_v<U, char>>>
-struct Promoted
-{
- using type = decltype(T() + U());
-};
-}
-
-template <typename T, typename U>
-using Promoted = typename detail::Promoted<T, U>::type;
-
-}
-
template <typename T>
constexpr inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; }
template <typename T>
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 2398c0a1a4..b81ad1375d 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -423,7 +423,7 @@ namespace Qt {
enum ApplicationAttribute
{
// AA_ImmediateWidgetCreation = 0,
- AA_QtQuickUseDefaultSizePolicy = 1 QT_TECH_PREVIEW_API,
+ AA_QtQuickUseDefaultSizePolicy = 1,
AA_DontShowIconsInMenus = 2,
AA_NativeWindows = 3,
AA_DontCreateNativeWidgetSiblings = 4,
@@ -462,7 +462,7 @@ namespace Qt {
AA_DisableShaderDiskCache = 27,
AA_DontShowShortcutsInContextMenus = 28,
AA_CompressTabletEvents = 29,
- AA_DontUsePopupWindows = 30,
+ // AA_DisableWindowContextHelpButton = 30, (in Qt 5)
AA_DisableSessionManager = 31,
// Add new attributes before this line
@@ -1356,6 +1356,11 @@ namespace Qt {
PreventContextMenu
};
+ enum class ContextMenuTrigger {
+ Press,
+ Release,
+ };
+
enum InputMethodQuery {
ImEnabled = 0x1,
ImCursorRectangle = 0x2,
@@ -1731,6 +1736,7 @@ namespace Qt {
Q_ENUM_NS(ScrollBarPolicy)
Q_ENUM_NS(FocusPolicy)
Q_ENUM_NS(ContextMenuPolicy)
+ Q_ENUM_NS(ContextMenuTrigger)
Q_ENUM_NS(ArrowType)
Q_ENUM_NS(ToolButtonStyle)
Q_ENUM_NS(PenStyle)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index ddfade675a..64da69c0ac 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -93,13 +93,13 @@
with the layout can be overridden by explicitly setting
\l{Layout::fillWidth}{Layout.fillWidth} or
\l{Layout::fillHeight}{Layout.fillHeight}.
- \b Note: This API is considered tech preview and may change or be removed in future
- versions of Qt.
-
\value AA_DontShowIconsInMenus Actions with the Icon property won't be
shown in any menus unless specifically set by the
- QAction::iconVisibleInMenu property.
+ QAction::iconVisibleInMenu property. The default value of this
+ attribute depends on the platform. To override the default
+ behavior, set the attribute after QGuiApplication has been
+ instantiated.
Menus that are currently open or menus already created in the native
\macos menubar \e{may not} pick up a change in this attribute. Changes
in the QAction::iconVisibleInMenu property will always be picked up.
@@ -279,11 +279,6 @@
level windows, unless required by the implementation.
This value was added in Qt 6.8.
- \value AA_DontUsePopupWindows When this attribute is set, popups will always appear
- as items in the scene, rather than having their own dedicated windows.
- Setting this attribute will only affect Qt Quick applications.
- This value was added in Qt 6.8.
-
\omitvalue AA_AttributeCount
\omitvalue AA_EnableHighDpiScaling
\omitvalue AA_UseHighDpiPixmaps
@@ -2087,6 +2082,18 @@
*/
/*!
+ \enum Qt::ContextMenuTrigger
+ \since 6.8
+
+ This enum type defines the mouse event used to trigger a context menu event.
+
+ \value Press context menu on mouse press event, default on UNIX systems.
+ \value Release context menu on mouse release event, default on Windows.
+
+ \sa QStyleHints::contextMenuTrigger
+*/
+
+/*!
\enum Qt::FocusPolicy
This enum type defines the various policies a widget can have with
@@ -3251,7 +3258,7 @@
The underlying type is \c int. You can use \l qToUnderlying() to convert
Qt::TimerId to \c int.
- \value Invalid Represents a no-op timer ID; it's usage depends on the
+ \value Invalid Represents a no-op timer ID; its usage depends on the
context, for example, this is the value returned by QObject::startTimer()
to indicate it failed to start a timer; whereas QChronoTimer::id() returns
this value when the timer is inactive, that is, \c timer.isActive()
diff --git a/src/corelib/global/qnativeinterface_p.h b/src/corelib/global/qnativeinterface_p.h
index aa7705e153..c6d216460a 100644
--- a/src/corelib/global/qnativeinterface_p.h
+++ b/src/corelib/global/qnativeinterface_p.h
@@ -21,7 +21,7 @@
QT_BEGIN_NAMESPACE
namespace QtPrivate {
-Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcNativeInterface, Q_CORE_EXPORT)
+QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(lcNativeInterface, Q_CORE_EXPORT)
}
// Provides a definition for the interface destructor
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index cf6063fca0..98e2f57357 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -565,6 +565,12 @@ const QOperatingSystemVersionBase QOperatingSystemVersion::MacOSVentura;
*/
/*!
+ \variable QOperatingSystemVersion::MacOSSequoia
+ \brief a version corresponding to macOS Sequoia (version 15).
+ \since 6.8
+*/
+
+/*!
\variable QOperatingSystemVersion::AndroidJellyBean
\brief a version corresponding to Android Jelly Bean (version 4.1, API level 16).
\since 5.9
diff --git a/src/corelib/global/qoperatingsystemversion.h b/src/corelib/global/qoperatingsystemversion.h
index a9f30dc275..7a32fc93a9 100644
--- a/src/corelib/global/qoperatingsystemversion.h
+++ b/src/corelib/global/qoperatingsystemversion.h
@@ -142,6 +142,7 @@ class QOperatingSystemVersion : public QOperatingSystemVersionBase
// ### Qt7: Regroup with the rest below
static constexpr QOperatingSystemVersionBase MacOSSonoma { QOperatingSystemVersionBase::MacOS, 14, 0 };
+ static constexpr QOperatingSystemVersionBase MacOSSequoia { QOperatingSystemVersionBase::MacOS, 15, 0 };
static constexpr QOperatingSystemVersionBase Android14 { QOperatingSystemVersionBase::Android, 14, 0 };
static constexpr QOperatingSystemVersionBase Windows11_23H2 { QOperatingSystemVersionBase::Windows, 10, 0, 22631 };
diff --git a/src/corelib/global/qtconfigmacros.h b/src/corelib/global/qtconfigmacros.h
index 018161eac4..b643122d5c 100644
--- a/src/corelib/global/qtconfigmacros.h
+++ b/src/corelib/global/qtconfigmacros.h
@@ -9,6 +9,8 @@
#endif
#include <QtCore/qtconfiginclude.h>
+#include <QtCore/qtdeprecationdefinitions.h>
+#include <QtCore/qtversionchecks.h>
#include <assert.h>
diff --git a/src/corelib/global/qtdeprecationdefinitions.h.in b/src/corelib/global/qtdeprecationdefinitions.h.in
new file mode 100644
index 0000000000..0570f63a5a
--- /dev/null
+++ b/src/corelib/global/qtdeprecationdefinitions.h.in
@@ -0,0 +1,28 @@
+// Copyright (C) 2024 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 QTDEPRECATIONDEFINITIONS_H
+#define QTDEPRECATIONDEFINITIONS_H
+
+#ifndef QT_DISABLE_DEPRECATED_UP_TO
+# ifdef QT_DISABLE_DEPRECATED_BEFORE // If the deprecated macro is defined, use its value
+# define QT_DISABLE_DEPRECATED_UP_TO QT_DISABLE_DEPRECATED_BEFORE
+# else
+# define QT_DISABLE_DEPRECATED_UP_TO @QT_DISABLE_DEPRECATED_UP_TO@
+# endif
+#endif
+
+#if QT_DISABLE_DEPRECATED_UP_TO < @QT_DISABLE_DEPRECATED_UP_TO@
+# warning QT_DISABLE_DEPRECATED_UP_TO is set to the version that is lower than the version that \
+ Qt was built with. This may lead to linking issues.
+#endif
+
+#ifndef QT_WARN_DEPRECATED_UP_TO
+# ifdef QT_DEPRECATED_WARNINGS_SINCE // If the deprecated macro is defined, use its value
+# define QT_WARN_DEPRECATED_UP_TO QT_DEPRECATED_WARNINGS_SINCE
+# else
+# define QT_WARN_DEPRECATED_UP_TO @QT_WARN_DEPRECATED_UP_TO@
+# endif
+#endif
+
+#endif // QTDEPRECATIONDEFINITIONS_H
diff --git a/src/corelib/global/qtdeprecationmarkers.h b/src/corelib/global/qtdeprecationmarkers.h
index 6df5ebce6d..68f4fda186 100644
--- a/src/corelib/global/qtdeprecationmarkers.h
+++ b/src/corelib/global/qtdeprecationmarkers.h
@@ -5,6 +5,7 @@
#define QTDEPRECATIONMARKERS_H
#include <QtCore/qtconfigmacros.h>
+#include <QtCore/qtdeprecationdefinitions.h>
#include <QtCore/qtversionchecks.h>
#include <QtCore/qcompilerdetection.h> // for Q_DECL_DEPRECATED
@@ -44,28 +45,6 @@ QT_BEGIN_NAMESPACE
# define Q_DECL_ENUMERATOR_DEPRECATED_X(ignored)
#endif
-// If the deprecated macro is defined, use its value
-#if !defined(QT_DISABLE_DEPRECATED_UP_TO) && defined(QT_DISABLE_DEPRECATED_BEFORE)
-# define QT_DISABLE_DEPRECATED_UP_TO QT_DISABLE_DEPRECATED_BEFORE
-#endif
-
-// If the deprecated macro is defined, use its value
-#if !defined(QT_WARN_DEPRECATED_UP_TO) && defined(QT_DEPRECATED_WARNINGS_SINCE)
-# define QT_WARN_DEPRECATED_UP_TO QT_DEPRECATED_WARNINGS_SINCE
-#endif
-
-#ifndef QT_WARN_DEPRECATED_UP_TO
-# ifdef QT_DISABLE_DEPRECATED_UP_TO
-# define QT_WARN_DEPRECATED_UP_TO QT_DISABLE_DEPRECATED_UP_TO
-# else
-# define QT_WARN_DEPRECATED_UP_TO QT_VERSION
-# endif
-#endif
-
-#ifndef QT_DISABLE_DEPRECATED_UP_TO
-#define QT_DISABLE_DEPRECATED_UP_TO QT_VERSION_CHECK(5, 0, 0)
-#endif
-
/*
QT_DEPRECATED_SINCE(major, minor) evaluates as true if the Qt version is greater than
the deprecation point specified.
diff --git a/src/corelib/global/qttypetraits.h b/src/corelib/global/qttypetraits.h
index 1efb24bf70..2cd68c73cb 100644
--- a/src/corelib/global/qttypetraits.h
+++ b/src/corelib/global/qttypetraits.h
@@ -7,8 +7,11 @@
#include <QtCore/qtconfigmacros.h>
#include <QtCore/qtdeprecationmarkers.h>
+#include <optional>
+#include <tuple>
#include <type_traits>
#include <utility>
+#include <variant>
#if 0
#pragma qt_class(QtTypeTraits)
@@ -60,6 +63,212 @@ template <typename T> struct type_dependent_false : std::false_type {};
template <auto T> struct value_dependent_false : std::false_type {};
}
+namespace QTypeTraits {
+
+namespace detail {
+template<typename T, typename U,
+ typename = std::enable_if_t<std::is_arithmetic_v<T> && std::is_arithmetic_v<U> &&
+ std::is_floating_point_v<T> == std::is_floating_point_v<U> &&
+ std::is_signed_v<T> == std::is_signed_v<U> &&
+ !std::is_same_v<T, bool> && !std::is_same_v<U, bool> &&
+ !std::is_same_v<T, char> && !std::is_same_v<U, char>>>
+struct Promoted
+{
+ using type = decltype(T() + U());
+};
+}
+
+template <typename T, typename U>
+using Promoted = typename detail::Promoted<T, U>::type;
+
+/*
+ The templates below aim to find out whether one can safely instantiate an operator==() or
+ operator<() for a type.
+
+ This is tricky for containers, as most containers have unconstrained comparison operators, even though they
+ rely on the corresponding operators for its content.
+ This is especially true for all of the STL template classes that have a comparison operator defined, and
+ leads to the situation, that the compiler would try to instantiate the operator, and fail if any
+ of its template arguments does not have the operator implemented.
+
+ The code tries to cover the relevant cases for Qt and the STL, by checking (recusrsively) the value_type
+ of a container (if it exists), and checking the template arguments of pair, tuple and variant.
+*/
+namespace detail {
+
+// find out whether T is a conteiner
+// this is required to check the value type of containers for the existence of the comparison operator
+template <typename, typename = void>
+struct is_container : std::false_type {};
+template <typename T>
+struct is_container<T, std::void_t<
+ typename T::value_type,
+ std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>
+>> : std::true_type {};
+
+
+// Checks the existence of the comparison operator for the class itself
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_FLOAT_COMPARE
+template <typename, typename = void>
+struct has_operator_equal : std::false_type {};
+template <typename T>
+struct has_operator_equal<T, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const T&>()))>>
+ : std::true_type {};
+QT_WARNING_POP
+
+// Two forward declarations
+template<typename T, bool = is_container<T>::value>
+struct expand_operator_equal_container;
+template<typename T>
+struct expand_operator_equal_tuple;
+
+// the entry point for the public method
+template<typename T>
+using expand_operator_equal = expand_operator_equal_container<T>;
+
+// if T isn't a container check if it's a tuple like object
+template<typename T, bool>
+struct expand_operator_equal_container : expand_operator_equal_tuple<T> {};
+// if T::value_type exists, check first T::value_type, then T itself
+template<typename T>
+struct expand_operator_equal_container<T, true> :
+ std::conjunction<
+ std::disjunction<
+ std::is_same<T, typename T::value_type>, // avoid endless recursion
+ expand_operator_equal<typename T::value_type>
+ >, expand_operator_equal_tuple<T>> {};
+
+// recursively check the template arguments of a tuple like object
+template<typename ...T>
+using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T>...>;
+
+template<typename T>
+struct expand_operator_equal_tuple : has_operator_equal<T> {};
+template<typename T>
+struct expand_operator_equal_tuple<std::optional<T>> : expand_operator_equal_recursive<T> {};
+template<typename T1, typename T2>
+struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
+template<typename ...T>
+struct expand_operator_equal_tuple<std::tuple<T...>> : expand_operator_equal_recursive<T...> {};
+template<typename ...T>
+struct expand_operator_equal_tuple<std::variant<T...>> : expand_operator_equal_recursive<T...> {};
+
+// the same for operator<(), see above for explanations
+template <typename, typename = void>
+struct has_operator_less_than : std::false_type{};
+template <typename T>
+struct has_operator_less_than<T, std::void_t<decltype(bool(std::declval<const T&>() < std::declval<const T&>()))>>
+ : std::true_type{};
+
+template<typename T, bool = is_container<T>::value>
+struct expand_operator_less_than_container;
+template<typename T>
+struct expand_operator_less_than_tuple;
+
+template<typename T>
+using expand_operator_less_than = expand_operator_less_than_container<T>;
+
+template<typename T, bool>
+struct expand_operator_less_than_container : expand_operator_less_than_tuple<T> {};
+template<typename T>
+struct expand_operator_less_than_container<T, true> :
+ std::conjunction<
+ std::disjunction<
+ std::is_same<T, typename T::value_type>,
+ expand_operator_less_than<typename T::value_type>
+ >, expand_operator_less_than_tuple<T>
+ > {};
+
+template<typename ...T>
+using expand_operator_less_than_recursive = std::conjunction<expand_operator_less_than<T>...>;
+
+template<typename T>
+struct expand_operator_less_than_tuple : has_operator_less_than<T> {};
+template<typename T>
+struct expand_operator_less_than_tuple<std::optional<T>> : expand_operator_less_than_recursive<T> {};
+template<typename T1, typename T2>
+struct expand_operator_less_than_tuple<std::pair<T1, T2>> : expand_operator_less_than_recursive<T1, T2> {};
+template<typename ...T>
+struct expand_operator_less_than_tuple<std::tuple<T...>> : expand_operator_less_than_recursive<T...> {};
+template<typename ...T>
+struct expand_operator_less_than_tuple<std::variant<T...>> : expand_operator_less_than_recursive<T...> {};
+
+}
+
+template<typename T, typename = void>
+struct is_dereferenceable : std::false_type {};
+
+template<typename T>
+struct is_dereferenceable<T, std::void_t<decltype(std::declval<T>().operator->())> >
+ : std::true_type {};
+
+template <typename T>
+inline constexpr bool is_dereferenceable_v = is_dereferenceable<T>::value;
+
+template<typename T>
+struct has_operator_equal : detail::expand_operator_equal<T> {};
+template<typename T>
+inline constexpr bool has_operator_equal_v = has_operator_equal<T>::value;
+
+template <typename Container, typename T>
+using has_operator_equal_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T>>;
+
+template<typename T>
+struct has_operator_less_than : detail::expand_operator_less_than<T> {};
+template<typename T>
+inline constexpr bool has_operator_less_than_v = has_operator_less_than<T>::value;
+
+template <typename Container, typename T>
+using has_operator_less_than_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_less_than<T>>;
+
+template <typename ...T>
+using compare_eq_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal<T>...>, bool>;
+
+template <typename Container, typename ...T>
+using compare_eq_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal_container<Container, T>...>, bool>;
+
+template <typename ...T>
+using compare_lt_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than<T>...>, bool>;
+
+template <typename Container, typename ...T>
+using compare_lt_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>...>, bool>;
+
+namespace detail {
+
+template<typename T>
+const T &const_reference();
+template<typename T>
+T &reference();
+
+}
+
+template <typename Stream, typename, typename = void>
+struct has_ostream_operator : std::false_type {};
+template <typename Stream, typename T>
+struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() << detail::const_reference<T>())>>
+ : std::true_type {};
+template <typename Stream, typename T>
+inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value;
+
+template <typename Stream, typename Container, typename T>
+using has_ostream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_ostream_operator<Stream, T>>;
+
+template <typename Stream, typename, typename = void>
+struct has_istream_operator : std::false_type {};
+template <typename Stream, typename T>
+struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>>
+ : std::true_type {};
+template <typename Stream, typename T>
+inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value;
+template <typename Stream, typename Container, typename T>
+using has_istream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_istream_operator<Stream, T>>;
+
+template <typename Stream, typename T>
+inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>;
+
+} // namespace QTypeTraits
+
QT_END_NAMESPACE
#endif // QTTYPETRAITS_H
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 255a2b33c6..e9dfbc34a4 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -8,9 +8,6 @@
#include <QtCore/qcompilerdetection.h>
#include <QtCore/qcontainerfwd.h>
-#include <variant>
-#include <optional>
-#include <tuple>
#include <type_traits>
QT_BEGIN_NAMESPACE
@@ -186,197 +183,5 @@ template<typename T> class QFlags;
template<typename T>
Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
-namespace QTypeTraits
-{
-
-/*
- The templates below aim to find out whether one can safely instantiate an operator==() or
- operator<() for a type.
-
- This is tricky for containers, as most containers have unconstrained comparison operators, even though they
- rely on the corresponding operators for its content.
- This is especially true for all of the STL template classes that have a comparison operator defined, and
- leads to the situation, that the compiler would try to instantiate the operator, and fail if any
- of its template arguments does not have the operator implemented.
-
- The code tries to cover the relevant cases for Qt and the STL, by checking (recusrsively) the value_type
- of a container (if it exists), and checking the template arguments of pair, tuple and variant.
-*/
-namespace detail {
-
-// find out whether T is a conteiner
-// this is required to check the value type of containers for the existence of the comparison operator
-template <typename, typename = void>
-struct is_container : std::false_type {};
-template <typename T>
-struct is_container<T, std::void_t<
- typename T::value_type,
- std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>
->> : std::true_type {};
-
-
-// Checks the existence of the comparison operator for the class itself
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_FLOAT_COMPARE
-template <typename, typename = void>
-struct has_operator_equal : std::false_type {};
-template <typename T>
-struct has_operator_equal<T, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const T&>()))>>
- : std::true_type {};
-QT_WARNING_POP
-
-// Two forward declarations
-template<typename T, bool = is_container<T>::value>
-struct expand_operator_equal_container;
-template<typename T>
-struct expand_operator_equal_tuple;
-
-// the entry point for the public method
-template<typename T>
-using expand_operator_equal = expand_operator_equal_container<T>;
-
-// if T isn't a container check if it's a tuple like object
-template<typename T, bool>
-struct expand_operator_equal_container : expand_operator_equal_tuple<T> {};
-// if T::value_type exists, check first T::value_type, then T itself
-template<typename T>
-struct expand_operator_equal_container<T, true> :
- std::conjunction<
- std::disjunction<
- std::is_same<T, typename T::value_type>, // avoid endless recursion
- expand_operator_equal<typename T::value_type>
- >, expand_operator_equal_tuple<T>> {};
-
-// recursively check the template arguments of a tuple like object
-template<typename ...T>
-using expand_operator_equal_recursive = std::conjunction<expand_operator_equal<T>...>;
-
-template<typename T>
-struct expand_operator_equal_tuple : has_operator_equal<T> {};
-template<typename T>
-struct expand_operator_equal_tuple<std::optional<T>> : expand_operator_equal_recursive<T> {};
-template<typename T1, typename T2>
-struct expand_operator_equal_tuple<std::pair<T1, T2>> : expand_operator_equal_recursive<T1, T2> {};
-template<typename ...T>
-struct expand_operator_equal_tuple<std::tuple<T...>> : expand_operator_equal_recursive<T...> {};
-template<typename ...T>
-struct expand_operator_equal_tuple<std::variant<T...>> : expand_operator_equal_recursive<T...> {};
-
-// the same for operator<(), see above for explanations
-template <typename, typename = void>
-struct has_operator_less_than : std::false_type{};
-template <typename T>
-struct has_operator_less_than<T, std::void_t<decltype(bool(std::declval<const T&>() < std::declval<const T&>()))>>
- : std::true_type{};
-
-template<typename T, bool = is_container<T>::value>
-struct expand_operator_less_than_container;
-template<typename T>
-struct expand_operator_less_than_tuple;
-
-template<typename T>
-using expand_operator_less_than = expand_operator_less_than_container<T>;
-
-template<typename T, bool>
-struct expand_operator_less_than_container : expand_operator_less_than_tuple<T> {};
-template<typename T>
-struct expand_operator_less_than_container<T, true> :
- std::conjunction<
- std::disjunction<
- std::is_same<T, typename T::value_type>,
- expand_operator_less_than<typename T::value_type>
- >, expand_operator_less_than_tuple<T>
- > {};
-
-template<typename ...T>
-using expand_operator_less_than_recursive = std::conjunction<expand_operator_less_than<T>...>;
-
-template<typename T>
-struct expand_operator_less_than_tuple : has_operator_less_than<T> {};
-template<typename T>
-struct expand_operator_less_than_tuple<std::optional<T>> : expand_operator_less_than_recursive<T> {};
-template<typename T1, typename T2>
-struct expand_operator_less_than_tuple<std::pair<T1, T2>> : expand_operator_less_than_recursive<T1, T2> {};
-template<typename ...T>
-struct expand_operator_less_than_tuple<std::tuple<T...>> : expand_operator_less_than_recursive<T...> {};
-template<typename ...T>
-struct expand_operator_less_than_tuple<std::variant<T...>> : expand_operator_less_than_recursive<T...> {};
-
-}
-
-template<typename T, typename = void>
-struct is_dereferenceable : std::false_type {};
-
-template<typename T>
-struct is_dereferenceable<T, std::void_t<decltype(std::declval<T>().operator->())> >
- : std::true_type {};
-
-template <typename T>
-inline constexpr bool is_dereferenceable_v = is_dereferenceable<T>::value;
-
-template<typename T>
-struct has_operator_equal : detail::expand_operator_equal<T> {};
-template<typename T>
-inline constexpr bool has_operator_equal_v = has_operator_equal<T>::value;
-
-template <typename Container, typename T>
-using has_operator_equal_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_equal<T>>;
-
-template<typename T>
-struct has_operator_less_than : detail::expand_operator_less_than<T> {};
-template<typename T>
-inline constexpr bool has_operator_less_than_v = has_operator_less_than<T>::value;
-
-template <typename Container, typename T>
-using has_operator_less_than_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_operator_less_than<T>>;
-
-template <typename ...T>
-using compare_eq_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal<T>...>, bool>;
-
-template <typename Container, typename ...T>
-using compare_eq_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_equal_container<Container, T>...>, bool>;
-
-template <typename ...T>
-using compare_lt_result = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than<T>...>, bool>;
-
-template <typename Container, typename ...T>
-using compare_lt_result_container = std::enable_if_t<std::conjunction_v<QTypeTraits::has_operator_less_than_container<Container, T>...>, bool>;
-
-namespace detail {
-
-template<typename T>
-const T &const_reference();
-template<typename T>
-T &reference();
-
-}
-
-template <typename Stream, typename, typename = void>
-struct has_ostream_operator : std::false_type {};
-template <typename Stream, typename T>
-struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() << detail::const_reference<T>())>>
- : std::true_type {};
-template <typename Stream, typename T>
-inline constexpr bool has_ostream_operator_v = has_ostream_operator<Stream, T>::value;
-
-template <typename Stream, typename Container, typename T>
-using has_ostream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_ostream_operator<Stream, T>>;
-
-template <typename Stream, typename, typename = void>
-struct has_istream_operator : std::false_type {};
-template <typename Stream, typename T>
-struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<Stream>() >> detail::reference<T>())>>
- : std::true_type {};
-template <typename Stream, typename T>
-inline constexpr bool has_istream_operator_v = has_istream_operator<Stream, T>::value;
-template <typename Stream, typename Container, typename T>
-using has_istream_operator_container = std::disjunction<std::is_base_of<Container, T>, QTypeTraits::has_istream_operator<Stream, T>>;
-
-template <typename Stream, typename T>
-inline constexpr bool has_stream_operator_v = has_ostream_operator_v<Stream, T> && has_istream_operator_v<Stream, T>;
-
-}
-
-
QT_END_NAMESPACE
#endif // QTYPEINFO_H
diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h
index 965d53e88f..fa2dd23728 100644
--- a/src/corelib/global/qversiontagging.h
+++ b/src/corelib/global/qversiontagging.h
@@ -13,6 +13,8 @@
#include <QtCore/qtversionchecks.h>
#include <QtCore/qtypes.h>
+QT_REQUIRE_CONFIG(version_tagging);
+
QT_BEGIN_NAMESPACE
/*