| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the Water library.
 -    Copyright (c) 2016 ROLI Ltd.
 -    Copyright (C) 2017-2018 Filipe Coelho <falktx@falktx.com>
 - 
 -    Permission is granted to use this software under the terms of the ISC license
 -    http://www.isc.org/downloads/software-support-policy/isc-license/
 - 
 -    Permission to use, copy, modify, and/or distribute this software for any
 -    purpose with or without fee is hereby granted, provided that the above
 -    copyright notice and this permission notice appear in all copies.
 - 
 -    THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
 -    TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 -    FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
 -    OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 -    USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 -    TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 -    OF THIS SOFTWARE.
 - 
 -   ==============================================================================
 - */
 - 
 - #ifndef WATER_HEAPBLOCK_H_INCLUDED
 - #define WATER_HEAPBLOCK_H_INCLUDED
 - 
 - #include "Memory.h"
 - #include "../maths/MathsFunctions.h"
 - 
 - namespace water {
 - 
 - //==============================================================================
 - /**
 -     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:
 -     @code
 -         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);
 -     @endcode
 - 
 -     ..you could just write this:
 -     @code
 -         HeapBlock<int> temp (1024);
 -         memcpy (temp, xyz, 1024 * sizeof (int));
 -         temp.calloc (2048);
 -         temp[0] = 1234;
 -         memcpy (foobar, temp, 2048 * sizeof (int));
 -     @endcode
 - 
 -     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 Array, OwnedArray, MemoryBlock
 - */
 - template <class ElementType>
 - class HeapBlock
 - {
 - public:
 -     //==============================================================================
 -     /** 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() noexcept  : data (nullptr)
 -     {
 -     }
 - 
 -     /** Destructor.
 -         This will free the data, if any has been allocated.
 -     */
 -     ~HeapBlock() noexcept
 -     {
 -         std::free (data);
 -     }
 - 
 -    #if WATER_COMPILER_SUPPORTS_MOVE_SEMANTICS
 -     HeapBlock (HeapBlock&& other) noexcept
 -         : data (other.data)
 -     {
 -         other.data = nullptr;
 -     }
 - 
 -     HeapBlock& operator= (HeapBlock&& other) noexcept
 -     {
 -         std::swap (data, other.data);
 -         return *this;
 -     }
 -    #endif
 - 
 -     //==============================================================================
 -     /** 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.
 -     */
 -     inline operator ElementType*() const noexcept                           { return data; }
 - 
 -     /** 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.
 -     */
 -     inline ElementType* getData() const noexcept                            { return data; }
 - 
 -     /** 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.
 -     */
 -     inline operator void*() const noexcept                                  { return static_cast<void*> (data); }
 - 
 -     /** 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.
 -     */
 -     inline operator const void*() const noexcept                            { return static_cast<const void*> (data); }
 - 
 -     /** 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.
 -     */
 -     inline ElementType* operator->() const  noexcept                        { return data; }
 - 
 -     /** 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.
 -     */
 -     template <typename IndexType>
 -     inline ElementType& operator[] (IndexType index) const noexcept         { return data [index]; }
 - 
 -     /** 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.
 -     */
 -     template <typename IndexType>
 -     inline ElementType* operator+ (IndexType index) const noexcept          { return data + index; }
 - 
 -     //==============================================================================
 -     /** Compares the pointer with another pointer.
 -         This can be handy for checking whether this is a null pointer.
 -     */
 -     inline bool operator== (const ElementType* const otherPointer) const noexcept   { return otherPointer == data; }
 - 
 -     /** Compares the pointer with another pointer.
 -         This can be handy for checking whether this is a null pointer.
 -     */
 -     inline bool operator!= (const ElementType* const otherPointer) const noexcept   { return otherPointer != data; }
 - 
 -     //==============================================================================
 -     /** 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.
 -     */
 -     bool malloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) noexcept
 -     {
 -         std::free (data);
 -         data = static_cast<ElementType*> (std::malloc (newNumElements * elementSize));
 - 
 -         return data != nullptr;
 -     }
 - 
 -     /** 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.
 -     */
 -     bool calloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) noexcept
 -     {
 -         std::free (data);
 -         data = static_cast<ElementType*> (std::calloc (newNumElements, elementSize));
 - 
 -         return data != nullptr;
 -     }
 - 
 -     /** 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.
 -     */
 -     bool allocate (const size_t newNumElements, bool initialiseToZero) noexcept
 -     {
 -         std::free (data);
 -         data = static_cast<ElementType*> (initialiseToZero
 -                                              ? std::calloc (newNumElements, sizeof (ElementType))
 -                                              : std::malloc (newNumElements * sizeof (ElementType)));
 - 
 -         return data != nullptr;
 -     }
 - 
 -     /** 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.
 -     */
 -     bool realloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) noexcept
 -     {
 -         data = static_cast<ElementType*> (data == nullptr ? std::malloc (newNumElements * elementSize)
 -                                                           : std::realloc (data, newNumElements * elementSize));
 -         return data != nullptr;
 -     }
 - 
 -     /** Frees any currently-allocated data.
 -         This will free the data and reset this object to be a null pointer.
 -     */
 -     void free() noexcept
 -     {
 -         std::free (data);
 -         data = nullptr;
 -     }
 - 
 -     /** Swaps this object's data with the data of another HeapBlock.
 -         The two objects simply exchange their data pointers.
 -     */
 -     void swapWith (HeapBlock<ElementType>& other) noexcept
 -     {
 -         std::swap (data, other.data);
 -     }
 - 
 -     /** 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.
 -     */
 -     void clear (size_t numElements) noexcept
 -     {
 -         zeromem (data, sizeof (ElementType) * numElements);
 -     }
 - 
 -     /** This typedef can be used to get the type of the heapblock's elements. */
 -     typedef ElementType Type;
 - 
 - private:
 -     //==============================================================================
 -     ElementType* data;
 - };
 - 
 - }
 - 
 - #endif // WATER_HEAPBLOCK_H_INCLUDED
 
 
  |