ArchiveOffset.h cstddef cstdint memory DNA.h DNA.h InputArchive.h InputArchive.h OutputArchive.h OutputArchive.h terse::ArchiveOffset terse::ArchiveOffset::Proxy terse //CopyrightEpicGames,Inc.AllRightsReserved. #pragmaonce #ifdef_MSC_VER #pragmawarning(push) #pragmawarning(disable:43654987) #endif #include<cstddef> #include<cstdint> #include<memory> #ifdef_MSC_VER #pragmawarning(pop) #endif namespaceterse{ //ArchiveOffsetisatypethatstoresanabsolutestreamoffset(bothin-memoryandwritesthatvalueintothestreamaswell). //IthasanaccompanyingProxytype,whichisavirtual,utilitytype,andtheyworktogethertoachievethefunction //ofArchiveOffset. //WhenArchiveOffsetisencounteredduringtheserializationprocess,atfirstanemptyoffset(zero)valuewillbewritten //intothestreamandthepositionofthatoffsetvaluewillbecapturedinanin-memoryvariable.Later,whenitsassociated //ArchiveOffset<T>::Proxyisencountered,thecurrentstreampositionwillbecaptured,anditwillupdatethein-memoryvalue //ofitsArchiveOffsetwithit.Then,itwillseekthestreamtotheearliercapturedpositionoftheoffsetvalue(wherezeros //werewritteninitially),anditwillwritetheoffsetvaluecapturedbytheproxyintothestream.Lastly,itwillseekback //tothepositionofthestreambeforetheproxywasencountered,andresumeserialization. template<typenameTOffset> structArchiveOffset{ usingValueType=TOffset; structProxy{ ArchiveOffset*target; explicitProxy(ArchiveOffset&ptr):target{std::addressof(ptr)}{ target->proxy=this; } ~Proxy(){ if(target!=nullptr){ target->proxy=nullptr; } } Proxy(constProxy&)=delete; Proxy&operator=(constProxy&)=delete; Proxy(Proxy&&rhs):target{nullptr}{ std::swap(target,rhs.target); target->proxy=this; } Proxy&operator=(Proxy&&rhs){ std::swap(target,rhs.target); target->proxy=this; return*this; } }; //Thepositionofthemarkeritselfinthestream(thisisaruntime-onlyvalue //whichisnotwrittentothefile,neededonlyfortheserializertoknowwhere //toseekwithinthestreamwhenthemarker'sactualvalueneedstobewritten) mutablestd::size_tposition; //Thepositioninthestreamwherethemarkerwantstopoint(thisistheactual //valuethatiswrittentothefile) mutableValueTypevalue; //Whenoffsetismoved,it'sassociatedproxymustbeupdatedaboutthenewaddress Proxy*proxy; ArchiveOffset():position{},value{},proxy{nullptr}{ } ~ArchiveOffset()=default; ArchiveOffset(constArchiveOffset&)=delete; ArchiveOffset&operator=(constArchiveOffset&)=delete; ArchiveOffset(ArchiveOffset&&rhs):position{},value{},proxy{nullptr}{ std::swap(position,rhs.position); std::swap(value,rhs.value); std::swap(proxy,rhs.proxy); //Updateproxywithnewaddress if(proxy!=nullptr){ proxy->target=this; } } ArchiveOffset&operator=(ArchiveOffset&&rhs){ std::swap(position,rhs.position); std::swap(value,rhs.value); std::swap(proxy,rhs.proxy); //Updateproxywithnewaddress if(proxy!=nullptr){ proxy->target=this; } return*this; } }; template<typenameTOffset> typenameArchiveOffset<TOffset>::Proxyproxy(ArchiveOffset<TOffset>&offset){ returntypenameArchiveOffset<TOffset>::Proxy{offset}; } }//namespaceterse