AlignedMemoryResource.cpp pma/resources/AlignedMemoryResource.h cassert cstddef cstdint cstdlib pma ALIGNED_ALLOC ptr alignment size ptr = alignedAlloc(size, alignment) ALIGNED_FREE ptr alignedFree(ptr) std::uintptr_t std::uintptr_t alignAddress (std::uintptr_t address, std::size_t alignment) alignAddress std::uintptr_t address std::size_t alignment alignPointer typename T T * T * alignPointer (T *ptr, std::size_t alignment) alignPointer T * ptr std::size_t alignment alignAddress alignedAlloc void * void * alignedAlloc (std::size_t size, std::size_t alignment) alignedAlloc std::size_t size std::size_t alignment alignPointer void void alignedFree (void *ptr) alignedFree void * ptr //CopyrightEpicGames,Inc.AllRightsReserved. #include"pma/resources/AlignedMemoryResource.h" #include<cassert> #include<cstddef> #include<cstdint> #include<cstdlib> #ifdefined(__linux__)||defined(__APPLE__) #include<stdlib.h> #elifdefined(_MSC_VER)||defined(__ANDROID__) #include<malloc.h> #endif #ifdefined(__cplusplus)&&(__cplusplus>=201703L)&&(defined(_GLIBCXX_HAVE_ALIGNED_ALLOC)||\ defined(_LIBCPP_HAS_ALIGNED_ALLOC)||defined(_LIBCPP_HAS_C11_FEATURES)) #defineALIGNED_ALLOC(ptr,alignment,size)ptr=std::aligned_alloc(alignment,size) #defineALIGNED_FREE(ptr)std::free(ptr) #elif((defined(_POSIX_VERSION)&&(_POSIX_VERSION>=200112L))||defined(__linux__)||defined(__APPLE__)) #defineALIGNED_ALLOC(ptr,alignment,size)if(::posix_memalign(&(ptr),alignment,size))\ (ptr)=nullptr #defineALIGNED_FREE(ptr)::free(ptr) #elifdefined(_MSC_VER) #defineALIGNED_ALLOC(ptr,alignment,size)ptr=_aligned_malloc(size,alignment) #defineALIGNED_FREE(ptr)_aligned_free(ptr) #elifdefined(__ANDROID__) #defineALIGNED_ALLOC(ptr,alignment,size)ptr=::memalign(alignment,size) #defineALIGNED_FREE(ptr)::free(ptr) #else inlinestd::uintptr_talignAddress(std::uintptr_taddress,std::size_talignment){ conststd::size_tmask=alignment-1ul; assert((alignment&mask)==0ul); return(address+mask)&~mask; } template<typenameT> inlineT*alignPointer(T*ptr,std::size_talignment){ conststd::uintptr_taddress=reinterpret_cast<std::uintptr_t>(ptr); conststd::uintptr_taligned=alignAddress(address,alignment); returnreinterpret_cast<T*>(aligned); } void*alignedAlloc(std::size_tsize,std::size_talignment){ conststd::size_tactualSize=size+alignment; char*pUnalignedChunk=newchar[actualSize]; char*pAlignedChunk=alignPointer(pUnalignedChunk,alignment); if(pAlignedChunk==pUnalignedChunk){ //Therewasnoneedforadditionalalignment,soanartificalgap //mustbeaddedtomakeroomfortheshiftvalue pAlignedChunk+=alignment; } //Computeandwritetheshiftvalueintothebuffer(itisneededduring //deallocationtoreconstructbywhichamountwasthegivenpointer //offsettomeetthealignmentrequirement) std::ptrdiff_tshift=pAlignedChunk-pUnalignedChunk; //Theguaranteedstoragesizefortheshiftvalueisonlyonebyte assert(shift>0&&shift<=256); pAlignedChunk[-1]=static_cast<char>(shift&0xFF); returnstatic_cast<void*>(pAlignedChunk); } voidalignedFree(void*ptr){ if(ptr){ autopAlignedChunk=reinterpret_cast<char*>(ptr); std::ptrdiff_tshift=pAlignedChunk[-1]; //Thereisno0alignment,sothevalueisreusedtoactuallydenotealignmentby256 if(shift==0){ shift=256; } //Computetheactualstartaddressofthechunk,priortoaligningit'saddress autopUnalignedChunk=pAlignedChunk-shift; delete[]pUnalignedChunk; } } #defineALIGNED_ALLOC(ptr,alignment,size)ptr=alignedAlloc(size,alignment) #defineALIGNED_FREE(ptr)alignedFree(ptr) #endif namespacepma{ void*AlignedMemoryResource::allocate(std::size_tsize,std::size_talignment){ void*ptr; ALIGNED_ALLOC(ptr,alignment,size); returnptr; } voidAlignedMemoryResource::deallocate(void*ptr,std::size_t/*unused*/,std::size_t/*unused*/){ //NOLINTNEXTLINE(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc,hicpp-no-malloc) ALIGNED_FREE(ptr); } }//namespacepma