nuclear@3: /************************************************************************************ nuclear@3: nuclear@3: PublicHeader: OVR.h nuclear@3: Filename : OVR_ContainerAllocator.h nuclear@3: Content : Template allocators and constructors for containers. nuclear@3: Created : September 19, 2012 nuclear@3: Notes : nuclear@3: nuclear@3: Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. nuclear@3: nuclear@3: Use of this software is subject to the terms of the Oculus license nuclear@3: agreement provided at the time of installation or download, or which nuclear@3: otherwise accompanies this software in either electronic or hard copy form. nuclear@3: nuclear@3: ************************************************************************************/ nuclear@3: nuclear@3: #ifndef OVR_ContainerAllocator_h nuclear@3: #define OVR_ContainerAllocator_h nuclear@3: nuclear@3: #include "OVR_Allocator.h" nuclear@3: #include nuclear@3: nuclear@3: nuclear@3: namespace OVR { nuclear@3: nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** Container Allocator nuclear@3: nuclear@3: // ContainerAllocator serves as a template argument for allocations done by nuclear@3: // containers, such as Array and Hash; replacing it could allow allocator nuclear@3: // substitution in containers. nuclear@3: nuclear@3: class ContainerAllocatorBase nuclear@3: { nuclear@3: public: nuclear@3: static void* Alloc(UPInt size) { return OVR_ALLOC(size); } nuclear@3: static void* Realloc(void* p, UPInt newSize) { return OVR_REALLOC(p, newSize); } nuclear@3: static void Free(void *p) { OVR_FREE(p); } nuclear@3: }; nuclear@3: nuclear@3: nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** Constructors, Destructors, Copiers nuclear@3: nuclear@3: // Plain Old Data - movable, no special constructors/destructor. nuclear@3: template nuclear@3: class ConstructorPOD nuclear@3: { nuclear@3: public: nuclear@3: static void Construct(void *) {} nuclear@3: static void Construct(void *p, const T& source) nuclear@3: { nuclear@3: *(T*)p = source; nuclear@3: } nuclear@3: nuclear@3: // Same as above, but allows for a different type of constructor. nuclear@3: template nuclear@3: static void ConstructAlt(void *p, const S& source) nuclear@3: { nuclear@3: *(T*)p = source; nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void*, UPInt) {} nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count, const T& source) nuclear@3: { nuclear@3: UByte *pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: *(T*)pdata = source; nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count, const T* psource) nuclear@3: { nuclear@3: memcpy(p, psource, sizeof(T) * count); nuclear@3: } nuclear@3: nuclear@3: static void Destruct(T*) {} nuclear@3: static void DestructArray(T*, UPInt) {} nuclear@3: nuclear@3: static void CopyArrayForward(T* dst, const T* src, UPInt count) nuclear@3: { nuclear@3: memmove(dst, src, count * sizeof(T)); nuclear@3: } nuclear@3: nuclear@3: static void CopyArrayBackward(T* dst, const T* src, UPInt count) nuclear@3: { nuclear@3: memmove(dst, src, count * sizeof(T)); nuclear@3: } nuclear@3: nuclear@3: static bool IsMovable() { return true; } nuclear@3: }; nuclear@3: nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** ConstructorMov nuclear@3: // nuclear@3: // Correct C++ construction and destruction for movable objects nuclear@3: template nuclear@3: class ConstructorMov nuclear@3: { nuclear@3: public: nuclear@3: static void Construct(void* p) nuclear@3: { nuclear@3: OVR::Construct(p); nuclear@3: } nuclear@3: nuclear@3: static void Construct(void* p, const T& source) nuclear@3: { nuclear@3: OVR::Construct(p, source); nuclear@3: } nuclear@3: nuclear@3: // Same as above, but allows for a different type of constructor. nuclear@3: template nuclear@3: static void ConstructAlt(void* p, const S& source) nuclear@3: { nuclear@3: OVR::ConstructAlt(p, source); nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count) nuclear@3: { nuclear@3: UByte* pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: Construct(pdata); nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count, const T& source) nuclear@3: { nuclear@3: UByte* pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: Construct(pdata, source); nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count, const T* psource) nuclear@3: { nuclear@3: UByte* pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: Construct(pdata, *psource++); nuclear@3: } nuclear@3: nuclear@3: static void Destruct(T* p) nuclear@3: { nuclear@3: p->~T(); nuclear@3: OVR_UNUSED(p); // Suppress silly MSVC warning nuclear@3: } nuclear@3: nuclear@3: static void DestructArray(T* p, UPInt count) nuclear@3: { nuclear@3: p += count - 1; nuclear@3: for (UPInt i=0; i~T(); nuclear@3: } nuclear@3: nuclear@3: static void CopyArrayForward(T* dst, const T* src, UPInt count) nuclear@3: { nuclear@3: memmove(dst, src, count * sizeof(T)); nuclear@3: } nuclear@3: nuclear@3: static void CopyArrayBackward(T* dst, const T* src, UPInt count) nuclear@3: { nuclear@3: memmove(dst, src, count * sizeof(T)); nuclear@3: } nuclear@3: nuclear@3: static bool IsMovable() { return true; } nuclear@3: }; nuclear@3: nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** ConstructorCPP nuclear@3: // nuclear@3: // Correct C++ construction and destruction for movable objects nuclear@3: template nuclear@3: class ConstructorCPP nuclear@3: { nuclear@3: public: nuclear@3: static void Construct(void* p) nuclear@3: { nuclear@3: OVR::Construct(p); nuclear@3: } nuclear@3: nuclear@3: static void Construct(void* p, const T& source) nuclear@3: { nuclear@3: OVR::Construct(p, source); nuclear@3: } nuclear@3: nuclear@3: // Same as above, but allows for a different type of constructor. nuclear@3: template nuclear@3: static void ConstructAlt(void* p, const S& source) nuclear@3: { nuclear@3: OVR::ConstructAlt(p, source); nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count) nuclear@3: { nuclear@3: UByte* pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: Construct(pdata); nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count, const T& source) nuclear@3: { nuclear@3: UByte* pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: Construct(pdata, source); nuclear@3: } nuclear@3: nuclear@3: static void ConstructArray(void* p, UPInt count, const T* psource) nuclear@3: { nuclear@3: UByte* pdata = (UByte*)p; nuclear@3: for (UPInt i=0; i< count; ++i, pdata += sizeof(T)) nuclear@3: Construct(pdata, *psource++); nuclear@3: } nuclear@3: nuclear@3: static void Destruct(T* p) nuclear@3: { nuclear@3: p->~T(); nuclear@3: OVR_UNUSED(p); // Suppress silly MSVC warning nuclear@3: } nuclear@3: nuclear@3: static void DestructArray(T* p, UPInt count) nuclear@3: { nuclear@3: p += count - 1; nuclear@3: for (UPInt i=0; i~T(); nuclear@3: } nuclear@3: nuclear@3: static void CopyArrayForward(T* dst, const T* src, UPInt count) nuclear@3: { nuclear@3: for(UPInt i = 0; i < count; ++i) nuclear@3: dst[i] = src[i]; nuclear@3: } nuclear@3: nuclear@3: static void CopyArrayBackward(T* dst, const T* src, UPInt count) nuclear@3: { nuclear@3: for(UPInt i = count; i; --i) nuclear@3: dst[i-1] = src[i-1]; nuclear@3: } nuclear@3: nuclear@3: static bool IsMovable() { return false; } nuclear@3: }; nuclear@3: nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** Container Allocator with movement policy nuclear@3: // nuclear@3: // Simple wraps as specialized allocators nuclear@3: template struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD {}; nuclear@3: template struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov {}; nuclear@3: template struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP {}; nuclear@3: nuclear@3: nuclear@3: } // OVR nuclear@3: nuclear@3: nuclear@3: #endif