DynArray.h algorithm cassert cstddef cstring functional iterator memory type_traits Blob.h InputArchive.h InputArchive.h OutputArchive.h OutputArchive.h TypeDefs.h TypeDefs.h terse::DynArray terse //CopyrightEpicGames,Inc.AllRightsReserved. #pragmaonce #ifdef_MSC_VER #pragmawarning(push) #pragmawarning(disable:43654987) #endif #include<algorithm> #include<cassert> #include<cstddef> #include<cstring> #include<functional> #include<iterator> #include<memory> #include<type_traits> #ifdef_MSC_VER #pragmawarning(pop) #endif namespaceterse{ template<typenameT,classTAllocator> classDynArray{ public: static_assert(std::is_trivial<T>::value,"Uninitializedvectordoesn'tsupportnon-trivialtypes."); usingvalue_type=T; usingallocator_type=TAllocator; private: usingpointer_type=std::unique_ptr<value_type,std::function<void(value_type*)>>; public: explicitDynArray(constallocator_type&allocator): alloc{allocator}, sz{}, ptr{nullptr}{ } DynArray():DynArray{allocator_type{}}{ } DynArray(std::size_tsize,constallocator_type&allocator=allocator_type{}): alloc{allocator}, sz{size}, ptr{create(sz,alloc)}{ } DynArray(std::size_tsize,constvalue_type&value,constallocator_type&allocator=allocator_type{}): DynArray{size,allocator}{ std::fill_n(data(),size,value); } DynArray(constvalue_type*source,std::size_tsize,constallocator_type&allocator=allocator_type{}): DynArray{size,allocator}{ if((data()!=nullptr)&&(source!=nullptr)){ std::memcpy(data(),source,size*sizeof(value_type)); } } template<typenameTIterator> DynArray(TIteratorstart,TIteratorend,constallocator_type&allocator=allocator_type{}): DynArray{static_cast<std::size_t>(std::distance(start,end)),allocator}{ #ifdefined(_MSC_VER)&&!defined(__clang__) if(size()!=0ul){ std::copy(start,end,stdext::checked_array_iterator<value_type*>(data(),size())); } #else std::copy(start,end,data()); #endif } ~DynArray()=default; DynArray(constDynArray&rhs):DynArray{rhs.size(),rhs.get_allocator()}{ if((data()!=nullptr)&&(rhs.data()!=nullptr)){ std::memcpy(data(),rhs.data(),rhs.size()*sizeof(value_type)); } } DynArray&operator=(constDynArray&rhs){ DynArraytmp{rhs}; std::swap(alloc,tmp.alloc); std::swap(ptr,tmp.ptr); std::swap(sz,tmp.sz); return*this; } DynArray(DynArray&&rhs)noexcept: alloc{}, sz{}, ptr{}{ std::swap(alloc,rhs.alloc); std::swap(ptr,rhs.ptr); std::swap(sz,rhs.sz); } DynArray&operator=(DynArray&&rhs)noexcept{ std::swap(alloc,rhs.alloc); std::swap(ptr,rhs.ptr); std::swap(sz,rhs.sz); return*this; } allocator_typeget_allocator()constnoexcept{ returnalloc; } voidclear(){ ptr.reset(); sz=0ul; } value_type*data(){ returnptr.get(); } constvalue_type*data()const{ returnptr.get(); } std::size_tsize()const{ returnsz; } boolempty()const{ return(sz==0ul); } value_type&operator[](std::size_tindex){ assert(index<size()); returndata()[index]; } constvalue_type&operator[](std::size_tindex)const{ assert(index<size()); returndata()[index]; } value_type*begin(){ returndata(); } value_type*end(){ returndata()+sz; } constvalue_type*cbegin()const{ returndata(); } constvalue_type*cend()const{ returndata()+sz; } constvalue_type*begin()const{ returncbegin(); } constvalue_type*end()const{ returncend(); } voidresize(std::size_tsize,constvalue_type&value){ if(size>sz){ pointer_typeold{ptr.release(),[this](value_type*p){ alloc.deallocate(p,sz); }}; ptr=create(size,alloc); assert(ptr!=nullptr); if(old!=nullptr){ std::memcpy(ptr.get(),old.get(),sz*sizeof(value_type)); } std::fill_n(begin()+sz,size-sz,value); } sz=size; } voidresize(std::size_tsize){ resize(size,value_type{}); } voidresize_uninitialized(std::size_tsize){ if(size>sz){ pointer_typeold{ptr.release(),[this](value_type*p){ alloc.deallocate(p,sz); }}; ptr=create(size,alloc); assert(ptr!=nullptr); if(old!=nullptr){ std::memcpy(ptr.get(),old.get(),sz*sizeof(value_type)); } } sz=size; } template<typenameTIterator> voidassign(TIteratorstart,TIteratorend){ resize_uninitialized(static_cast<std::size_t>(std::distance(start,end))); #ifdefined(_MSC_VER)&&!defined(__clang__) if(size()!=0ul){ std::copy(start,end,stdext::checked_array_iterator<value_type*>(data(),size())); } #else std::copy(start,end,data()); #endif } private: staticpointer_typecreate(std::size_tsize,allocator_typealloc){ returnpointer_type{alloc.allocate(size),[alloc,size](value_type*p)mutable{ alloc.deallocate(p,size); }}; } private: allocator_typealloc; std::size_tsz; pointer_typeptr; }; }//namespaceterse