Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qcomptr_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCOMPTR_P_H
5#define QCOMPTR_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/private/qglobal_p.h>
19#include <QtCore/qtconfigmacros.h>
20#include <type_traits>
21#if defined(Q_OS_WIN) || defined(Q_QDOC)
22
23// clang-format off
24#include <QtCore/qt_windows.h>
25#include <wrl/client.h>
26// clang-format on
27
28QT_BEGIN_NAMESPACE
29
30namespace Detail {
31
32template <typename, typename, typename = void>
33struct has_equal_to_operator : std::false_type
34{
35};
36
37template <typename T, typename U>
38struct has_equal_to_operator<
39 T, U, std::void_t<decltype(operator==(std::declval<T>(), std::declval<U>()))>>
40 : std::true_type
41{
42};
43
44template <typename T, typename U>
45using EnableIfMissingEqualToOperator = std::enable_if_t<!has_equal_to_operator<T, U>::value, bool>;
46
47template <typename, typename, typename = void>
48struct has_not_equal_to_operator : std::false_type
49{
50};
51
52template <typename T, typename U>
53struct has_not_equal_to_operator<
54 T, U, std::void_t<decltype(operator!=(std::declval<T>(), std::declval<U>()))>>
55 : std::true_type
56{
57};
58
59template <typename T, typename U>
60using EnableIfMissingNotEqualToOperator =
61 std::enable_if_t<!has_not_equal_to_operator<T, U>::value, bool>;
62
63template <typename, typename, typename = void>
64struct has_less_than_operator : std::false_type
65{
66};
67
68template <typename T, typename U>
69struct has_less_than_operator<
70 T, U, std::void_t<decltype(operator<(std::declval<T>(), std::declval<U>()))>>
71 : std::true_type
72{
73};
74
75template <typename T, typename U>
76using EnableIfMissingLessThanOperator =
77 std::enable_if_t<!has_less_than_operator<T, U>::value, bool>;
78
79} // namespace Detail
80
81QT_END_NAMESPACE
82
83namespace Microsoft {
84namespace WRL {
85
86// Add missing comparison operators if MINGW does not provide them
87
88template <typename T, typename U,
89 QT_PREPEND_NAMESPACE(Detail)::EnableIfMissingEqualToOperator<ComPtr<T>, ComPtr<U>> = true>
90bool operator==(const ComPtr<T> &lhs, const ComPtr<U> &rhs) noexcept
91{
92 static_assert(std::is_base_of_v<T, U> || std::is_base_of_v<U, T>);
93 return lhs.Get() == rhs.Get();
94}
95
96template <typename T,
97 QT_PREPEND_NAMESPACE(Detail)::EnableIfMissingEqualToOperator<ComPtr<T>, std::nullptr_t> =
98 true>
99bool operator==(const ComPtr<T> &lhs, std::nullptr_t) noexcept
100{
101 return lhs.Get() == nullptr;
102}
103
104template <typename T,
105 QT_PREPEND_NAMESPACE(Detail)::EnableIfMissingEqualToOperator<std::nullptr_t, ComPtr<T>> =
106 true>
107bool operator==(std::nullptr_t, const ComPtr<T> &rhs) noexcept
108{
109 return rhs.Get() == nullptr;
110}
111
112template <typename T, typename U,
113 QT_PREPEND_NAMESPACE(Detail)::EnableIfMissingNotEqualToOperator<ComPtr<T>, ComPtr<U>> =
114 true>
115bool operator!=(const ComPtr<T> &a, const ComPtr<U> &b) noexcept
116{
117 static_assert(std::is_base_of_v<T, U> || std::is_base_of_v<U, T>);
118 return a.Get() != b.Get();
119}
120
121template <class T,
122 QT_PREPEND_NAMESPACE(
123 Detail)::EnableIfMissingNotEqualToOperator<ComPtr<T>, std::nullptr_t> = true>
124bool operator!=(const ComPtr<T> &a, std::nullptr_t) noexcept
125{
126 return a.Get() != nullptr;
127}
128
129template <class T,
130 QT_PREPEND_NAMESPACE(
131 Detail)::EnableIfMissingNotEqualToOperator<std::nullptr_t, ComPtr<T>> = true>
132bool operator!=(std::nullptr_t, const ComPtr<T> &a) noexcept
133{
134 return a.Get() != nullptr;
135}
136
137// MSVC WRL only defines operator<, we do not add other variants such as <=, > or >=
138template <
139 class T, class U,
140 QT_PREPEND_NAMESPACE(Detail)::EnableIfMissingLessThanOperator<ComPtr<T>, ComPtr<U>> = true>
141bool operator<(const ComPtr<T> &a, const ComPtr<U> &b) noexcept
142{
143 static_assert(std::is_base_of_v<T, U> || std::is_base_of_v<U, T>);
144 return a.Get() < b.Get();
145}
146
147} // namespace WRL
148} // namespace Microsoft
149
150QT_BEGIN_NAMESPACE
151
152using Microsoft::WRL::ComPtr;
153
154template <typename T, typename... Args>
155ComPtr<T> makeComObject(Args &&...args)
156{
157 ComPtr<T> p;
158 // Don't use Attach because of MINGW64 bug
159 // #892 Microsoft::WRL::ComPtr::Attach leaks references
160 *p.GetAddressOf() = new T(std::forward<Args>(args)...);
161 return p;
162}
163
164QT_END_NAMESPACE
165
166#endif // Q_OS_WIN
167
168#endif // QCOMPTR_P_H