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