Plasma Engine  2.0
Loading...
Searching...
No Matches
Blob.h
1
2#pragma once
3
4#include <Foundation/Basics.h>
5#include <Foundation/Types/ArrayPtr.h>
6
11template <typename T>
13{
14public:
15 PL_DECLARE_POD_TYPE();
16
17 static_assert(!std::is_same_v<T, void>, "plBlobPtr<void> is not allowed (anymore)");
18 static_assert(!std::is_same_v<T, const void>, "plBlobPtr<void> is not allowed (anymore)");
19
20 using ByteType = typename plArrayPtrDetail::ByteTypeHelper<T>::type;
21 using ValueType = T;
22 using PointerType = T*;
23
25 plBlobPtr() = default;
26
28 template <typename U>
29 inline plBlobPtr(U* pPtr, plUInt64 uiCount)
30 : m_pPtr(pPtr)
31 , m_uiCount(uiCount)
32 {
33 // If any of the arguments is invalid, we invalidate ourself.
34 if (m_pPtr == nullptr || m_uiCount == 0)
35 {
36 m_pPtr = nullptr;
37 m_uiCount = 0;
38 }
39 }
40
42 template <size_t N>
43 PL_ALWAYS_INLINE plBlobPtr(ValueType (&staticArray)[N])
44 : m_pPtr(staticArray)
45 , m_uiCount(static_cast<plUInt64>(N))
46 {
47 }
48
50 PL_ALWAYS_INLINE plBlobPtr(const plBlobPtr<T>& other)
51 : m_pPtr(other.m_pPtr)
52 , m_uiCount(other.m_uiCount)
53 {
54 }
55
57 operator plBlobPtr<const T>() const { return plBlobPtr<const T>(static_cast<const T*>(GetPtr()), GetCount()); }
58
60 PL_ALWAYS_INLINE void operator=(const plBlobPtr<T>& other)
61 {
62 m_pPtr = other.m_pPtr;
63 m_uiCount = other.m_uiCount;
64 }
65
67 PL_ALWAYS_INLINE void Clear()
68 {
69 m_pPtr = nullptr;
70 m_uiCount = 0;
71 }
72
73 PL_ALWAYS_INLINE void operator=(std::nullptr_t)
74 {
75 m_pPtr = nullptr;
76 m_uiCount = 0;
77 }
78
80 PL_ALWAYS_INLINE PointerType GetPtr() const { return m_pPtr; }
81
83 PL_ALWAYS_INLINE PointerType GetPtr() { return m_pPtr; }
84
86 PL_ALWAYS_INLINE PointerType GetEndPtr() { return m_pPtr + m_uiCount; }
87
89 PL_ALWAYS_INLINE PointerType GetEndPtr() const { return m_pPtr + m_uiCount; }
90
92 PL_ALWAYS_INLINE bool IsEmpty() const { return GetCount() == 0; }
93
95 PL_ALWAYS_INLINE plUInt64 GetCount() const { return m_uiCount; }
96
98 PL_FORCE_INLINE plBlobPtr<T> GetSubArray(plUInt64 uiStart, plUInt64 uiCount) const // [tested]
99 {
100 PL_ASSERT_DEV(
101 uiStart + uiCount <= GetCount(), "uiStart+uiCount ({0}) has to be smaller or equal than the count ({1}).", uiStart + uiCount, GetCount());
102 return plBlobPtr<T>(GetPtr() + uiStart, uiCount);
103 }
104
107 PL_FORCE_INLINE plBlobPtr<T> GetSubArray(plUInt64 uiStart) const // [tested]
108 {
109 PL_ASSERT_DEV(uiStart <= GetCount(), "uiStart ({0}) has to be smaller or equal than the count ({1}).", uiStart, GetCount());
110 return plBlobPtr<T>(GetPtr() + uiStart, GetCount() - uiStart);
111 }
112
114 PL_ALWAYS_INLINE plBlobPtr<const ByteType> ToByteBlob() const
115 {
116 return plBlobPtr<const ByteType>(reinterpret_cast<const ByteType*>(GetPtr()), GetCount() * sizeof(T));
117 }
118
120 PL_ALWAYS_INLINE plBlobPtr<ByteType> ToByteBlob() { return plBlobPtr<ByteType>(reinterpret_cast<ByteType*>(GetPtr()), GetCount() * sizeof(T)); }
121
123 template <typename U>
124 PL_ALWAYS_INLINE plBlobPtr<U> Cast()
125 {
126 static_assert(sizeof(T) == sizeof(U), "Can only cast with equivalent element size.");
127 return plBlobPtr<U>(reinterpret_cast<U*>(GetPtr()), GetCount());
128 }
129
131 template <typename U>
132 PL_ALWAYS_INLINE plBlobPtr<const U> Cast() const
133 {
134 static_assert(sizeof(T) == sizeof(U), "Can only cast with equivalent element size.");
135 return plBlobPtr<const U>(reinterpret_cast<const U*>(GetPtr()), GetCount());
136 }
137
139 PL_FORCE_INLINE const ValueType& operator[](plUInt64 uiIndex) const // [tested]
140 {
141 PL_ASSERT_DEBUG(uiIndex < GetCount(), "Cannot access element {0}, the array only holds {1} elements.", uiIndex, GetCount());
142 return *static_cast<const ValueType*>(GetPtr() + uiIndex);
143 }
144
146 PL_FORCE_INLINE ValueType& operator[](plUInt64 uiIndex) // [tested]
147 {
148 PL_ASSERT_DEBUG(uiIndex < GetCount(), "Cannot access element {0}, the array only holds {1} elements.", uiIndex, GetCount());
149 return *static_cast<ValueType*>(GetPtr() + uiIndex);
150 }
151
153 inline bool operator==(const plBlobPtr<const T>& other) const // [tested]
154 {
155 if (GetCount() != other.GetCount())
156 return false;
157
158 if (GetPtr() == other.GetPtr())
159 return true;
160
161 return plMemoryUtils::IsEqual(static_cast<const ValueType*>(GetPtr()), static_cast<const ValueType*>(other.GetPtr()), static_cast<size_t>(GetCount()));
162 }
163
165 PL_ALWAYS_INLINE bool operator!=(const plBlobPtr<const T>& other) const // [tested]
166 {
167 return !(*this == other);
168 }
169
171 inline void CopyFrom(const plBlobPtr<const T>& other) // [tested]
172 {
173 PL_ASSERT_DEV(GetCount() == other.GetCount(), "Count for copy does not match. Target has {0} elements, source {1} elements", GetCount(), other.GetCount());
174
175 plMemoryUtils::Copy(static_cast<ValueType*>(GetPtr()), static_cast<const ValueType*>(other.GetPtr()), static_cast<size_t>(GetCount()));
176 }
177
178 PL_ALWAYS_INLINE void Swap(plBlobPtr<T>& other)
179 {
180 plMath::Swap(m_pPtr, other.m_pPtr);
181 plMath::Swap(m_uiCount, other.m_uiCount);
182 }
183
184 using const_iterator = const T*;
185 using const_reverse_iterator = const_reverse_pointer_iterator<T>;
186 using iterator = T*;
187 using reverse_iterator = reverse_pointer_iterator<T>;
188
189private:
190 PointerType m_pPtr = nullptr;
191 plUInt64 m_uiCount = 0u;
192};
193
195
198
200
202template <typename T>
203PL_ALWAYS_INLINE plBlobPtr<T> plMakeBlobPtr(T* pPtr, plUInt64 uiCount)
204{
205 return plBlobPtr<T>(pPtr, uiCount);
206}
207
209template <typename T, plUInt64 N>
210PL_ALWAYS_INLINE plBlobPtr<T> plMakeBlobPtr(T (&staticArray)[N])
211{
212 return plBlobPtr<T>(staticArray);
213}
214
216template <typename T>
217PL_ALWAYS_INLINE plConstByteBlobPtr plMakeByteBlobPtr(const T* pPtr, plUInt32 uiCount)
218{
219 return plConstByteBlobPtr(static_cast<const plUInt8*>(pPtr), uiCount * sizeof(T));
220}
221
223template <typename T>
224PL_ALWAYS_INLINE plByteBlobPtr plMakeByteBlobPtr(T* pPtr, plUInt32 uiCount)
225{
226 return plByteBlobPtr(reinterpret_cast<plUInt8*>(pPtr), uiCount * sizeof(T));
227}
228
230PL_ALWAYS_INLINE plByteBlobPtr plMakeByteBlobPtr(void* pPtr, plUInt32 uiBytes)
231{
232 return plByteBlobPtr(reinterpret_cast<plUInt8*>(pPtr), uiBytes);
233}
234
236PL_ALWAYS_INLINE plConstByteBlobPtr plMakeByteBlobPtr(const void* pPtr, plUInt32 uiBytes)
237{
238 return plConstByteBlobPtr(static_cast<const plUInt8*>(pPtr), uiBytes);
239}
240
242
243template <typename T>
244typename plBlobPtr<T>::iterator begin(plBlobPtr<T>& in_container)
245{
246 return in_container.GetPtr();
247}
248
249template <typename T>
250typename plBlobPtr<T>::const_iterator begin(const plBlobPtr<T>& container)
251{
252 return container.GetPtr();
253}
254
255template <typename T>
256typename plBlobPtr<T>::const_iterator cbegin(const plBlobPtr<T>& container)
257{
258 return container.GetPtr();
259}
260
261template <typename T>
262typename plBlobPtr<T>::reverse_iterator rbegin(plBlobPtr<T>& in_container)
263{
264 return typename plBlobPtr<T>::reverse_iterator(in_container.GetPtr() + in_container.GetCount() - 1);
265}
266
267template <typename T>
268typename plBlobPtr<T>::const_reverse_iterator rbegin(const plBlobPtr<T>& container)
269{
270 return typename plBlobPtr<T>::const_reverse_iterator(container.GetPtr() + container.GetCount() - 1);
271}
272
273template <typename T>
274typename plBlobPtr<T>::const_reverse_iterator crbegin(const plBlobPtr<T>& container)
275{
276 return typename plBlobPtr<T>::const_reverse_iterator(container.GetPtr() + container.GetCount() - 1);
277}
278
279template <typename T>
280typename plBlobPtr<T>::iterator end(plBlobPtr<T>& in_container)
281{
282 return in_container.GetPtr() + in_container.GetCount();
283}
284
285template <typename T>
286typename plBlobPtr<T>::const_iterator end(const plBlobPtr<T>& container)
287{
288 return container.GetPtr() + container.GetCount();
289}
290
291template <typename T>
292typename plBlobPtr<T>::const_iterator cend(const plBlobPtr<T>& container)
293{
294 return container.GetPtr() + container.GetCount();
295}
296
297template <typename T>
298typename plBlobPtr<T>::reverse_iterator rend(plBlobPtr<T>& in_container)
299{
300 return typename plBlobPtr<T>::reverse_iterator(in_container.GetPtr() - 1);
301}
302
303template <typename T>
304typename plBlobPtr<T>::const_reverse_iterator rend(const plBlobPtr<T>& container)
305{
306 return typename plBlobPtr<T>::const_reverse_iterator(container.GetPtr() - 1);
307}
308
309template <typename T>
310typename plBlobPtr<T>::const_reverse_iterator crend(const plBlobPtr<T>& container)
311{
312 return typename plBlobPtr<T>::const_reverse_iterator(container.GetPtr() - 1);
313}
314
318class PL_FOUNDATION_DLL plBlob
319{
320public:
321 PL_DECLARE_MEM_RELOCATABLE_TYPE();
322
325
327 plBlob(plBlob&& other);
328
330 void operator=(plBlob&& rhs);
331
333 ~plBlob();
334
337 void SetFrom(const void* pSource, plUInt64 uiSize);
338
340 void Clear();
341
343 bool IsEmpty() const;
344
346 void SetCountUninitialized(plUInt64 uiCount);
347
349 void ZeroFill();
350
352 template <typename T>
354 {
355 return plBlobPtr<T>(static_cast<T*>(m_pStorage), m_uiSize);
356 }
357
359 template <typename T>
361 {
362 return plBlobPtr<const T>(static_cast<T*>(m_pStorage), m_uiSize);
363 }
364
366 plByteBlobPtr GetByteBlobPtr() { return plByteBlobPtr(reinterpret_cast<plUInt8*>(m_pStorage), m_uiSize); }
367
369 plConstByteBlobPtr GetByteBlobPtr() const { return plConstByteBlobPtr(reinterpret_cast<const plUInt8*>(m_pStorage), m_uiSize); }
370
371private:
372 void* m_pStorage = nullptr;
373 plUInt64 m_uiSize = 0;
374};
plBlob allows to store simple binary data larger than 4GB. This storage class is used by plImage to a...
Definition Blob.h:319
plConstByteBlobPtr GetByteBlobPtr() const
Returns a blob pointer to the blob data, or an empty blob pointer if the blob is empty.
Definition Blob.h:369
plByteBlobPtr GetByteBlobPtr()
Returns a blob pointer to the blob data, or an empty blob pointer if the blob is empty.
Definition Blob.h:366
plBlobPtr< T > GetBlobPtr()
Returns a blob pointer to the blob data, or an empty blob pointer if the blob is empty.
Definition Blob.h:353
plBlobPtr< const T > GetBlobPtr() const
Returns a blob pointer to the blob data, or an empty blob pointer if the blob is empty.
Definition Blob.h:360
plBlob()
Default constructor. Does not allocate any memory.
This class encapsulates a blob's storage and it's size. It is recommended to use this class instead o...
Definition Blob.h:13
bool operator==(const plBlobPtr< const T > &other) const
Compares the two arrays for equality.
Definition Blob.h:153
PL_FORCE_INLINE ValueType & operator[](plUInt64 uiIndex)
Index access.
Definition Blob.h:146
PL_ALWAYS_INLINE plBlobPtr(ValueType(&staticArray)[N])
Initializes the plBlobPtr to encapsulate the given array.
Definition Blob.h:43
PL_ALWAYS_INLINE void Clear()
Clears the array.
Definition Blob.h:67
PL_FORCE_INLINE const ValueType & operator[](plUInt64 uiIndex) const
Index access.
Definition Blob.h:139
PL_ALWAYS_INLINE void operator=(const plBlobPtr< T > &other)
Copies the pointer and size of /a other. Does not allocate any data.
Definition Blob.h:60
PL_FORCE_INLINE plBlobPtr< T > GetSubArray(plUInt64 uiStart) const
Creates a sub-array from this array.
Definition Blob.h:107
PL_ALWAYS_INLINE plBlobPtr< ByteType > ToByteBlob()
Reinterprets this array as a byte array.
Definition Blob.h:120
void CopyFrom(const plBlobPtr< const T > &other)
Copies the data from other into this array. The arrays must have the exact same size.
Definition Blob.h:171
PL_ALWAYS_INLINE PointerType GetEndPtr()
Returns the pointer behind the last element of the array.
Definition Blob.h:86
PL_ALWAYS_INLINE plBlobPtr< const ByteType > ToByteBlob() const
Reinterprets this array as a byte array.
Definition Blob.h:114
PL_ALWAYS_INLINE plBlobPtr(const plBlobPtr< T > &other)
Initializes the plBlobPtr to be a copy of other. No memory is allocated or copied.
Definition Blob.h:50
PL_ALWAYS_INLINE bool operator!=(const plBlobPtr< const T > &other) const
Compares the two arrays for inequality.
Definition Blob.h:165
PL_ALWAYS_INLINE PointerType GetEndPtr() const
Returns the pointer behind the last element of the array.
Definition Blob.h:89
PL_ALWAYS_INLINE plBlobPtr< const U > Cast() const
Cast an BlobPtr to an BlobPtr to a different, but same size, type.
Definition Blob.h:132
PL_FORCE_INLINE plBlobPtr< T > GetSubArray(plUInt64 uiStart, plUInt64 uiCount) const
Creates a sub-array from this array.
Definition Blob.h:98
PL_ALWAYS_INLINE PointerType GetPtr() const
Returns the pointer to the array.
Definition Blob.h:80
PL_ALWAYS_INLINE PointerType GetPtr()
Returns the pointer to the array.
Definition Blob.h:83
plBlobPtr(U *pPtr, plUInt64 uiCount)
Initializes the plBlobPtr with the given pointer and number of elements. No memory is allocated or co...
Definition Blob.h:29
PL_ALWAYS_INLINE bool IsEmpty() const
Returns whether the array is empty.
Definition Blob.h:92
PL_ALWAYS_INLINE plBlobPtr< U > Cast()
Cast an BlobPtr to an BlobPtr to a different, but same size, type.
Definition Blob.h:124
PL_ALWAYS_INLINE plUInt64 GetCount() const
Returns the number of elements in the array.
Definition Blob.h:95
plBlobPtr()=default
Initializes the plBlobPtr to be empty.
static bool IsEqual(const T *a, const T *b, size_t uiCount=1)
Tests if objects of type T from pSource and pDestination are equal.
static void Copy(T *pDestination, const T *pSource, size_t uiCount=1)
Copies objects of type T from pSource to pDestination.
PL_ALWAYS_INLINE void Swap(T &ref_f1, T &ref_f2)
Swaps the values in the two variables f1 and f2.
Definition Math_inl.h:224
Base class for Pointer like reverse iterators.
Definition ArrayIterator.h:152
Non-Const class for Pointer like reverse iterators.
Definition ArrayIterator.h:216