ScopedPtr.h utility Aliases.h Aliases.h Aliases.h ArenaMemoryResource.cpp ArenaMemoryResource.h MemoryMappedFileStreamFallback.cpp MemoryMappedFileStreamFallback.h pma::New pma::Delete pma::New< T[]> pma::Delete< T[]> pma::FactoryCreate pma::FactoryDestroy pma::DefaultInstanceCreator pma::DefaultInstanceDestroyer pma::ScopedPtr pma::ScopedPtr::inspect pma::ScopedPtr::inspect< U[]> pma //CopyrightEpicGames,Inc.AllRightsReserved. #pragmaonce #ifdef_MSC_VER #pragmawarning(push) #pragmawarning(disable:43654987) #endif #include<utility> #ifdef_MSC_VER #pragmawarning(pop) #endif namespacepma{ template<classT,classB=T> structNew{ template<typename...Args> B*operator()(Args&&...args){ returnnewT{std::forward<Args>(args)...}; } }; template<classT,classB=T> structDelete{ voidoperator()(B*ptr){ //Callingdeleteonanincompletetypeisundefinedbehavior. //Thischeckwillresultinacompileerrorforincompletetypes,ratherthanallowUB. #if!defined(__clang__)&&defined(__GNUC__) #pragmaGCCdiagnosticpush #pragmaGCCdiagnosticignored"-Wsign-conversion" #endif usingcomplete_type_checker=char[sizeof(T)?1:-1]; #if!defined(__clang__)&&defined(__GNUC__) #pragmaGCCdiagnosticpop #endif static_cast<void>(sizeof(complete_type_checker)); deleteptr; } }; template<classT> structNew<T[]>{ T*operator()(std::size_tsize){ returnnewT[size]{}; } }; template<classT> structDelete<T[]>{ voidoperator()(T*ptr){ //Callingdeleteonanincompletetypeisundefinedbehavior. //Thischeckwillresultinacompileerrorforincompletetypes,ratherthanallowUB. #if!defined(__clang__)&&defined(__GNUC__) #pragmaGCCdiagnosticpush #pragmaGCCdiagnosticignored"-Wsign-conversion" #endif usingcomplete_type_checker=char[sizeof(T)?1:-1]; #if!defined(__clang__)&&defined(__GNUC__) #pragmaGCCdiagnosticpop #endif static_cast<void>(sizeof(complete_type_checker)); delete[]ptr; } }; template<classT,classB=T> structFactoryCreate{ template<typename...Args> B*operator()(Args&&...args){ returnT::create(std::forward<Args>(args)...); } }; template<classT,classB=T> structFactoryDestroy{ voidoperator()(B*ptr){ T::destroy(static_cast<T*>(ptr)); } }; template<classT> structDefaultInstanceCreator{ usingtype=New<T>; }; template<classT> structDefaultInstanceDestroyer{ usingtype=Delete<T>; }; template<classT,classTDestroyer=typenameDefaultInstanceDestroyer<T>::type> classScopedPtr:privateTDestroyer{ private: template<typenameU> structinspect{ usingelement_type=U; usingpointer_type=element_type*; usingis_array=std::false_type; }; template<typenameU> structinspect<U[]>{ usingelement_type=U; usingpointer_type=element_type*; usingis_array=std::true_type; }; public: usingpointer=typenameinspect<T>::pointer_type; usingelement_type=typenameinspect<T>::element_type; usingdestroyer_type=TDestroyer; template<typenameU,classUDestroyer> friendclassScopedPtr; public: ScopedPtr():ptr{nullptr}{ } explicitScopedPtr(pointerptr_):ptr{ptr_}{ } ScopedPtr(pointerptr_,destroyer_type&&destroyer):destroyer_type{std::move(destroyer)},ptr{ptr_}{ } ~ScopedPtr(){ if(ptr){ destroyer_type::operator()(ptr); ptr=pointer{}; } } ScopedPtr(std::nullptr_t):ptr{nullptr}{ } ScopedPtr&operator=(std::nullptr_t){ reset(); return*this; } ScopedPtr(constScopedPtr&)=delete; ScopedPtr&operator=(constScopedPtr&)=delete; ScopedPtr(ScopedPtr&&rhs)noexcept:ptr{nullptr}{ rhs.swap(*this); } ScopedPtr&operator=(ScopedPtr&&rhs)noexcept{ rhs.swap(*this); return*this; } template<typenameU,classUDestroyer> ScopedPtr(ScopedPtr<U, UDestroyer>&&rhs)noexcept:ptr{nullptr}{ ScopedPtr<T, destroyer_type>tmp{rhs.release(),static_cast<UDestroyer&&>(rhs)}; tmp.swap(*this); } template<typenameU,classUDestroyer> ScopedPtr&operator=(ScopedPtr<U, UDestroyer>&&rhs)noexcept{ ScopedPtr<T, destroyer_type>tmp{rhs.release(),static_cast<UDestroyer&&>(rhs)}; tmp.swap(*this); return*this; } template<typenameU=T,typenameIA=typenameinspect<U>::is_array> typenamestd::enable_if<IA::value,element_type&>::typeoperator[](std::size_tindex)constnoexcept{ returnptr[index]; } template<typenameU=T,typenameIA=typenameinspect<U>::is_array> typenamestd::enable_if<!IA::value,element_type&>::typeoperator*()constnoexcept{ return*ptr; } pointeroperator->()constnoexcept{ returnptr; } operatorbool()constnoexcept{ returnptr!=nullptr; } pointerget()constnoexcept{ returnptr; } pointerrelease()noexcept{ pointerresult=nullptr; std::swap(result,ptr); returnresult; } voidreset(pointerrhs=pointer())noexcept{ pointerold=release(); ptr=rhs; if(old){ destroyer_type::operator()(old); } } voidswap(ScopedPtr&rhs)noexcept{ std::swap(static_cast<destroyer_type&>(*this),static_cast<destroyer_type&>(rhs)); std::swap(ptr,rhs.ptr); } private: pointerptr; }; template<classT,classTCreator,classTDestroyer,typename...Args, typenameBase=typenamestd::remove_pointer<decltype(TCreator{}(std::declval<Args>()...))>::type> ScopedPtr<Base, TDestroyer>makeScoped(Args&&...args){ static_assert(std::is_same<Base,T>::value|| std::is_base_of<Base,T>::value|| std::is_convertible<T,typenamestd::add_pointer<Base>::type>::value, "Incompatibletypes."); returnScopedPtr<Base, TDestroyer>{TCreator{}(std::forward<Args>(args)...)}; } template<classT,template<class...>classTCreatorTemplate,template<class...>classTDestroyerTemplate,typename...Args> ScopedPtr<T, TDestroyerTemplate<T>>makeScoped(Args&&...args){ usingTCreator=TCreatorTemplate<T>; usingTDestroyer=TDestroyerTemplate<T>; returnmakeScoped<T,TCreator,TDestroyer>(std::forward<Args>(args)...); } template<classT,typename...Args> ScopedPtr<T, typename DefaultInstanceDestroyer<T>::type>makeScoped(Args&&...args){ usingTCreator=typenameDefaultInstanceCreator<T>::type; usingTDestroyer=typenameDefaultInstanceDestroyer<T>::type; returnmakeScoped<T,TCreator,TDestroyer>(std::forward<Args>(args)...); } }//namespacepma