LMMS
Loading...
Searching...
No Matches
water::HeapBlock< ElementType > Class Template Reference

#include <HeapBlock.h>

Public Types

typedef ElementType Type

Public Member Functions

 HeapBlock () noexcept
 ~HeapBlock () noexcept
 operator ElementType * () const noexcept
ElementType * getData () const noexcept
const ElementType * getConstData () const noexcept
 operator void * () const noexcept
 operator const void * () const noexcept
ElementType * operator-> () const noexcept
template<typename IndexType>
ElementType & operator[] (IndexType index) const noexcept
template<typename IndexType>
ElementType * operator+ (IndexType index) const noexcept
bool operator== (const ElementType *const otherPointer) const noexcept
bool operator!= (const ElementType *const otherPointer) const noexcept
bool malloc (const size_t newNumElements, const size_t elementSize=sizeof(ElementType)) noexcept
bool calloc (const size_t newNumElements, const size_t elementSize=sizeof(ElementType)) noexcept
bool allocate (const size_t newNumElements, bool initialiseToZero) noexcept
bool realloc (const size_t newNumElements, const size_t elementSize=sizeof(ElementType)) noexcept
void free () noexcept
void swapWith (HeapBlock< ElementType > &other) noexcept
void clear (size_t numElements) noexcept
ElementType * release () noexcept

Private Attributes

ElementType * data

Detailed Description

template<class ElementType>
class water::HeapBlock< ElementType >

Very simple container class to hold a pointer to some data on the heap.

When you need to allocate some heap storage for something, always try to use this class instead of allocating the memory directly using malloc/free.

A HeapBlock<char> object can be treated in pretty much exactly the same way as an char*, but as long as you allocate it on the stack or as a class member, it's almost impossible for it to leak memory.

It also makes your code much more concise and readable than doing the same thing using direct allocations,

E.g. instead of this:

int* temp = (int*) malloc (1024 * sizeof (int));
memcpy (temp, xyz, 1024 * sizeof (int));
free (temp);
temp = (int*) calloc (2048 * sizeof (int));
temp[0] = 1234;
memcpy (foobar, temp, 2048 * sizeof (int));
free (temp);
bool malloc(const size_t newNumElements, const size_t elementSize=sizeof(ElementType)) noexcept
Definition HeapBlock.h:171
bool calloc(const size_t newNumElements, const size_t elementSize=sizeof(ElementType)) noexcept
Definition HeapBlock.h:182
void free() noexcept
Definition HeapBlock.h:219
memcpy(hh, h, RAND_HEAD_LEN)

..you could just write this:

HeapBlock<int> temp (1024);
memcpy (temp, xyz, 1024 * sizeof (int));
temp.calloc (2048);
temp[0] = 1234;
memcpy (foobar, temp, 2048 * sizeof (int));
HeapBlock() noexcept
Definition HeapBlock.h:85

The class is extremely lightweight, containing only a pointer to the data, and exposes malloc/realloc/calloc/free methods that do the same jobs as their less object-oriented counterparts. Despite adding safety, you probably won't sacrifice any performance by using this in place of normal pointers.

See also
Array, OwnedArray, MemoryBlock

Member Typedef Documentation

◆ Type

template<class ElementType>
typedef ElementType water::HeapBlock< ElementType >::Type

This typedef can be used to get the type of the heapblock's elements.

Constructor & Destructor Documentation

◆ HeapBlock()

template<class ElementType>
water::HeapBlock< ElementType >::HeapBlock ( )
inlinenoexcept

Creates a HeapBlock which is initially just a null pointer.

After creation, you can resize the array using the malloc(), calloc(), or realloc() methods.

◆ ~HeapBlock()

template<class ElementType>
water::HeapBlock< ElementType >::~HeapBlock ( )
inlinenoexcept

Destructor. This will free the data, if any has been allocated.

Member Function Documentation

◆ allocate()

template<class ElementType>
bool water::HeapBlock< ElementType >::allocate ( const size_t newNumElements,
bool initialiseToZero )
inlinenoexcept

Allocates a specified amount of memory and optionally clears it. This does the same job as either malloc() or calloc(), depending on the initialiseToZero parameter.

◆ calloc()

template<class ElementType>
bool water::HeapBlock< ElementType >::calloc ( const size_t newNumElements,
const size_t elementSize = sizeof (ElementType) )
inlinenoexcept

Allocates a specified amount of memory and clears it. This does the same job as the malloc() method, but clears the memory that it allocates.

◆ clear()

template<class ElementType>
void water::HeapBlock< ElementType >::clear ( size_t numElements)
inlinenoexcept

This fills the block with zeros, up to the number of elements specified. Since the block has no way of knowing its own size, you must make sure that the number of elements you specify doesn't exceed the allocated size.

◆ free()

template<class ElementType>
void water::HeapBlock< ElementType >::free ( )
inlinenoexcept

Frees any currently-allocated data. This will free the data and reset this object to be a null pointer.

◆ getConstData()

template<class ElementType>
const ElementType * water::HeapBlock< ElementType >::getConstData ( ) const
inlinenoexcept

Returns a raw pointer to the allocated data. This may be a null pointer if the data hasn't yet been allocated, or if it has been freed by calling the free() method.

◆ getData()

template<class ElementType>
ElementType * water::HeapBlock< ElementType >::getData ( ) const
inlinenoexcept

Returns a raw pointer to the allocated data. This may be a null pointer if the data hasn't yet been allocated, or if it has been freed by calling the free() method.

◆ malloc()

template<class ElementType>
bool water::HeapBlock< ElementType >::malloc ( const size_t newNumElements,
const size_t elementSize = sizeof (ElementType) )
inlinenoexcept

Allocates a specified amount of memory.

This uses the normal malloc to allocate an amount of memory for this object. Any previously allocated memory will be freed by this method.

The number of bytes allocated will be (newNumElements * elementSize). Normally you wouldn't need to specify the second parameter, but it can be handy if you need to allocate a size in bytes rather than in terms of the number of elements.

The data that is allocated will be freed when this object is deleted, or when you call free() or any of the allocation methods.

◆ operator const void *()

template<class ElementType>
water::HeapBlock< ElementType >::operator const void * ( ) const
inlinenoexcept

Returns a void pointer to the allocated data. This may be a null pointer if the data hasn't yet been allocated, or if it has been freed by calling the free() method.

◆ operator ElementType *()

template<class ElementType>
water::HeapBlock< ElementType >::operator ElementType * ( ) const
inlinenoexcept

Returns a raw pointer to the allocated data. This may be a null pointer if the data hasn't yet been allocated, or if it has been freed by calling the free() method.

◆ operator void *()

template<class ElementType>
water::HeapBlock< ElementType >::operator void * ( ) const
inlinenoexcept

Returns a void pointer to the allocated data. This may be a null pointer if the data hasn't yet been allocated, or if it has been freed by calling the free() method.

◆ operator!=()

template<class ElementType>
bool water::HeapBlock< ElementType >::operator!= ( const ElementType *const otherPointer) const
inlinenoexcept

Compares the pointer with another pointer. This can be handy for checking whether this is a null pointer.

◆ operator+()

template<class ElementType>
template<typename IndexType>
ElementType * water::HeapBlock< ElementType >::operator+ ( IndexType index) const
inlinenoexcept

Returns a pointer to a data element at an offset from the start of the array. This is the same as doing pointer arithmetic on the raw pointer itself.

◆ operator->()

template<class ElementType>
ElementType * water::HeapBlock< ElementType >::operator-> ( ) const
inlinenoexcept

Lets you use indirect calls to the first element in the array. Obviously this will cause problems if the array hasn't been initialised, because it'll be referencing a null pointer.

◆ operator==()

template<class ElementType>
bool water::HeapBlock< ElementType >::operator== ( const ElementType *const otherPointer) const
inlinenoexcept

Compares the pointer with another pointer. This can be handy for checking whether this is a null pointer.

◆ operator[]()

template<class ElementType>
template<typename IndexType>
ElementType & water::HeapBlock< ElementType >::operator[] ( IndexType index) const
inlinenoexcept

Returns a reference to one of the data elements. Obviously there's no bounds-checking here, as this object is just a dumb pointer and has no idea of the size it currently has allocated.

◆ realloc()

template<class ElementType>
bool water::HeapBlock< ElementType >::realloc ( const size_t newNumElements,
const size_t elementSize = sizeof (ElementType) )
inlinenoexcept

Re-allocates a specified amount of memory.

The semantics of this method are the same as malloc() and calloc(), but it uses realloc() to keep as much of the existing data as possible.

◆ release()

template<class ElementType>
ElementType * water::HeapBlock< ElementType >::release ( )
inlinenoexcept

Release this object's data ownership, returning the data pointer.

◆ swapWith()

template<class ElementType>
void water::HeapBlock< ElementType >::swapWith ( HeapBlock< ElementType > & other)
inlinenoexcept

Swaps this object's data with the data of another HeapBlock. The two objects simply exchange their data pointers.

Member Data Documentation

◆ data

template<class ElementType>
ElementType* water::HeapBlock< ElementType >::data
private

The documentation for this class was generated from the following file: