diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-09-01 15:33:13 +0200 |
---|---|---|
committer | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-09-07 15:48:35 +0200 |
commit | 9f13842fe61541cb8ab9822174ea963e418b5537 (patch) | |
tree | 0a377443905a961cfcde23e3816d4b2dd6ebf7dc /src/corelib/global | |
parent | 4cde0e484c009415397430050cde389fb9b445b6 (diff) |
Fix compilation for recursive Qt containers
The operator checks cause compilation errors when trying to check for
their existence for recursive containers. This happens because of trying
to check for the operators on the template parameter type(s), that
inherit from the container itself, which leads to compilation errors.
Introduced alternative versions of the operator checks (with _container
suffix), that first check if the container is recursive, i.e. any of its
template parameter types inherits from the given container, and skips
the operator check, if that's the case.
The fix is done for all Qt container types that had the problem, except
for QVarLengthArray and QContiguousCache, which don't compile with
recursive parameter types for unrelated reasons.
Fixes: QTBUG-91707
Pick-to: 6.2 6.1
Change-Id: Ia1e7240b4ce240c1c44f00ca680717d182df7550
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/global')
-rw-r--r-- | src/corelib/global/qtypeinfo.h | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 58f20b7be4..2729217aab 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -335,17 +335,29 @@ 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> @@ -363,6 +375,9 @@ struct has_ostream_operator<Stream, T, std::void_t<decltype(detail::reference<St 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> @@ -370,6 +385,8 @@ struct has_istream_operator<Stream, T, std::void_t<decltype(detail::reference<St : 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>; |