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
qcomtaskresource_p.h
Go to the documentation of this file.
1// Copyright (C) 2023 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//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists purely as an
9// implementation detail. This header file may change from version to
10// version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#ifndef QCOMTASKRESOURCE_P_H
16#define QCOMTASKRESOURCE_P_H
17
18#include <QtCore/qassert.h>
19
20#include <objbase.h>
21#include <algorithm>
22#include <type_traits>
23#include <utility>
24
25QT_BEGIN_NAMESPACE
26
27class QEmptyDeleter final
28{
29public:
30 template<typename T>
31 void operator()(T /*element*/) const
32 {
33 }
34};
35
36class QComDeleter final
37{
38public:
39 template<typename T>
40 void operator()(T element) const
41 {
42 element->Release();
43 }
44};
45
46template<typename T>
48{
49public:
50 QComTaskResourceBase(const QComTaskResourceBase<T> &source) = delete;
52
53 explicit operator bool() const { return m_resource != nullptr; }
54
55 T *get() const { return m_resource; }
56
57protected:
59 explicit QComTaskResourceBase(T *const resource) : m_resource(resource) { }
60
61 T *release() { return std::exchange(m_resource, nullptr); }
62
63 void reset(T *const resource = nullptr)
64 {
65 if (m_resource != resource) {
66 if (m_resource)
67 CoTaskMemFree(m_resource);
68 m_resource = resource;
69 }
70 }
71
72 T *m_resource = nullptr;
73};
74
75template<typename T, typename TElementDeleter = QEmptyDeleter>
76class QComTaskResource final : public QComTaskResourceBase<T>
77{
78 using Base = QComTaskResourceBase<T>;
79
80public:
81 using Base::QComTaskResourceBase;
82
83 ~QComTaskResource() { reset(); }
84
85 T *operator->() const { return m_resource; }
86 T &operator*() const { return *m_resource; }
87
88 T **address()
89 {
90 Q_ASSERT(m_resource == nullptr);
91 return &m_resource;
92 }
93
94 using Base::release;
95 using Base::reset;
96
97private:
98 using Base::m_resource;
99};
100
101template<typename T, typename TElementDeleter>
102class QComTaskResource<T[], TElementDeleter> final : public QComTaskResourceBase<T>
103{
104 using Base = QComTaskResourceBase<T>;
105
106public:
107 QComTaskResource() = default;
108 explicit QComTaskResource(T *const resource, const std::size_t size)
109 : Base(resource), m_size(size)
110 {
111 }
112
113 ~QComTaskResource() { reset(); }
114
115 T &operator[](const std::size_t index) const
116 {
117 Q_ASSERT(index < m_size);
118 return m_resource[index];
119 }
120
122 {
123 m_size = 0;
124
125 return Base::release();
126 }
127
128 void reset() { reset(nullptr, 0); }
129
130 void reset(T *const resource, const std::size_t size)
131 {
132 if (m_resource != resource) {
133 resetElements();
134
135 Base::reset(resource);
136
137 m_size = size;
138 }
139 }
140
141private:
142 void resetElements()
143 {
144 if constexpr (!std::is_same_v<TElementDeleter, QEmptyDeleter>) {
145 std::for_each(m_resource, m_resource + m_size, TElementDeleter());
146 }
147 }
148
149 std::size_t m_size = 0;
150
151 using Base::m_resource;
152};
153
154QT_END_NAMESPACE
155
156#endif
void operator()(T element) const
QComTaskResourceBase & operator=(const QComTaskResourceBase< T > &right)=delete
void reset(T *const resource=nullptr)
QComTaskResourceBase()=default
QComTaskResourceBase(T *const resource)
QComTaskResourceBase(const QComTaskResourceBase< T > &source)=delete
QComTaskResource(T *const resource, const std::size_t size)
T & operator[](const std::size_t index) const
void reset(T *const resource, const std::size_t size)