26#if ! (DOXYGEN || JUCE_EXCEPTIONS_DISABLED)
27namespace HeapBlockHelper
29 template <
bool shouldThrow>
30 struct ThrowOnFail {
static void checkPointer (
void*) {} };
33 struct ThrowOnFail<true> {
static void checkPointer (
void* data) {
if (data ==
nullptr)
throw std::bad_alloc(); } };
85template <
class ElementType,
bool throwOnFailure = false>
89 template <
class OtherElementType>
110 template <
typename SizeType, std::enable_if_t<std::is_convertible_v<SizeType,
int>,
int> = 0>
112 : data (mallocWrapper (static_cast<
size_t> (numElements) * sizeof (ElementType)))
121 template <
typename SizeType, std::enable_if_t<std::is_convertible_v<SizeType,
int>,
int> = 0>
123 : data (initialiseToZero ? callocWrapper (static_cast<
size_t> (numElements), sizeof (ElementType))
124 : mallocWrapper (static_cast<
size_t> (numElements) * sizeof (ElementType)))
140 other.data =
nullptr;
154 template <
class OtherElementType,
bool otherThrowOnFailure,
typename = AllowConversion<OtherElementType>>
156 : data (
reinterpret_cast<ElementType*
> (other.data))
158 other.data =
nullptr;
165 template <
class OtherElementType,
bool otherThrowOnFailure,
typename = AllowConversion<OtherElementType>>
169 data =
reinterpret_cast<ElementType*
> (other.data);
170 other.data =
nullptr;
179 inline operator ElementType*()
const noexcept {
return data; }
185 inline ElementType*
get() const noexcept {
return data; }
191 inline ElementType*
getData() const noexcept {
return data; }
197 inline operator void*()
const noexcept {
return static_cast<void*
> (data); }
203 inline operator const void*()
const noexcept {
return static_cast<const void*
> (data); }
209 inline ElementType*
operator->() const noexcept {
return data; }
215 template <
typename IndexType>
216 ElementType&
operator[] (IndexType index)
const noexcept {
return data [index]; }
221 template <
typename IndexType>
222 ElementType*
operator+ (IndexType index)
const noexcept {
return data + index; }
228 inline bool operator== (
const ElementType* otherPointer)
const noexcept {
return otherPointer == data; }
233 inline bool operator!= (
const ElementType* otherPointer)
const noexcept {
return otherPointer != data; }
248 template <
typename SizeType>
249 void malloc (SizeType newNumElements,
size_t elementSize =
sizeof (ElementType))
252 data = mallocWrapper (
static_cast<size_t> (newNumElements) * elementSize);
258 template <
typename SizeType>
259 void calloc (SizeType newNumElements,
const size_t elementSize =
sizeof (ElementType))
262 data = callocWrapper (
static_cast<size_t> (newNumElements), elementSize);
269 template <
typename SizeType>
270 void allocate (SizeType newNumElements,
bool initialiseToZero)
273 data = initialiseToZero ? callocWrapper (
static_cast<size_t> (newNumElements),
sizeof (ElementType))
274 : mallocWrapper (
static_cast<size_t> (newNumElements) *
sizeof (ElementType));
282 template <
typename SizeType>
283 void realloc (SizeType newNumElements,
size_t elementSize =
sizeof (ElementType))
285 data = reallocWrapper (data,
static_cast<size_t> (newNumElements) * elementSize);
300 template <
bool otherBlockThrows>
310 template <
typename SizeType>
311 void clear (SizeType numElements)
noexcept
313 zeromem (data,
sizeof (ElementType) *
static_cast<size_t> (numElements));
323 template <
typename Functor>
324 static ElementType* wrapper (
size_t size, Functor&& f)
329 auto* memory =
static_cast<ElementType*
> (f());
331 #if JUCE_EXCEPTIONS_DISABLED
334 HeapBlockHelper::ThrowOnFail<throwOnFailure>::checkPointer (memory);
340 static ElementType* mallocWrapper (
size_t size)
342 return wrapper (size, [size] {
return std::malloc (size); });
345 static ElementType* callocWrapper (
size_t num,
size_t size)
347 return wrapper (num * size, [num, size] {
return std::calloc (num, size); });
350 static ElementType* reallocWrapper (
void* ptr,
size_t newSize)
352 return wrapper (newSize, [ptr, newSize] {
return std::realloc (ptr, newSize); });
355 template <
class OtherElementType,
bool otherThrowOnFailure>
356 friend class HeapBlock;
359 ElementType* data =
nullptr;
361 #if ! (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD))
Very simple container class to hold a pointer to some data on the heap.
HeapBlock(SizeType numElements)
Creates a HeapBlock containing a number of elements.
HeapBlock(HeapBlock< OtherElementType, otherThrowOnFailure > &&other) noexcept
Converting move constructor.
HeapBlock & operator=(HeapBlock &&other) noexcept
Move assignment operator.
ElementType Type
This typedef can be used to get the type of the heapblock's elements.
void clear(SizeType numElements) noexcept
This fills the block with zeros, up to the number of elements specified.
void swapWith(HeapBlock< ElementType, otherBlockThrows > &other) noexcept
Swaps this object's data with the data of another HeapBlock.
bool operator!=(const ElementType *otherPointer) const noexcept
Compares the pointer with another pointer.
ElementType * operator+(IndexType index) const noexcept
Returns a pointer to a data element at an offset from the start of the array.
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
HeapBlock(HeapBlock &&other) noexcept
Move constructor.
ElementType * get() const noexcept
Returns a raw pointer to the allocated data.
ElementType * getData() const noexcept
Returns a raw pointer to the allocated data.
ElementType & operator[](IndexType index) const noexcept
Returns a reference to one of the data elements.
HeapBlock()=default
Creates a HeapBlock which is initially just a null pointer.
void allocate(SizeType newNumElements, bool initialiseToZero)
Allocates a specified amount of memory and optionally clears it.
HeapBlock(SizeType numElements, bool initialiseToZero)
Creates a HeapBlock containing a number of elements.
bool operator==(const ElementType *otherPointer) const noexcept
Compares the pointer with another pointer.
void realloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Re-allocates a specified amount of memory.
void free() noexcept
Frees any currently-allocated data.
ElementType * operator->() const noexcept
Lets you use indirect calls to the first element in the array.
void calloc(SizeType newNumElements, const size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory and clears it.
void zeromem(void *memory, size_t numBytes) noexcept
Fills a block of memory with zeros.