| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #pragma once
- #include "BsPrerequisitesUtil.h"
- namespace bs
- {
- /** @addtogroup Internal-Utility
- * @{
- */
- /** @addtogroup Memory-Internal
- * @{
- */
- /**
- * Provides an easy way to group multiple allocations under a single (actual) allocation. Requires the user to first
- * call reserve() methods for all requested data elements, followed by init(), after which allocation/deallocation
- * can follow using construct/destruct or alloc/free methods.
- */
- class GroupAlloc : INonCopyable
- {
- public:
- GroupAlloc()
- : mData(nullptr), mDataPtr(nullptr), mNumBytes(0)
- { }
- GroupAlloc(GroupAlloc&& other) noexcept
- : mData(other.mData), mDataPtr(other.mDataPtr), mNumBytes(other.mNumBytes)
- {
- other.mData = nullptr;
- other.mDataPtr = nullptr;
- other.mNumBytes = 0;
- }
- ~GroupAlloc()
- {
- if (mNumBytes > 0)
- bs_free(mData);
- }
- GroupAlloc& operator=(GroupAlloc&& other) noexcept
- {
- if (this == &other)
- return *this;
- if (mNumBytes > 0)
- bs_free(mData);
- mData = other.mData;
- mDataPtr = other.mDataPtr;
- mNumBytes = other.mNumBytes;
- other.mData = nullptr;
- other.mDataPtr = nullptr;
- other.mNumBytes = 0;
- return *this;
- }
- /**
- * Allocates internal memory as reserved by previous calls to reserve(). Must be called before any calls to
- * construct or alloc.
- */
- void init()
- {
- assert(mData == nullptr);
- if (mNumBytes > 0)
- mData = (UINT8*)bs_alloc(mNumBytes);
- mDataPtr = mData;
- }
- /**
- * Reserves the specified amount of bytes to allocate. Multiple calls to reserve() are cumulative. After all needed
- * memory is reserved, call init(), followed by actual allocation via construct() or alloc() methods.
- */
- GroupAlloc& reserve(UINT32 amount)
- {
- assert(mData == nullptr);
- mNumBytes += amount;
- return *this;
- }
- /**
- * Reserves the specified amount of bytes to allocate. Multiple calls to reserve() are cumulative. After all needed
- * memory is reserved, call init(), followed by actual allocation via construct() or alloc() methods.
- */
- template<class T>
- GroupAlloc& reserve(UINT32 count = 1)
- {
- assert(mData == nullptr);
- mNumBytes += sizeof(T) * count;
- return *this;
- }
- /**
- * Allocates a new piece of memory of the specified size.
- *
- * @param[in] amount Amount of memory to allocate, in bytes.
- */
- UINT8* alloc(UINT32 amount)
- {
- assert(mDataPtr + amount <= (mData + mNumBytes));
- UINT8* output = mDataPtr;
- mDataPtr += amount;
- return output;
- }
- /**
- * Allocates enough memory to hold @p count elements of the specified type.
- *
- * @param[in] count Number of elements to allocate.
- */
- template<class T>
- T* alloc(UINT32 count = 1)
- {
- return (T*)alloc(sizeof(T) * count);
- }
- /** Deallocates a previously allocated piece of memory. */
- void free(void* data)
- {
- // Do nothing
- }
- /**
- * Allocates enough memory to hold the object(s) of specified type using the static allocator, and constructs them.
- */
- template<class T>
- T* construct(UINT32 count = 1)
- {
- T* data = (T*)alloc(sizeof(T) * count);
- for(unsigned int i = 0; i < count; i++)
- new ((void*)&data[i]) T;
- return data;
- }
- /**
- * Allocates enough memory to hold the object(s) of specified type using the static allocator, and constructs them.
- */
- template<class T, class... Args>
- T* construct(Args &&...args, UINT32 count = 1)
- {
- T* data = (T*)alloc(sizeof(T) * count);
- for(unsigned int i = 0; i < count; i++)
- new ((void*)&data[i]) T(std::forward<Args>(args)...);
- return data;
- }
- /** Destructs and deallocates an object allocated with the static allocator. */
- template<class T>
- void destruct(T* data)
- {
- data->~T();
- free(data);
- }
- /** Destructs and deallocates an array of objects allocated with the static frame allocator. */
- template<class T>
- void destruct(T* data, UINT32 count)
- {
- for(unsigned int i = 0; i < count; i++)
- data[i].~T();
- free(data);
- }
- private:
- UINT8* mData;
- UINT8* mDataPtr;
- UINT32 mNumBytes;
- };
- /** @} */
- /** @} */
- }
|