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