diff options
author | Marc Mutz <[email protected]> | 2024-05-29 09:33:39 +0200 |
---|---|---|
committer | Marc Mutz <[email protected]> | 2024-06-04 11:31:56 +0000 |
commit | b2eb422699118f4ae8370519b4c7bb3fe121beb2 (patch) | |
tree | ab02a3aff638130567cdc04e3852542c12b78f0f | |
parent | cc89c4c76567184b2887952dfe44375ff3ebd28d (diff) |
qtypeinfo.h: move QTypeTraits part to qttypetraits.h
Makes sense to collect the stuff in a similarly-named header, and it's
not like any of the QTypeTraits stuff was needed for QTypeInfo.
Makes #include <qtypeinfo.h> _much_ lighter again, at the expense of
qminmax.h now getting <variant>, <tuple> and <optional> instead, but
qminmax.h is much easier to avoid in Qt headers (just use the std
versions) than qtypeinfo.h.
[ChangeLog][QtCore][Potentially Source-Incompatible Changes] The
qtypeinfo.h header no longer transitively includes <optional>, <tuple>
and <variant>.
Task-number: QTBUG-97601
Pick-to: 6.8
Change-Id: Ied96113f38c1232fef3ec79847ee62f06c68f268
Reviewed-by: Fabian Kosmale <[email protected]>
-rw-r--r-- | src/corelib/global/qttypetraits.h | 189 | ||||
-rw-r--r-- | src/corelib/global/qtypeinfo.h | 195 | ||||
-rw-r--r-- | src/corelib/io/qdebug.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qpropertyprivate.h | 1 | ||||
-rw-r--r-- | src/corelib/serialization/qdatastream.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qcontiguouscache.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qhash.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qlist.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qmap.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qset.h | 1 | ||||
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 1 | ||||
-rw-r--r-- | src/testlib/qtesttostring.h | 2 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 2 |
15 files changed, 204 insertions, 195 deletions
diff --git a/src/corelib/global/qttypetraits.h b/src/corelib/global/qttypetraits.h index 35dfad155bf..2cd68c73cbe 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) @@ -78,6 +81,192 @@ struct Promoted 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 diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 255a2b33c61..e9dfbc34a4f 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/io/qdebug.h b/src/corelib/io/qdebug.h index 4797bcd169f..44c3dea804b 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -11,6 +11,7 @@ #include <QtCore/qcontainerfwd.h> #include <QtCore/qtextstream.h> +#include <QtCore/qttypetraits.h> #include <QtCore/qtypes.h> #include <QtCore/qstring.h> #include <QtCore/qcontiguouscache.h> diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 12a67aef584..1e944660c61 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -18,6 +18,7 @@ #include <QtCore/qobjectdefs.h> #endif #include <QtCore/qscopeguard.h> +#include <QtCore/qttypetraits.h> #include <array> #include <new> diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h index 0373867a661..8c4b13cf5e8 100644 --- a/src/corelib/kernel/qproperty.h +++ b/src/corelib/kernel/qproperty.h @@ -7,6 +7,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qshareddata.h> #include <QtCore/qstring.h> +#include <QtCore/qttypetraits.h> #include <QtCore/qbindingstorage.h> #include <type_traits> diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h index a8456721d05..c4a73f2c912 100644 --- a/src/corelib/kernel/qpropertyprivate.h +++ b/src/corelib/kernel/qpropertyprivate.h @@ -19,6 +19,7 @@ #include <QtCore/qtaggedpointer.h> #include <QtCore/qmetatype.h> #include <QtCore/qcontainerfwd.h> +#include <QtCore/qttypetraits.h> #include <functional> diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index cf37df71d75..e094d76c13e 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -8,6 +8,7 @@ #include <QtCore/qiodevicebase.h> #include <QtCore/qcontainerfwd.h> #include <QtCore/qnamespace.h> +#include <QtCore/qttypetraits.h> #include <iterator> // std::distance(), std::next() diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index c01dbb9390f..e3f98c30de6 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -8,6 +8,7 @@ #include <QtCore/qassert.h> #include <QtCore/qtclasshelpermacros.h> #include <QtCore/qtcoreexports.h> +#include <QtCore/qttypetraits.h> #include <QtCore/qtypeinfo.h> #include <climits> diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index e7cd4123fb4..9cc6fbf30bc 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -11,6 +11,7 @@ #include <QtCore/qiterator.h> #include <QtCore/qlist.h> #include <QtCore/qrefcount.h> +#include <QtCore/qttypetraits.h> #include <initializer_list> #include <functional> // for std::hash diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 89e0e3f380f..1cced5acc2d 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -11,6 +11,7 @@ #include <QtCore/qiterator.h> #include <QtCore/qcontainertools_impl.h> #include <QtCore/qnamespace.h> +#include <QtCore/qttypetraits.h> #include <functional> #include <limits> diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 7ee0be1e519..326ae7d8a51 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -12,6 +12,7 @@ #include <QtCore/qpair.h> #include <QtCore/qshareddata.h> #include <QtCore/qshareddata_impl.h> +#include <QtCore/qttypetraits.h> #include <functional> #include <initializer_list> diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 7330b5e91cc..6eaeb8fc417 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -6,6 +6,7 @@ #include <QtCore/qhash.h> #include <QtCore/qcontainertools_impl.h> +#include <QtCore/qttypetraits.h> #include <initializer_list> #include <iterator> diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 0a579bf4873..78d5a276277 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -14,6 +14,7 @@ #include <QtCore/qalgorithms.h> #include <QtCore/qcontainertools_impl.h> #include <QtCore/qhashfunctions.h> +#include <QtCore/qttypetraits.h> #include <algorithm> #include <initializer_list> diff --git a/src/testlib/qtesttostring.h b/src/testlib/qtesttostring.h index 18262332ba3..a1ee4f69258 100644 --- a/src/testlib/qtesttostring.h +++ b/src/testlib/qtesttostring.h @@ -7,6 +7,8 @@ #include <QtTest/qttestglobal.h> +#include <QtCore/qttypetraits.h> + #if QT_CONFIG(itemmodel) # include <QtCore/qabstractitemmodel.h> #endif diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index a8e2c7bda37..d79e0e82f8a 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -5,6 +5,8 @@ #include <qvariant.h> +#include <QtCore/qttypetraits.h> + // don't assume <type_traits> template <typename T, typename U> constexpr inline bool my_is_same_v = false; |