1 | // Copyright (C) 2008-2012 NVIDIA Corporation. |
2 | // Copyright (C) 2019 The Qt Company Ltd. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #ifndef QSSGDATAREF_H |
6 | #define QSSGDATAREF_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 <QtQuick3DUtils/private/qtquick3dutilsglobal_p.h> |
20 | |
21 | #include <QtCore/qlist.h> |
22 | #include <QtCore/qbytearray.h> |
23 | |
24 | QT_BEGIN_NAMESPACE |
25 | |
26 | template<typename T> |
27 | struct QSSGDataView |
28 | { |
29 | const T *mData; |
30 | qsizetype mSize; |
31 | |
32 | explicit QSSGDataView(const QList<T> &data) : mData(data.constData()), mSize(data.size()) { Q_ASSERT(mSize >= 0); } |
33 | template <qsizetype N> |
34 | explicit QSSGDataView(const QVarLengthArray<T, N> &data) : mData(data.constData()), mSize(data.size()) { Q_ASSERT(mSize >= 0); } |
35 | QSSGDataView(const T *inData, qsizetype inSize) : mData(inData), mSize(inSize) { Q_ASSERT(mSize >= 0); } |
36 | constexpr QSSGDataView() : mData(nullptr), mSize(0) {} |
37 | |
38 | qsizetype size() const { return mSize; } |
39 | |
40 | const T *begin() const { return mData; } |
41 | const T *end() const { return mData + mSize; } |
42 | |
43 | const T& first() const { Q_ASSERT(!isEmpty()); return *begin(); } |
44 | const T& last() const { Q_ASSERT(!isEmpty()); return *(end()-1); } |
45 | |
46 | const T &operator[](int index) const |
47 | { |
48 | Q_ASSERT(index > -1); |
49 | Q_ASSERT(index < mSize); |
50 | return mData[index]; |
51 | } |
52 | |
53 | bool isEmpty() const { return (mSize == 0); } |
54 | |
55 | void clear() |
56 | { |
57 | mData = nullptr; |
58 | mSize = 0; |
59 | } |
60 | |
61 | operator const void *() { return reinterpret_cast<const void *>(mData); } |
62 | }; |
63 | |
64 | template<> |
65 | struct QSSGDataView<quint8> |
66 | { |
67 | const quint8 *mData; |
68 | qsizetype mSize; |
69 | |
70 | explicit QSSGDataView(const QByteArray &data) |
71 | : mData(reinterpret_cast<const quint8 *>(data.constBegin())), mSize(data.size()) |
72 | { Q_ASSERT(mSize >= 0); } |
73 | template<typename T> |
74 | explicit QSSGDataView(const QList<T> &data) |
75 | : mData(reinterpret_cast<const quint8 *>(data.constData())), mSize(data.size()*sizeof(T)) |
76 | { Q_ASSERT(mSize >= 0); } |
77 | QSSGDataView(const quint8 *inData, qsizetype inSize) : mData(inData), mSize(inSize) { Q_ASSERT(mSize >= 0); } |
78 | template<typename T> |
79 | QSSGDataView(const T *inData, qsizetype inSize) |
80 | : mData(reinterpret_cast<const quint8 *>(inData)), mSize(inSize*sizeof(T)) |
81 | { Q_ASSERT(mSize >= 0); } |
82 | constexpr QSSGDataView() : mData(nullptr), mSize(0) {} |
83 | |
84 | qsizetype size() const { return mSize; } |
85 | bool isEmpty() const { return (mSize == 0); } |
86 | |
87 | const quint8 *begin() const { return mData; } |
88 | const quint8 *end() const { return mData + mSize; } |
89 | |
90 | const quint8 &operator[](int index) const |
91 | { |
92 | Q_ASSERT(index > -1); |
93 | Q_ASSERT(index < mSize); |
94 | return mData[index]; |
95 | } |
96 | |
97 | void clear() |
98 | { |
99 | mData = nullptr; |
100 | mSize = 0; |
101 | } |
102 | |
103 | operator const void *() { return reinterpret_cast<const void *>(mData); } |
104 | }; |
105 | |
106 | using QSSGByteView = QSSGDataView<quint8>; |
107 | |
108 | template<typename T> |
109 | inline QSSGDataView<T> toDataView(const T &type) |
110 | { |
111 | return QSSGDataView<T>(&type, 1); |
112 | } |
113 | |
114 | template<typename T> |
115 | inline QSSGDataView<T> toDataView(const QList<T> &type) |
116 | { |
117 | return QSSGDataView<T>(type); |
118 | } |
119 | |
120 | template<typename T> |
121 | inline QSSGByteView toByteView(const T &type) |
122 | { |
123 | return QSSGByteView(&type, 1); |
124 | } |
125 | |
126 | template<typename T> |
127 | inline QSSGByteView toByteView(const QList<T> &type) |
128 | { |
129 | return QSSGByteView(type); |
130 | } |
131 | |
132 | template<> |
133 | inline QSSGByteView toByteView(const QByteArray &type) |
134 | { |
135 | return QSSGByteView(type); |
136 | } |
137 | |
138 | inline QSSGByteView toByteView(const char *str) |
139 | { |
140 | return QSSGByteView(str, qstrlen(str)); |
141 | } |
142 | |
143 | template<typename T> |
144 | inline QSSGDataView<T> toDataView(const T *type, qsizetype count) |
145 | { |
146 | return QSSGDataView<T>(type, count); |
147 | } |
148 | |
149 | template<typename T> |
150 | inline QSSGByteView toByteView(const T *type, qsizetype count) |
151 | { |
152 | return QSSGByteView(type, count); |
153 | } |
154 | |
155 | template<typename T> |
156 | struct QSSGDataRef |
157 | { |
158 | T *mData; |
159 | qsizetype mSize; |
160 | |
161 | QSSGDataRef(T *inData, qsizetype inSize) : mData(inData), mSize(inSize) { Q_ASSERT(inSize >= 0); } |
162 | QSSGDataRef() : mData(nullptr), mSize(0) {} |
163 | qsizetype size() const { return mSize; } |
164 | |
165 | T *begin() { return mData; } |
166 | T *end() { return mData + mSize; } |
167 | |
168 | T *begin() const { return mData; } |
169 | T *end() const { return mData + mSize; } |
170 | |
171 | T& first() { Q_ASSERT(!isEmpty()); return *begin(); } |
172 | T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); } |
173 | |
174 | const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); } |
175 | const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); } |
176 | |
177 | bool isEmpty() const { return (mSize == 0); } |
178 | |
179 | T &operator[](qsizetype index) |
180 | { |
181 | Q_ASSERT(index >= 0); |
182 | Q_ASSERT(index < mSize); |
183 | return mData[index]; |
184 | } |
185 | |
186 | const T &operator[](qsizetype index) const |
187 | { |
188 | Q_ASSERT(index >= 0); |
189 | Q_ASSERT(index < mSize); |
190 | return mData[index]; |
191 | } |
192 | |
193 | void clear() |
194 | { |
195 | mData = nullptr; |
196 | mSize = 0; |
197 | } |
198 | |
199 | operator QSSGDataView<T>() const { return QSSGDataView<T>(mData, mSize); } |
200 | operator void *() { return reinterpret_cast<void *>(mData); } |
201 | }; |
202 | |
203 | using QSSGByteRef = QSSGDataRef<quint8>; |
204 | |
205 | template<typename T> |
206 | inline QSSGDataRef<T> toDataRef(T &type) |
207 | { |
208 | return QSSGDataRef<T>(&type, 1); |
209 | } |
210 | |
211 | template<typename T> |
212 | inline QSSGByteRef toByteRef(T &type) |
213 | { |
214 | return QSSGByteRef(reinterpret_cast<quint8 *>(&type), sizeof(T)); |
215 | } |
216 | |
217 | template<typename T> |
218 | inline QSSGDataRef<T> toDataRef(T *type, qsizetype count) |
219 | { |
220 | return QSSGDataRef<T>(type, count); |
221 | } |
222 | |
223 | template<typename T> |
224 | inline QSSGByteRef toByteRef(T *type, qsizetype count) |
225 | { |
226 | return QSSGByteRef(reinterpret_cast<quint8 *>(type), sizeof(T) * count); |
227 | } |
228 | |
229 | QT_END_NAMESPACE |
230 | |
231 | #endif // QSSGDATAREF_H |
232 | |