Reorganize beast modules and files

This commit is contained in:
Vinnie Falco
2013-09-22 19:02:48 -07:00
parent 9e18bb3c31
commit 5c5de57290
78 changed files with 1416 additions and 8885 deletions

View File

@@ -1,186 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_BYTEORDER_H_INCLUDED
#define BEAST_BYTEORDER_H_INCLUDED
//==============================================================================
/** Contains static methods for converting the byte order between different
endiannesses.
*/
class BEAST_API ByteOrder : public Uncopyable
{
public:
//==============================================================================
/** Swaps the upper and lower bytes of a 16-bit integer. */
static uint16 swap (uint16 value);
/** Reverses the order of the 4 bytes in a 32-bit integer. */
static uint32 swap (uint32 value);
/** Reverses the order of the 8 bytes in a 64-bit integer. */
static uint64 swap (uint64 value);
//==============================================================================
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
static uint16 swapIfBigEndian (uint16 value);
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
static uint32 swapIfBigEndian (uint32 value);
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
static uint64 swapIfBigEndian (uint64 value);
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
static uint16 swapIfLittleEndian (uint16 value);
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
static uint32 swapIfLittleEndian (uint32 value);
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
static uint64 swapIfLittleEndian (uint64 value);
//==============================================================================
/** Turns 2 bytes into a little-endian integer. */
static uint16 littleEndianShort (const void* bytes);
/** Turns 4 bytes into a little-endian integer. */
static uint32 littleEndianInt (const void* bytes);
/** Turns 4 bytes into a little-endian integer. */
static uint64 littleEndianInt64 (const void* bytes);
/** Turns 2 bytes into a big-endian integer. */
static uint16 bigEndianShort (const void* bytes);
/** Turns 4 bytes into a big-endian integer. */
static uint32 bigEndianInt (const void* bytes);
/** Turns 4 bytes into a big-endian integer. */
static uint64 bigEndianInt64 (const void* bytes);
//==============================================================================
/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
static int littleEndian24Bit (const char* bytes);
/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
static int bigEndian24Bit (const char* bytes);
/** Copies a 24-bit number to 3 little-endian bytes. */
static void littleEndian24BitToChars (int value, char* destBytes);
/** Copies a 24-bit number to 3 big-endian bytes. */
static void bigEndian24BitToChars (int value, char* destBytes);
//==============================================================================
/** Returns true if the current CPU is big-endian. */
static bool isBigEndian();
private:
ByteOrder();
};
//==============================================================================
#if BEAST_USE_INTRINSICS && ! defined (__INTEL_COMPILER)
#pragma intrinsic (_byteswap_ulong)
#endif
inline uint16 ByteOrder::swap (uint16 n)
{
#if BEAST_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic!
return static_cast <uint16> (_byteswap_ushort (n));
#else
return static_cast <uint16> ((n << 8) | (n >> 8));
#endif
}
inline uint32 ByteOrder::swap (uint32 n)
{
#if BEAST_MAC || BEAST_IOS
return OSSwapInt32 (n);
#elif BEAST_GCC && BEAST_INTEL && ! BEAST_NO_INLINE_ASM
asm("bswap %%eax" : "=a"(n) : "a"(n));
return n;
#elif BEAST_USE_INTRINSICS
return _byteswap_ulong (n);
#elif BEAST_MSVC && ! BEAST_NO_INLINE_ASM
__asm {
mov eax, n
bswap eax
mov n, eax
}
return n;
#elif BEAST_ANDROID
return bswap_32 (n);
#else
return (n << 24) | (n >> 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8);
#endif
}
inline uint64 ByteOrder::swap (uint64 value)
{
#if BEAST_MAC || BEAST_IOS
return OSSwapInt64 (value);
#elif BEAST_USE_INTRINSICS
return _byteswap_uint64 (value);
#else
return (((int64) swap ((uint32) value)) << 32) | swap ((uint32) (value >> 32));
#endif
}
#if BEAST_LITTLE_ENDIAN
inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) { return v; }
inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) { return v; }
inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) { return v; }
inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) { return swap (v); }
inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) { return swap (v); }
inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) { return swap (v); }
inline uint16 ByteOrder::littleEndianShort (const void* const bytes) { return *static_cast <const uint16*> (bytes); }
inline uint32 ByteOrder::littleEndianInt (const void* const bytes) { return *static_cast <const uint32*> (bytes); }
inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) { return *static_cast <const uint64*> (bytes); }
inline uint16 ByteOrder::bigEndianShort (const void* const bytes) { return swap (*static_cast <const uint16*> (bytes)); }
inline uint32 ByteOrder::bigEndianInt (const void* const bytes) { return swap (*static_cast <const uint32*> (bytes)); }
inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) { return swap (*static_cast <const uint64*> (bytes)); }
inline bool ByteOrder::isBigEndian() { return false; }
#else
inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) { return swap (v); }
inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) { return swap (v); }
inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) { return swap (v); }
inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) { return v; }
inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) { return v; }
inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) { return v; }
inline uint32 ByteOrder::littleEndianInt (const void* const bytes) { return swap (*static_cast <const uint32*> (bytes)); }
inline uint16 ByteOrder::littleEndianShort (const void* const bytes) { return swap (*static_cast <const uint16*> (bytes)); }
inline uint16 ByteOrder::bigEndianShort (const void* const bytes) { return *static_cast <const uint16*> (bytes); }
inline uint32 ByteOrder::bigEndianInt (const void* const bytes) { return *static_cast <const uint32*> (bytes); }
inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) { return *static_cast <const uint64*> (bytes); }
inline bool ByteOrder::isBigEndian() { return true; }
#endif
inline int ByteOrder::littleEndian24Bit (const char* const bytes) { return (((int) bytes[2]) << 16) | (((int) (uint8) bytes[1]) << 8) | ((int) (uint8) bytes[0]); }
inline int ByteOrder::bigEndian24Bit (const char* const bytes) { return (((int) bytes[0]) << 16) | (((int) (uint8) bytes[1]) << 8) | ((int) (uint8) bytes[2]); }
inline void ByteOrder::littleEndian24BitToChars (const int value, char* const destBytes) { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
inline void ByteOrder::bigEndian24BitToChars (const int value, char* const destBytes) { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }
#endif

View File

@@ -1,126 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_BYTESWAP_H_INCLUDED
#define BEAST_BYTESWAP_H_INCLUDED
namespace detail
{
/** Specialized helper class template for swapping bytes.
Normally you won't use this directly, use the helper function
byteSwap instead. You can specialize this class for your
own user defined types, as was done for uint24.
@see swapBytes, uint24
*/
template <typename IntegralType>
struct SwapBytes
{
inline IntegralType operator() (IntegralType value) const noexcept
{
return ByteOrder::swap (value);
}
};
// Specializations for signed integers
template <>
struct SwapBytes <int16>
{
inline int16 operator() (int16 value) const noexcept
{
return static_cast <int16> (ByteOrder::swap (static_cast <uint16> (value)));
}
};
template <>
struct SwapBytes <int32>
{
inline int32 operator() (int32 value) const noexcept
{
return static_cast <int32> (ByteOrder::swap (static_cast <uint32> (value)));
}
};
template <>
struct SwapBytes <int64>
{
inline int64 operator() (int64 value) const noexcept
{
return static_cast <int64> (ByteOrder::swap (static_cast <uint64> (value)));
}
};
}
//------------------------------------------------------------------------------
/** Returns a type with the bytes swapped.
Little endian becomes big endian and vice versa. The underlying
type must be an integral type or behave like one.
*/
template <class IntegralType>
inline IntegralType swapBytes (IntegralType value) noexcept
{
return detail::SwapBytes <IntegralType> () (value);
}
/** Returns the machine byte-order value to little-endian byte order. */
template <typename IntegralType>
inline IntegralType toLittleEndian (IntegralType value) noexcept
{
#if BEAST_LITTLE_ENDIAN
return value;
#else
return swapBytes (value);
#endif
}
/** Returns the machine byte-order value to big-endian byte order. */
template <typename IntegralType>
inline IntegralType toBigEndian (IntegralType value) noexcept
{
#if BEAST_LITTLE_ENDIAN
return swapBytes (value);
#else
return value;
#endif
}
/** Returns the machine byte-order value to network byte order. */
template <typename IntegralType>
inline IntegralType toNetworkByteOrder (IntegralType value) noexcept
{
return toBigEndian (value);
}
/** Converts from network byte order to machine byte order. */
template <typename IntegralType>
inline IntegralType fromNetworkByteOrder (IntegralType value) noexcept
{
#if BEAST_LITTLE_ENDIAN
return swapBytes (value);
#else
return value;
#endif
}
#endif

View File

@@ -1,309 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_HEAPBLOCK_H_INCLUDED
#define BEAST_HEAPBLOCK_H_INCLUDED
#ifndef DOXYGEN
namespace HeapBlockHelper
{
template <bool shouldThrow>
struct ThrowOnFail { static void check (void*) {} };
template<>
struct ThrowOnFail <true> { static void check (void* data) { if (data == nullptr) throw std::bad_alloc(); } };
}
#endif
//==============================================================================
/**
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.
The throwOnFailure template parameter can be set to true if you'd like the class
to throw a std::bad_alloc exception when an allocation fails. If this is false,
then a failed allocation will just leave the heapblock with a null pointer (assuming
that the system's malloc() function doesn't throw).
@see Array, OwnedArray, MemoryBlock
*/
template <class ElementType, bool throwOnFailure = false>
class HeapBlock : public Uncopyable
{
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)
{
}
HeapBlock (HeapBlock& other)
{
data = other.data;
other.data = nullptr;
}
/** Creates a HeapBlock containing a number of elements.
The contents of the block are undefined, as it will have been created by a
malloc call.
If you want an array of zero values, you can use the calloc() method or the
other constructor that takes an InitialisationState parameter.
*/
explicit HeapBlock (const size_t numElements)
: data (static_cast <ElementType*> (std::malloc (numElements * sizeof (ElementType))))
{
throwOnAllocationFailure();
}
/** Creates a HeapBlock containing a number of elements.
The initialiseToZero parameter determines whether the new memory should be cleared,
or left uninitialised.
*/
HeapBlock (const size_t numElements, const bool initialiseToZero)
: data (static_cast <ElementType*> (initialiseToZero
? std::calloc (numElements, sizeof (ElementType))
: std::malloc (numElements * sizeof (ElementType))))
{
throwOnAllocationFailure();
}
/** Destructor.
This will free the data, if any has been allocated.
*/
~HeapBlock()
{
std::free (data);
}
#if BEAST_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.
*/
void malloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType))
{
std::free (data);
data = static_cast <ElementType*> (std::malloc (newNumElements * elementSize));
throwOnAllocationFailure();
}
/** 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.
*/
void calloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType))
{
std::free (data);
data = static_cast <ElementType*> (std::calloc (newNumElements, elementSize));
throwOnAllocationFailure();
}
/** 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.
*/
void allocate (const size_t newNumElements, bool initialiseToZero)
{
std::free (data);
data = static_cast <ElementType*> (initialiseToZero
? std::calloc (newNumElements, sizeof (ElementType))
: std::malloc (newNumElements * sizeof (ElementType)));
throwOnAllocationFailure();
}
/** 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.
*/
void realloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType))
{
data = static_cast <ElementType*> (data == nullptr ? std::malloc (newNumElements * elementSize)
: std::realloc (data, newNumElements * elementSize));
throwOnAllocationFailure();
}
/** Frees any currently-allocated data.
This will free the data and reset this object to be a null pointer.
*/
void free()
{
std::free (data);
data = nullptr;
}
/** Swaps this object's data with the data of another HeapBlock.
The two objects simply exchange their data pointers.
*/
template <bool otherBlockThrows>
void swapWith (HeapBlock <ElementType, otherBlockThrows>& 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;
void throwOnAllocationFailure() const
{
HeapBlockHelper::ThrowOnFail<throwOnFailure>::check (data);
}
#if ! (defined (BEAST_DLL) || defined (BEAST_DLL_BUILD))
BEAST_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point!
#endif
};
#endif // BEAST_HEAPBLOCK_H_INCLUDED

View File

@@ -1,94 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_MEMORY_H_INCLUDED
#define BEAST_MEMORY_H_INCLUDED
//==============================================================================
/** Fills a block of memory with zeros. */
inline void zeromem (void* memory, size_t numBytes) noexcept { memset (memory, 0, numBytes); }
/** Overwrites a structure or object with zeros. */
template <typename Type>
inline void zerostruct (Type& structure) noexcept { memset (&structure, 0, sizeof (structure)); }
/** Delete an object pointer, and sets the pointer to null.
Remember that it's not good c++ practice to use delete directly - always try to use a ScopedPointer
or other automatic lifetime-management system rather than resorting to deleting raw pointers!
*/
template <typename Type>
inline void deleteAndZero (Type& pointer) { delete pointer; pointer = nullptr; }
/** A handy function which adds a number of bytes to any type of pointer and returns the result.
This can be useful to avoid casting pointers to a char* and back when you want to move them by
a specific number of bytes,
*/
template <typename Type, typename IntegerType>
inline Type* addBytesToPointer (Type* pointer, IntegerType bytes) noexcept { return (Type*) (((char*) pointer) + bytes); }
/** A handy function which returns the difference between any two pointers, in bytes.
The address of the second pointer is subtracted from the first, and the difference in bytes is returned.
*/
template <typename Type1, typename Type2>
inline int getAddressDifference (Type1* pointer1, Type2* pointer2) noexcept { return (int) (((const char*) pointer1) - (const char*) pointer2); }
/** If a pointer is non-null, this returns a new copy of the object that it points to, or safely returns
nullptr if the pointer is null.
*/
template <class Type>
inline Type* createCopyIfNotNull (const Type* pointer) { return pointer != nullptr ? new Type (*pointer) : nullptr; }
//==============================================================================
#if BEAST_MAC || BEAST_IOS || DOXYGEN
/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII.
You should use the BEAST_AUTORELEASEPOOL macro to create a local auto-release pool on the stack.
*/
class BEAST_API ScopedAutoReleasePool : public Uncopyable
{
public:
ScopedAutoReleasePool();
~ScopedAutoReleasePool();
private:
void* pool;
};
/** A macro that can be used to easily declare a local ScopedAutoReleasePool
object for RAII-based obj-C autoreleasing.
Because this may use the \@autoreleasepool syntax, you must follow the macro with
a set of braces to mark the scope of the pool.
*/
#if (BEAST_COMPILER_SUPPORTS_ARC && defined (__OBJC__)) || DOXYGEN
#define BEAST_AUTORELEASEPOOL @autoreleasepool
#else
#define BEAST_AUTORELEASEPOOL const beast::ScopedAutoReleasePool BEAST_JOIN_MACRO (autoReleasePool_, __LINE__);
#endif
#else
#define BEAST_AUTORELEASEPOOL
#endif
#endif