mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/urde
This commit is contained in:
commit
58c2b2e82d
|
@ -22,8 +22,8 @@ struct PATH : BigDNA
|
||||||
struct Link : BigDNA
|
struct Link : BigDNA
|
||||||
{
|
{
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atUint32> regionIdx;
|
|
||||||
Value<atUint32> nodeIdx;
|
Value<atUint32> nodeIdx;
|
||||||
|
Value<atUint32> regionIdx;
|
||||||
Value<float> width2d;
|
Value<float> width2d;
|
||||||
Value<float> oneOverWidth2d;
|
Value<float> oneOverWidth2d;
|
||||||
};
|
};
|
||||||
|
|
|
@ -63,7 +63,7 @@ CPlayerState::CPlayerState()
|
||||||
: x188_staticIntf(5)
|
: x188_staticIntf(5)
|
||||||
{
|
{
|
||||||
x0_24_alive = true;
|
x0_24_alive = true;
|
||||||
x24_powerups.set_size(41);
|
x24_powerups.resize(41);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlayerState::CPlayerState(CBitStreamReader& stream)
|
CPlayerState::CPlayerState(CBitStreamReader& stream)
|
||||||
|
@ -74,7 +74,7 @@ CPlayerState::CPlayerState(CBitStreamReader& stream)
|
||||||
xc_health.SetHP(*reinterpret_cast<float*>(&tmp));
|
xc_health.SetHP(*reinterpret_cast<float*>(&tmp));
|
||||||
x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5)));
|
x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5)));
|
||||||
x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4)));
|
x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4)));
|
||||||
x24_powerups.set_size(41);
|
x24_powerups.resize(41);
|
||||||
for (u32 i = 0; i < x24_powerups.size(); ++i)
|
for (u32 i = 0; i < x24_powerups.size(); ++i)
|
||||||
{
|
{
|
||||||
if (PowerUpMaxValues[i] == 0)
|
if (PowerUpMaxValues[i] == 0)
|
||||||
|
|
|
@ -122,7 +122,7 @@ private:
|
||||||
EPlayerVisor x18_transitioningVisor = x14_currentVisor;
|
EPlayerVisor x18_transitioningVisor = x14_currentVisor;
|
||||||
float x1c_visorTransitionFactor = 0.2f;
|
float x1c_visorTransitionFactor = 0.2f;
|
||||||
EPlayerSuit x20_currentSuit = EPlayerSuit::Power;
|
EPlayerSuit x20_currentSuit = EPlayerSuit::Power;
|
||||||
rstl::prereserved_vector<CPowerUp, 41> x24_powerups;
|
rstl::reserved_vector<CPowerUp, 41> x24_powerups;
|
||||||
rstl::reserved_vector<std::pair<CAssetId, float>, 846> x170_scanTimes;
|
rstl::reserved_vector<std::pair<CAssetId, float>, 846> x170_scanTimes;
|
||||||
std::pair<u32, u32> x180_scanCompletionRate = {};
|
std::pair<u32, u32> x180_scanCompletionRate = {};
|
||||||
CStaticInterference x188_staticIntf;
|
CStaticInterference x188_staticIntf;
|
||||||
|
|
|
@ -52,7 +52,7 @@ static const u16 SelectionSfxs[] =
|
||||||
};
|
};
|
||||||
|
|
||||||
CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type,
|
CHudVisorBeamMenu::CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type,
|
||||||
const rstl::prereserved_vector<bool, 4>& enables)
|
const rstl::reserved_vector<bool, 4>& enables)
|
||||||
: x0_baseHud(baseHud), x4_type(type)
|
: x0_baseHud(baseHud), x4_type(type)
|
||||||
{
|
{
|
||||||
x14_24_visibleDebug = true;
|
x14_24_visibleDebug = true;
|
||||||
|
@ -300,7 +300,7 @@ void CHudVisorBeamMenu::SetIsVisibleGame(bool v)
|
||||||
Update(0.f, true);
|
Update(0.f, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHudVisorBeamMenu::SetPlayerHas(const rstl::prereserved_vector<bool, 4>& enables)
|
void CHudVisorBeamMenu::SetPlayerHas(const rstl::reserved_vector<bool, 4>& enables)
|
||||||
{
|
{
|
||||||
for (int i=0 ; i<4 ; ++i)
|
for (int i=0 ; i<4 ; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,11 +59,11 @@ private:
|
||||||
void UpdateMenuWidgetTransform(int, CGuiWidget& w, float);
|
void UpdateMenuWidgetTransform(int, CGuiWidget& w, float);
|
||||||
public:
|
public:
|
||||||
CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type,
|
CHudVisorBeamMenu(CGuiFrame& baseHud, EHudVisorBeamMenu type,
|
||||||
const rstl::prereserved_vector<bool, 4>& enables);
|
const rstl::reserved_vector<bool, 4>& enables);
|
||||||
void Update(float dt, bool init);
|
void Update(float dt, bool init);
|
||||||
void UpdateHudAlpha(float alpha);
|
void UpdateHudAlpha(float alpha);
|
||||||
void SetIsVisibleGame(bool v);
|
void SetIsVisibleGame(bool v);
|
||||||
void SetPlayerHas(const rstl::prereserved_vector<bool, 4>& enables);
|
void SetPlayerHas(const rstl::reserved_vector<bool, 4>& enables);
|
||||||
void SetSelection(int, int, float);
|
void SetSelection(int, int, float);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,12 +51,12 @@ CSamusHud::CSamusHud(CStateManager& stateMgr)
|
||||||
x274_loadedFrmeBaseHud->SetMaxAspect(1.78f);
|
x274_loadedFrmeBaseHud->SetMaxAspect(1.78f);
|
||||||
x2a0_helmetIntf = std::make_unique<CHudHelmetInterface>(*x264_loadedFrmeHelmet);
|
x2a0_helmetIntf = std::make_unique<CHudHelmetInterface>(*x264_loadedFrmeHelmet);
|
||||||
|
|
||||||
rstl::prereserved_vector<bool, 4> hasVisors = BuildPlayerHasVisors(stateMgr);
|
rstl::reserved_vector<bool, 4> hasVisors = BuildPlayerHasVisors(stateMgr);
|
||||||
x2a4_visorMenu = std::make_unique<CHudVisorBeamMenu>(*x274_loadedFrmeBaseHud,
|
x2a4_visorMenu = std::make_unique<CHudVisorBeamMenu>(*x274_loadedFrmeBaseHud,
|
||||||
CHudVisorBeamMenu::EHudVisorBeamMenu::Visor,
|
CHudVisorBeamMenu::EHudVisorBeamMenu::Visor,
|
||||||
hasVisors);
|
hasVisors);
|
||||||
|
|
||||||
rstl::prereserved_vector<bool, 4> hasBeams = BuildPlayerHasBeams(stateMgr);
|
rstl::reserved_vector<bool, 4> hasBeams = BuildPlayerHasBeams(stateMgr);
|
||||||
x2a8_beamMenu = std::make_unique<CHudVisorBeamMenu>(*x274_loadedFrmeBaseHud,
|
x2a8_beamMenu = std::make_unique<CHudVisorBeamMenu>(*x274_loadedFrmeBaseHud,
|
||||||
CHudVisorBeamMenu::EHudVisorBeamMenu::Beam,
|
CHudVisorBeamMenu::EHudVisorBeamMenu::Beam,
|
||||||
hasBeams);
|
hasBeams);
|
||||||
|
@ -76,23 +76,23 @@ CSamusHud::~CSamusHud()
|
||||||
g_SamusHud = nullptr;
|
g_SamusHud = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rstl::prereserved_vector<bool, 4> CSamusHud::BuildPlayerHasVisors(const CStateManager& mgr)
|
rstl::reserved_vector<bool, 4> CSamusHud::BuildPlayerHasVisors(const CStateManager& mgr)
|
||||||
{
|
{
|
||||||
rstl::prereserved_vector<bool, 4> ret;
|
rstl::reserved_vector<bool, 4> ret;
|
||||||
ret[0] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::CombatVisor);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::CombatVisor));
|
||||||
ret[1] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::XRayVisor);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::XRayVisor));
|
||||||
ret[2] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ScanVisor);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ScanVisor));
|
||||||
ret[3] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ThermalVisor);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::ThermalVisor));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
rstl::prereserved_vector<bool, 4> CSamusHud::BuildPlayerHasBeams(const CStateManager& mgr)
|
rstl::reserved_vector<bool, 4> CSamusHud::BuildPlayerHasBeams(const CStateManager& mgr)
|
||||||
{
|
{
|
||||||
rstl::prereserved_vector<bool, 4> ret;
|
rstl::reserved_vector<bool, 4> ret;
|
||||||
ret[0] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PowerBeam);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PowerBeam));
|
||||||
ret[1] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::IceBeam);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::IceBeam));
|
||||||
ret[2] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::WaveBeam);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::WaveBeam));
|
||||||
ret[3] = mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PlasmaBeam);
|
ret.push_back(mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PlasmaBeam));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,8 +194,8 @@ class CSamusHud
|
||||||
CCookieCutterDepthRandomStaticFilter m_cookieCutterStatic = { EFilterType::NoColor };
|
CCookieCutterDepthRandomStaticFilter m_cookieCutterStatic = { EFilterType::NoColor };
|
||||||
|
|
||||||
static CSamusHud* g_SamusHud;
|
static CSamusHud* g_SamusHud;
|
||||||
static rstl::prereserved_vector<bool, 4> BuildPlayerHasVisors(const CStateManager& mgr);
|
static rstl::reserved_vector<bool, 4> BuildPlayerHasVisors(const CStateManager& mgr);
|
||||||
static rstl::prereserved_vector<bool, 4> BuildPlayerHasBeams(const CStateManager& mgr);
|
static rstl::reserved_vector<bool, 4> BuildPlayerHasBeams(const CStateManager& mgr);
|
||||||
void InitializeFrameGluePermanent(const CStateManager& mgr);
|
void InitializeFrameGluePermanent(const CStateManager& mgr);
|
||||||
void InitializeFrameGlueMutable(const CStateManager& mgr);
|
void InitializeFrameGlueMutable(const CStateManager& mgr);
|
||||||
void UninitializeFrameGlueMutable();
|
void UninitializeFrameGlueMutable();
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
u32 x80_ = 0;
|
u32 x80_ = 0;
|
||||||
u32 x84_ = -1;
|
u32 x84_ = -1;
|
||||||
u32 x88_seed1 = 99;
|
u32 x88_seed1 = 99;
|
||||||
rstl::prereserved_vector<std::unique_ptr<CElementGen>, 4> x8c_thermalColdParticles;
|
rstl::reserved_vector<std::unique_ptr<CElementGen>, 4> x8c_thermalColdParticles;
|
||||||
s32 xb0_ = -1;
|
s32 xb0_ = -1;
|
||||||
u32 xb4_seed2 = 99;
|
u32 xb4_seed2 = 99;
|
||||||
std::unique_ptr<CElementGen> xb8_;
|
std::unique_ptr<CElementGen> xb8_;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdlib.h>
|
||||||
#include "CPathFindArea.hpp"
|
#include "CPathFindArea.hpp"
|
||||||
#include "IVParamObj.hpp"
|
#include "IVParamObj.hpp"
|
||||||
#include "CToken.hpp"
|
#include "CToken.hpp"
|
||||||
|
@ -8,12 +9,12 @@ namespace urde
|
||||||
CPFAreaOctree::CPFAreaOctree(CMemoryInStream& in)
|
CPFAreaOctree::CPFAreaOctree(CMemoryInStream& in)
|
||||||
{
|
{
|
||||||
x0_isLeaf = in.readUint32Big();
|
x0_isLeaf = in.readUint32Big();
|
||||||
for (int i=0 ; i<3 ; ++i)
|
x4_aabb.readBoundingBoxBig(in);
|
||||||
x4_points[i] = in.readVec3fBig();
|
x1c_center.readBig(in);
|
||||||
for (int i=0 ; i<8 ; ++i)
|
for (int i=0 ; i<8 ; ++i)
|
||||||
x28_children[i] = reinterpret_cast<CPFAreaOctree*>(in.readUint32Big());
|
x28_children[i] = reinterpret_cast<CPFAreaOctree*>(in.readUint32Big());
|
||||||
x48_regionCount = in.readUint32Big();
|
x48_regions.set_size(in.readUint32Big());
|
||||||
x4c_regions = reinterpret_cast<CPFRegion**>(in.readUint32Big());
|
x48_regions.set_data(reinterpret_cast<CPFRegion**>(in.readUint32Big()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPFAreaOctree::Fixup(CPFArea& area)
|
void CPFAreaOctree::Fixup(CPFArea& area)
|
||||||
|
@ -21,9 +22,9 @@ void CPFAreaOctree::Fixup(CPFArea& area)
|
||||||
x0_isLeaf = x0_isLeaf != 0 ? 1 : 0;
|
x0_isLeaf = x0_isLeaf != 0 ? 1 : 0;
|
||||||
if (x0_isLeaf)
|
if (x0_isLeaf)
|
||||||
{
|
{
|
||||||
if (!x48_regionCount)
|
if (x48_regions.empty())
|
||||||
return;
|
return;
|
||||||
x4c_regions = &area.x160_octreeRegionLookup[reinterpret_cast<uintptr_t>(x4c_regions)];
|
x48_regions.set_data(&area.x160_octreeRegionLookup[reinterpret_cast<uintptr_t>(x48_regions.data())]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +37,18 @@ void CPFAreaOctree::Fixup(CPFArea& area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CPFAreaOctree::GetChildIndex(const zeus::CVector3f& point) const
|
||||||
|
{
|
||||||
|
int idx = 0x0;
|
||||||
|
if (point.x > x1c_center.x)
|
||||||
|
idx = 0x1;
|
||||||
|
if (point.y > x1c_center.y)
|
||||||
|
idx |= 0x2;
|
||||||
|
if (point.z > x1c_center.z)
|
||||||
|
idx |= 0x4;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
CPFOpenList::CPFOpenList()
|
CPFOpenList::CPFOpenList()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -75,12 +88,12 @@ CPFArea::CPFArea(std::unique_ptr<u8[]>&& buf, u32 len)
|
||||||
x10_.reserve(maxRegionNodes);
|
x10_.reserve(maxRegionNodes);
|
||||||
|
|
||||||
u32 numBitfieldWords = (numRegions * (numRegions - 1) / 2 + 31) / 32;
|
u32 numBitfieldWords = (numRegions * (numRegions - 1) / 2 + 31) / 32;
|
||||||
x168_connectionsA.reserve(numBitfieldWords);
|
x168_connectionsGround.reserve(numBitfieldWords);
|
||||||
for (u32 i=0 ; i<numBitfieldWords ; ++i)
|
for (u32 i=0 ; i<numBitfieldWords ; ++i)
|
||||||
x168_connectionsA.push_back(r.readUint32Big());
|
x168_connectionsGround.push_back(r.readUint32Big());
|
||||||
x170_connectionsB.reserve(numBitfieldWords);
|
x170_connectionsFlyers.reserve(numBitfieldWords);
|
||||||
for (u32 i=0 ; i<numBitfieldWords ; ++i)
|
for (u32 i=0 ; i<numBitfieldWords ; ++i)
|
||||||
x170_connectionsB.push_back(r.readUint32Big());
|
x170_connectionsFlyers.push_back(r.readUint32Big());
|
||||||
|
|
||||||
r.seek(((((numRegions * numRegions) + 31) / 32) - numBitfieldWords) * 2 * sizeof(u32));
|
r.seek(((((numRegions * numRegions) + 31) / 32) - numBitfieldWords) * 2 * sizeof(u32));
|
||||||
|
|
||||||
|
@ -101,6 +114,28 @@ CPFArea::CPFArea(std::unique_ptr<u8[]>&& buf, u32 len)
|
||||||
node.Fixup(*this);
|
node.Fixup(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPFArea::PathExists(const CPFRegion* r1, const CPFRegion* r2, u32 flags) const
|
||||||
|
{
|
||||||
|
if (r1 == r2 || (flags & 0x4) != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
u32 i1 = r1->GetIndex();
|
||||||
|
u32 i2 = r2->GetIndex();
|
||||||
|
if (i1 > i2)
|
||||||
|
std::swap(i1, i2);
|
||||||
|
|
||||||
|
u32 remRegions = u32(x150_regions.size()) - i1;
|
||||||
|
u32 remConnections = remRegions * (remRegions - 1) / 2;
|
||||||
|
u32 totalConnections = u32(x150_regions.size()) * (u32(x150_regions.size()) - 1) / 2;
|
||||||
|
u32 bit = totalConnections - remConnections + i2 - (i1 + 1);
|
||||||
|
|
||||||
|
auto d = std::div(bit, 32);
|
||||||
|
if ((flags & 0x2) != 0)
|
||||||
|
return ((x170_connectionsFlyers[d.quot] >> d.rem) & 0x1) == 0x1;
|
||||||
|
else
|
||||||
|
return ((x168_connectionsGround[d.quot] >> d.rem) & 0x1) == 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
CFactoryFnReturn FPathFindAreaFactory(const urde::SObjectTag& tag,
|
CFactoryFnReturn FPathFindAreaFactory(const urde::SObjectTag& tag,
|
||||||
std::unique_ptr<u8[]>&& in, u32 len,
|
std::unique_ptr<u8[]>&& in, u32 len,
|
||||||
const urde::CVParamTransfer& vparms,
|
const urde::CVParamTransfer& vparms,
|
||||||
|
|
|
@ -25,16 +25,16 @@ public:
|
||||||
class CPFAreaOctree
|
class CPFAreaOctree
|
||||||
{
|
{
|
||||||
u32 x0_isLeaf;
|
u32 x0_isLeaf;
|
||||||
zeus::CVector3f x4_points[3];
|
zeus::CAABox x4_aabb;
|
||||||
|
zeus::CVector3f x1c_center;
|
||||||
CPFAreaOctree* x28_children[8];
|
CPFAreaOctree* x28_children[8];
|
||||||
u32 x48_regionCount;
|
rstl::prereserved_vector<CPFRegion*> x48_regions;
|
||||||
CPFRegion** x4c_regions;
|
|
||||||
public:
|
public:
|
||||||
CPFAreaOctree(CMemoryInStream& in);
|
CPFAreaOctree(CMemoryInStream& in);
|
||||||
void Fixup(CPFArea& area);
|
void Fixup(CPFArea& area);
|
||||||
void GetChildIndex(const zeus::CVector3f&) const;
|
int GetChildIndex(const zeus::CVector3f& point) const;
|
||||||
void GetRegionList(const zeus::CVector3f&) const;
|
void GetRegionList(const zeus::CVector3f&) const;
|
||||||
//void GetRegionListList(rstl::reserved_vector<rstl::prereserved_vector<CPFRegion>, 32>, const zeus::CVector3f&, float);
|
void GetRegionListList(rstl::reserved_vector<rstl::prereserved_vector<CPFRegion*>*, 32>, const zeus::CVector3f&, float);
|
||||||
bool IsPointInPaddedAABox(const zeus::CVector3f&, float);
|
bool IsPointInPaddedAABox(const zeus::CVector3f&, float);
|
||||||
void Render();
|
void Render();
|
||||||
};
|
};
|
||||||
|
@ -102,13 +102,16 @@ class CPFArea
|
||||||
CPFOpenList x78_;
|
CPFOpenList x78_;
|
||||||
u32 x138_;
|
u32 x138_;
|
||||||
//std::unique_ptr<u8[]> x13c_data;
|
//std::unique_ptr<u8[]> x13c_data;
|
||||||
|
/* Used to be prereserved_vectors backed by x13c_data
|
||||||
|
* This has been changed to meet storage requirements of
|
||||||
|
* modern systems */
|
||||||
std::vector<CPFNode> x140_nodes; // x140: count, x144: ptr
|
std::vector<CPFNode> x140_nodes; // x140: count, x144: ptr
|
||||||
std::vector<CPFLink> x148_links; // x148: count, x14c: ptr
|
std::vector<CPFLink> x148_links; // x148: count, x14c: ptr
|
||||||
std::vector<CPFRegion> x150_regions; // x150: count, x154: ptr
|
std::vector<CPFRegion> x150_regions; // x150: count, x154: ptr
|
||||||
std::vector<CPFAreaOctree> x158_octree; // x158: count, x15c: ptr
|
std::vector<CPFAreaOctree> x158_octree; // x158: count, x15c: ptr
|
||||||
std::vector<CPFRegion*> x160_octreeRegionLookup; // x160: count, x164: ptr
|
std::vector<CPFRegion*> x160_octreeRegionLookup; // x160: count, x164: ptr
|
||||||
std::vector<u32> x168_connectionsA; // x168: word_count, x16c: ptr
|
std::vector<u32> x168_connectionsGround; // x168: word_count, x16c: ptr
|
||||||
std::vector<u32> x170_connectionsB; // x170: word_count, x174: ptr
|
std::vector<u32> x170_connectionsFlyers; // x170: word_count, x174: ptr
|
||||||
std::vector<CPFRegionData> x178_regionDatas;
|
std::vector<CPFRegionData> x178_regionDatas;
|
||||||
zeus::CTransform x188_transform;
|
zeus::CTransform x188_transform;
|
||||||
public:
|
public:
|
||||||
|
@ -129,6 +132,7 @@ public:
|
||||||
void FindRegions(rstl::reserved_vector<CPFRegion, 4>&, const zeus::CVector3f&, u32);
|
void FindRegions(rstl::reserved_vector<CPFRegion, 4>&, const zeus::CVector3f&, u32);
|
||||||
void FindClosestRegion(const zeus::CVector3f&, u32, float);
|
void FindClosestRegion(const zeus::CVector3f&, u32, float);
|
||||||
void FindClosestReachablePoint(rstl::reserved_vector<CPFRegion, 4>&, const zeus::CVector3f&, u32);
|
void FindClosestReachablePoint(rstl::reserved_vector<CPFRegion, 4>&, const zeus::CVector3f&, u32);
|
||||||
|
bool PathExists(const CPFRegion* r1, const CPFRegion* r2, u32 flags) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ CPFNode::CPFNode(CMemoryInStream& in)
|
||||||
|
|
||||||
CPFLink::CPFLink(CMemoryInStream& in)
|
CPFLink::CPFLink(CMemoryInStream& in)
|
||||||
{
|
{
|
||||||
x0_region = in.readUint32Big();
|
x0_node = in.readUint32Big();
|
||||||
x4_node = in.readUint32Big();
|
x4_region = in.readUint32Big();
|
||||||
x8_2dWidth = in.readFloatBig();
|
x8_2dWidth = in.readFloatBig();
|
||||||
xc_oo2dWidth = in.readFloatBig();
|
xc_oo2dWidth = in.readFloatBig();
|
||||||
}
|
}
|
||||||
|
@ -48,4 +48,69 @@ void CPFRegion::Fixup(CPFArea& area, u32& maxRegionNodes)
|
||||||
maxRegionNodes = x0_numNodes;
|
maxRegionNodes = x0_numNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CPFRegion::FitThroughLink2d(const zeus::CVector3f& p1, const CPFLink& link,
|
||||||
|
const zeus::CVector3f& p2, float f1) const
|
||||||
|
{
|
||||||
|
CPFNode& node = x4_startNode[link.GetNode()];
|
||||||
|
CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes];
|
||||||
|
zeus::CVector3f nodeDelta = nextNode.GetPos() - node.GetPos();
|
||||||
|
float t = 0.5f;
|
||||||
|
if (f1 < 0.5f * link.Get2dWidth())
|
||||||
|
{
|
||||||
|
zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y);
|
||||||
|
delta2d *= link.GetOO2dWidth();
|
||||||
|
zeus::CVector3f nodeToP1 = p1 - node.GetPos();
|
||||||
|
float f27 = nodeToP1.dot(node.GetNormal());
|
||||||
|
float f31 = delta2d.dot(zeus::CVector2f(nodeToP1.y, nodeToP1.y));
|
||||||
|
zeus::CVector3f nodeToP2 = p2 - node.GetPos();
|
||||||
|
float f26 = -nodeToP2.dot(node.GetNormal());
|
||||||
|
float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y));
|
||||||
|
float f3 = f27 + f26;
|
||||||
|
if (f3 > FLT_EPSILON)
|
||||||
|
t = zeus::clamp(f1, 1.f / f3 * (f26 * f31 + f27 * f1b), link.Get2dWidth() - f1) * link.GetOO2dWidth();
|
||||||
|
}
|
||||||
|
return nodeDelta * t + node.GetPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPFLink& link,
|
||||||
|
float f1, const zeus::CVector3f& p2, float f2, float f3) const
|
||||||
|
{
|
||||||
|
CPFNode& node = x4_startNode[link.GetNode()];
|
||||||
|
CPFNode& nextNode = x4_startNode[(link.GetNode() + 1) % x0_numNodes];
|
||||||
|
zeus::CVector3f nodeDelta = nextNode.GetPos() - node.GetPos();
|
||||||
|
float f25 = (p1 - node.GetPos()).dot(node.GetNormal());
|
||||||
|
float f24 = (node.GetPos() - p2).dot(node.GetNormal());
|
||||||
|
float f23 = f25 + f24;
|
||||||
|
# if 0
|
||||||
|
if (f2 < 0.5f * link.Get2dWidth())
|
||||||
|
{
|
||||||
|
zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y);
|
||||||
|
delta2d *= link.GetOO2dWidth();
|
||||||
|
zeus::CVector3f nodeToP1 = p1 - node.GetPos();
|
||||||
|
float f29 = delta2d.dot(zeus::CVector2f(nodeToP1.y, nodeToP1.y));
|
||||||
|
zeus::CVector3f nodeToP2 = p2 - node.GetPos();
|
||||||
|
float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y));
|
||||||
|
if (f23 > FLT_EPSILON)
|
||||||
|
{
|
||||||
|
zeus::clamp(f2, 1.f / f23 * f24 * f29 + f25 * f1b, link.Get2dWidth() - f2) * link.GetOO2dWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
zeus::CVector3f midPoint = nodeDelta * 0.5f + node.GetPos();
|
||||||
|
float z;
|
||||||
|
if (f3 < 0.5f * f1)
|
||||||
|
{
|
||||||
|
float minZ = f3 + midPoint.z;
|
||||||
|
z = 0.5f * (p1.z + p2.z);
|
||||||
|
if (f23 > FLT_EPSILON)
|
||||||
|
z = 1.f / f23 * (f24 * p1.z + f25 * p2.z);
|
||||||
|
z = zeus::clamp(minZ, z, f1 + midPoint.z - f3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z = (p1.z + p2.z) * 0.5f;
|
||||||
|
}
|
||||||
|
return {midPoint.x, midPoint.y, z};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,14 @@ public:
|
||||||
|
|
||||||
class CPFLink
|
class CPFLink
|
||||||
{
|
{
|
||||||
u32 x0_region;
|
u32 x0_node;
|
||||||
u32 x4_node;
|
u32 x4_region;
|
||||||
float x8_2dWidth;
|
float x8_2dWidth;
|
||||||
float xc_oo2dWidth;
|
float xc_oo2dWidth;
|
||||||
public:
|
public:
|
||||||
CPFLink(CMemoryInStream& in);
|
CPFLink(CMemoryInStream& in);
|
||||||
u32 GetRegion() const { return x0_region; }
|
u32 GetNode() const { return x0_node; }
|
||||||
u32 GetNode() const { return x4_node; }
|
u32 GetRegion() const { return x4_region; }
|
||||||
float Get2dWidth() const { return x8_2dWidth; }
|
float Get2dWidth() const { return x8_2dWidth; }
|
||||||
float GetOO2dWidth() const { return xc_oo2dWidth; }
|
float GetOO2dWidth() const { return xc_oo2dWidth; }
|
||||||
};
|
};
|
||||||
|
@ -52,7 +52,7 @@ public:
|
||||||
CPFRegion(CMemoryInStream& in);
|
CPFRegion(CMemoryInStream& in);
|
||||||
void SetData(CPFRegionData* data) { x4c_regionData = data; }
|
void SetData(CPFRegionData* data) { x4c_regionData = data; }
|
||||||
CPFRegionData* Data() const { return x4c_regionData; }
|
CPFRegionData* Data() const { return x4c_regionData; }
|
||||||
void GetIndex() const;
|
u32 GetIndex() const { return x24_regionIdx; }
|
||||||
float GetHeight() const { return x14_height; }
|
float GetHeight() const { return x14_height; }
|
||||||
void GetPathLink() const {}
|
void GetPathLink() const {}
|
||||||
u32 GetNumLinks() const { return x8_numLinks; }
|
u32 GetNumLinks() const { return x8_numLinks; }
|
||||||
|
@ -72,8 +72,8 @@ public:
|
||||||
void SetLinkTo(s32);
|
void SetLinkTo(s32);
|
||||||
void DropToGround(zeus::CVector3f&) const;
|
void DropToGround(zeus::CVector3f&) const;
|
||||||
void GetLinkMidPoint(const CPFLink&);
|
void GetLinkMidPoint(const CPFLink&);
|
||||||
void FitThroughLink2d(const zeus::CVector3f&, const CPFLink&, const zeus::CVector3f&, float) const;
|
zeus::CVector3f FitThroughLink2d(const zeus::CVector3f&, const CPFLink&, const zeus::CVector3f&, float) const;
|
||||||
void FitThroughLink3d(const zeus::CVector3f&, const CPFLink&, float, const zeus::CVector3f&, float, float) const;
|
zeus::CVector3f FitThroughLink3d(const zeus::CVector3f&, const CPFLink&, float, const zeus::CVector3f&, float, float) const;
|
||||||
void IsPointInsidePaddedAABox(const zeus::CVector3f&, float) const;
|
void IsPointInsidePaddedAABox(const zeus::CVector3f&, float) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,12 +81,12 @@ class CPFRegionData
|
||||||
{
|
{
|
||||||
float x0_ = 0.f;
|
float x0_ = 0.f;
|
||||||
zeus::CVector3f x4_;
|
zeus::CVector3f x4_;
|
||||||
s32 x10_ = -1;
|
s32 x10_cookie = -1;
|
||||||
zeus::CVector3f x14_;
|
zeus::CVector3f x14_;
|
||||||
s32 x20_ = 0;
|
s32 x20_ = 0;
|
||||||
CPFRegion* x24_openLess = nullptr;
|
CPFRegion* x24_openLess = nullptr;
|
||||||
CPFRegion* x28_openMore = nullptr;
|
CPFRegion* x28_openMore = nullptr;
|
||||||
s32 x2c_ = 0;
|
s32 x2c_pathLink = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPFRegionData() = default;
|
CPFRegionData() = default;
|
||||||
|
@ -95,16 +95,16 @@ public:
|
||||||
CPFRegion* GetOpenLess() const { return x24_openLess; }
|
CPFRegion* GetOpenLess() const { return x24_openLess; }
|
||||||
CPFRegion* GetOpenMore() const { return x28_openMore; }
|
CPFRegion* GetOpenMore() const { return x28_openMore; }
|
||||||
void GetCost();
|
void GetCost();
|
||||||
void GetPathLink() const;
|
s32 GetPathLink() const { return x2c_pathLink; }
|
||||||
|
void SetPathLink(s32 l) { x2c_pathLink = l; }
|
||||||
void GetParent() const;
|
void GetParent() const;
|
||||||
void Setup(CPFRegion*, float, float);
|
void Setup(CPFRegion*, float, float);
|
||||||
void SetBestPoint(const zeus::CVector3f&);
|
void SetBestPoint(const zeus::CVector3f&);
|
||||||
void SetBestPointDistanceSquared(float);
|
void SetBestPointDistanceSquared(float);
|
||||||
float GetBestPointDistanceSquared() const;
|
float GetBestPointDistanceSquared() const;
|
||||||
void SetPathLink(s32);
|
|
||||||
void SetCookie(s32);
|
|
||||||
zeus::CVector3f GetBestPoint() const;
|
zeus::CVector3f GetBestPoint() const;
|
||||||
void GetCookie() const;
|
void SetCookie(s32 c) { x10_cookie = c; }
|
||||||
|
s32 GetCookie() const { return x10_cookie; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,17 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CPathFindSearch::CPathFindSearch(CPFArea* area, u32 w1, u32 w2, float f1, float f2)
|
CPathFindSearch::CPathFindSearch(CPFArea* area, u32 flags, u32 w2, float f1, float f2)
|
||||||
: x0_area(area), xd0_f2(f2), xd4_f1(f1), xdc_w1(w1), xe0_w2(1u << w2)
|
: x0_area(area), xd0_f2(f2), xd4_f1(f1), xdc_flags(flags), xe0_w2(1u << w2)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPathFindSearch::Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2)
|
||||||
|
{
|
||||||
|
x4_.clear();
|
||||||
|
xc8_ = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,16 @@ namespace urde
|
||||||
class CPathFindSearch
|
class CPathFindSearch
|
||||||
{
|
{
|
||||||
CPFArea* x0_area;
|
CPFArea* x0_area;
|
||||||
u32 x4_ = 0;
|
rstl::reserved_vector<zeus::CVector3f, 16> x4_;
|
||||||
u32 xc8_ = 0;
|
u32 xc8_ = 0;
|
||||||
float xd0_f2;
|
float xd0_f2;
|
||||||
float xd4_f1;
|
float xd4_f1;
|
||||||
float xd8_ = 10.f;
|
float xd8_ = 10.f;
|
||||||
u32 xdc_w1;
|
u32 xdc_flags; // 0x2: flyer, 0x4: path-always-exists
|
||||||
u32 xe0_w2;
|
u32 xe0_w2;
|
||||||
public:
|
public:
|
||||||
CPathFindSearch(CPFArea* area, u32 w1, u32 w2, float f1, float f2);
|
CPathFindSearch(CPFArea* area, u32 flags, u32 w2, float f1, float f2);
|
||||||
|
void Search(const zeus::CVector3f& p1, const zeus::CVector3f& p2);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ void CScriptActorRotate::UpdateActors(bool next, CStateManager& mgr)
|
||||||
|
|
||||||
void CScriptActorRotate::UpdateSpiderBallWaypoints(CStateManager& mgr)
|
void CScriptActorRotate::UpdateSpiderBallWaypoints(CStateManager& mgr)
|
||||||
{
|
{
|
||||||
rstl::prereserved_vector<TUniqueId, 1024> waypointIds;
|
rstl::reserved_vector<TUniqueId, 1024> waypointIds;
|
||||||
CObjectList& objectList = mgr.GetAllObjectList();
|
CObjectList& objectList = mgr.GetAllObjectList();
|
||||||
for (CEntity* ent : objectList)
|
for (CEntity* ent : objectList)
|
||||||
{
|
{
|
||||||
|
|
737
Runtime/rstl.hpp
737
Runtime/rstl.hpp
|
@ -21,37 +21,17 @@ using optional_object = std::experimental::optional<T>;
|
||||||
/**
|
/**
|
||||||
* @brief Base vector backed by statically-allocated array
|
* @brief Base vector backed by statically-allocated array
|
||||||
*/
|
*/
|
||||||
template <class T, size_t N>
|
template <class T>
|
||||||
class _reserved_vector_base
|
class _reserved_vector_base
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
union alignas(T) storage_t
|
|
||||||
{
|
|
||||||
struct {} _dummy;
|
|
||||||
T _value;
|
|
||||||
storage_t() : _dummy() {}
|
|
||||||
~storage_t() {}
|
|
||||||
};
|
|
||||||
explicit _reserved_vector_base(size_t _init_sz) : x0_size(_init_sz) {}
|
|
||||||
size_t x0_size;
|
|
||||||
storage_t x4_data[N];
|
|
||||||
T& _value(std::ptrdiff_t idx) { return x4_data[idx]._value; }
|
|
||||||
const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; }
|
|
||||||
template <typename Tp>
|
|
||||||
static void destroy(Tp& t, std::enable_if_t<std::is_destructible<Tp>::value &&
|
|
||||||
!std::is_trivially_destructible<Tp>::value>* = 0) { t.Tp::~Tp(); }
|
|
||||||
template <typename Tp>
|
|
||||||
static void destroy(Tp& t, std::enable_if_t<!std::is_destructible<Tp>::value ||
|
|
||||||
std::is_trivially_destructible<Tp>::value>* = 0) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class const_iterator
|
class const_iterator
|
||||||
{
|
{
|
||||||
friend class _reserved_vector_base;
|
friend class _reserved_vector_base;
|
||||||
protected:
|
protected:
|
||||||
const T* m_val;
|
const T* m_val;
|
||||||
explicit const_iterator(const T* val) : m_val(val) {}
|
|
||||||
public:
|
public:
|
||||||
|
explicit const_iterator(const T* val) : m_val(val) {}
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using pointer = T*;
|
using pointer = T*;
|
||||||
|
@ -81,8 +61,8 @@ public:
|
||||||
class iterator : public const_iterator
|
class iterator : public const_iterator
|
||||||
{
|
{
|
||||||
friend class _reserved_vector_base;
|
friend class _reserved_vector_base;
|
||||||
explicit iterator(T* val) : const_iterator(val) {}
|
|
||||||
public:
|
public:
|
||||||
|
explicit iterator(T* val) : const_iterator(val) {}
|
||||||
T& operator*() const { return *const_cast<T*>(const_iterator::m_val); }
|
T& operator*() const { return *const_cast<T*>(const_iterator::m_val); }
|
||||||
T* operator->() const { return const_cast<T*>(const_iterator::m_val); }
|
T* operator->() const { return const_cast<T*>(const_iterator::m_val); }
|
||||||
iterator& operator++() { ++const_iterator::m_val; return *this; }
|
iterator& operator++() { ++const_iterator::m_val; return *this; }
|
||||||
|
@ -102,8 +82,8 @@ public:
|
||||||
friend class _reserved_vector_base;
|
friend class _reserved_vector_base;
|
||||||
protected:
|
protected:
|
||||||
const T* m_val;
|
const T* m_val;
|
||||||
explicit const_reverse_iterator(const T* val) : m_val(val) {}
|
|
||||||
public:
|
public:
|
||||||
|
explicit const_reverse_iterator(const T* val) : m_val(val) {}
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using pointer = T*;
|
using pointer = T*;
|
||||||
|
@ -133,8 +113,8 @@ public:
|
||||||
class reverse_iterator : public const_reverse_iterator
|
class reverse_iterator : public const_reverse_iterator
|
||||||
{
|
{
|
||||||
friend class _reserved_vector_base;
|
friend class _reserved_vector_base;
|
||||||
explicit reverse_iterator(T* val) : const_reverse_iterator(val) {}
|
|
||||||
public:
|
public:
|
||||||
|
explicit reverse_iterator(T* val) : const_reverse_iterator(val) {}
|
||||||
T& operator*() const { return *const_cast<T*>(const_reverse_iterator::m_val); }
|
T& operator*() const { return *const_cast<T*>(const_reverse_iterator::m_val); }
|
||||||
T* operator->() const { return const_cast<T*>(const_reverse_iterator::m_val); }
|
T* operator->() const { return const_cast<T*>(const_reverse_iterator::m_val); }
|
||||||
reverse_iterator& operator++() { --const_reverse_iterator::m_val; return *this; }
|
reverse_iterator& operator++() { --const_reverse_iterator::m_val; return *this; }
|
||||||
|
@ -151,6 +131,265 @@ public:
|
||||||
T& operator[](std::ptrdiff_t i) const { return const_cast<T*>(const_reverse_iterator::m_val)[-i]; }
|
T& operator[](std::ptrdiff_t i) const { return const_cast<T*>(const_reverse_iterator::m_val)[-i]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static iterator _const_cast_iterator(const const_iterator& it) { return iterator(const_cast<T*>(it.m_val)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vector backed by statically-allocated array with uninitialized storage
|
||||||
|
*/
|
||||||
|
template <class T, size_t N>
|
||||||
|
class reserved_vector : public _reserved_vector_base<T>
|
||||||
|
{
|
||||||
|
union alignas(T) storage_t
|
||||||
|
{
|
||||||
|
struct {} _dummy;
|
||||||
|
T _value;
|
||||||
|
storage_t() : _dummy() {}
|
||||||
|
~storage_t() {}
|
||||||
|
};
|
||||||
|
size_t x0_size;
|
||||||
|
storage_t x4_data[N];
|
||||||
|
T& _value(std::ptrdiff_t idx) { return x4_data[idx]._value; }
|
||||||
|
const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; }
|
||||||
|
template <typename Tp>
|
||||||
|
static void destroy(Tp& t, std::enable_if_t<std::is_destructible<Tp>::value &&
|
||||||
|
!std::is_trivially_destructible<Tp>::value>* = 0) { t.Tp::~Tp(); }
|
||||||
|
template <typename Tp>
|
||||||
|
static void destroy(Tp& t, std::enable_if_t<!std::is_destructible<Tp>::value ||
|
||||||
|
std::is_trivially_destructible<Tp>::value>* = 0) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
using base = _reserved_vector_base<T>;
|
||||||
|
using iterator = typename base::iterator;
|
||||||
|
using const_iterator = typename base::const_iterator;
|
||||||
|
using reverse_iterator = typename base::reverse_iterator;
|
||||||
|
using const_reverse_iterator = typename base::const_reverse_iterator;
|
||||||
|
reserved_vector() : x0_size(0) {}
|
||||||
|
|
||||||
|
reserved_vector(const reserved_vector& other) : x0_size(other.x0_size)
|
||||||
|
{
|
||||||
|
for (size_t i=0 ; i<x0_size ; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
reserved_vector& operator=(const reserved_vector& other)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
if (other.x0_size > x0_size)
|
||||||
|
{
|
||||||
|
for (; i<x0_size ; ++i)
|
||||||
|
_value(i) = other._value(i);
|
||||||
|
for (; i<other.x0_size ; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(i)))) T(other._value(i));
|
||||||
|
}
|
||||||
|
else if (other.x0_size < x0_size)
|
||||||
|
{
|
||||||
|
for (; i<other.x0_size ; ++i)
|
||||||
|
_value(i) = other._value(i);
|
||||||
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
for (; i<x0_size ; ++i)
|
||||||
|
destroy(_value(i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; i<other.x0_size ; ++i)
|
||||||
|
_value(i) = other._value(i);
|
||||||
|
}
|
||||||
|
x0_size = other.x0_size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
reserved_vector(reserved_vector&& other) : x0_size(other.x0_size)
|
||||||
|
{
|
||||||
|
for (size_t i=0 ; i<x0_size ; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(i)))) T(std::forward<T>(other._value(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
reserved_vector& operator=(reserved_vector&& other)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
if (other.x0_size > x0_size)
|
||||||
|
{
|
||||||
|
for (; i<x0_size ; ++i)
|
||||||
|
_value(i) = std::forward<T>(other._value(i));
|
||||||
|
for (; i<other.x0_size ; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(i)))) T(std::forward<T>(other._value(i)));
|
||||||
|
}
|
||||||
|
else if (other.x0_size < x0_size)
|
||||||
|
{
|
||||||
|
for (; i<other.x0_size ; ++i)
|
||||||
|
_value(i) = std::forward<T>(other._value(i));
|
||||||
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
for (; i<x0_size ; ++i)
|
||||||
|
destroy(_value(i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; i<other.x0_size ; ++i)
|
||||||
|
_value(i) = std::forward<T>(other._value(i));
|
||||||
|
}
|
||||||
|
x0_size = other.x0_size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~reserved_vector()
|
||||||
|
{
|
||||||
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
for (size_t i=0 ; i<x0_size ; ++i)
|
||||||
|
destroy(_value(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const T& d)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == N)
|
||||||
|
Log.report(logvisor::Fatal, "push_back() called on full rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(d);
|
||||||
|
++x0_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(T&& d)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == N)
|
||||||
|
Log.report(logvisor::Fatal, "push_back() called on full rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(d));
|
||||||
|
++x0_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... _Args>
|
||||||
|
void emplace_back(_Args&&... args)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == N)
|
||||||
|
Log.report(logvisor::Fatal, "emplace_back() called on full rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<_Args>(args)...);
|
||||||
|
++x0_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_back()
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == 0)
|
||||||
|
Log.report(logvisor::Fatal, "pop_back() called on empty rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
--x0_size;
|
||||||
|
destroy(_value(x0_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator insert(const_iterator pos, const T& value)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == N)
|
||||||
|
Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
auto target_it = base::_const_cast_iterator(pos);
|
||||||
|
if (pos == cend())
|
||||||
|
{
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size))))
|
||||||
|
T(std::forward<T>(_value(x0_size - 1)));
|
||||||
|
for (auto it = end() - 1; it != target_it; --it)
|
||||||
|
*it = std::forward<T>(*(it - 1));
|
||||||
|
*target_it = value;
|
||||||
|
}
|
||||||
|
++x0_size;
|
||||||
|
return target_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator insert(const_iterator pos, T&& value)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == N)
|
||||||
|
Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
auto target_it = base::_const_cast_iterator(pos);
|
||||||
|
if (pos == cend())
|
||||||
|
{
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size)))) T(std::forward<T>(value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(x0_size))))
|
||||||
|
T(std::forward<T>(_value(x0_size - 1)));
|
||||||
|
for (auto it = end() - 1; it != target_it; --it)
|
||||||
|
*it = std::forward<T>(*(it - 1));
|
||||||
|
*target_it = std::forward<T>(value);
|
||||||
|
}
|
||||||
|
++x0_size;
|
||||||
|
return target_it;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(size_t size)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (size > N)
|
||||||
|
Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
if (size > x0_size)
|
||||||
|
{
|
||||||
|
for (size_t i = x0_size; i < size; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(i)))) T();
|
||||||
|
x0_size = size;
|
||||||
|
}
|
||||||
|
else if (size < x0_size)
|
||||||
|
{
|
||||||
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
for (size_t i = size; i < x0_size; ++i)
|
||||||
|
destroy(_value(i));
|
||||||
|
x0_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(size_t size, const T& value)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (size > N)
|
||||||
|
Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
if (size > x0_size)
|
||||||
|
{
|
||||||
|
for (size_t i = x0_size; i < size; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(_value(i)))) T(value);
|
||||||
|
x0_size = size;
|
||||||
|
}
|
||||||
|
else if (size < x0_size)
|
||||||
|
{
|
||||||
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
for (size_t i = size; i < x0_size; ++i)
|
||||||
|
destroy(_value(i));
|
||||||
|
x0_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator erase(const_iterator pos)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (x0_size == 0)
|
||||||
|
Log.report(logvisor::Fatal, "erase() called on empty rstl::reserved_vector.");
|
||||||
|
#endif
|
||||||
|
for (auto it = base::_const_cast_iterator(pos) + 1; it != end(); ++it)
|
||||||
|
*(it - 1) = std::forward<T>(*it);
|
||||||
|
--x0_size;
|
||||||
|
destroy(_value(x0_size));
|
||||||
|
return base::_const_cast_iterator(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
for (auto it = begin(); it != end(); ++it)
|
||||||
|
destroy(*it);
|
||||||
|
x0_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t size() const noexcept { return x0_size; }
|
size_t size() const noexcept { return x0_size; }
|
||||||
bool empty() const noexcept { return x0_size == 0; }
|
bool empty() const noexcept { return x0_size == 0; }
|
||||||
constexpr size_t capacity() const noexcept { return N; }
|
constexpr size_t capacity() const noexcept { return N; }
|
||||||
|
@ -179,430 +418,58 @@ public:
|
||||||
|
|
||||||
T& operator[](size_t idx) { return _value(idx); }
|
T& operator[](size_t idx) { return _value(idx); }
|
||||||
const T& operator[](size_t idx) const { return _value(idx); }
|
const T& operator[](size_t idx) const { return _value(idx); }
|
||||||
|
|
||||||
protected:
|
|
||||||
static iterator _const_cast_iterator(const const_iterator& it) { return iterator(const_cast<T*>(it.m_val)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Vector backed by statically-allocated array with uninitialized storage
|
* @brief Vector-style view backed by externally-allocated storage
|
||||||
*/
|
*/
|
||||||
template <class T, size_t N>
|
template <class T>
|
||||||
class reserved_vector : public _reserved_vector_base<T, N>
|
class prereserved_vector : public _reserved_vector_base<T>
|
||||||
{
|
{
|
||||||
|
size_t x0_size;
|
||||||
|
T* x4_data;
|
||||||
|
T& _value(std::ptrdiff_t idx) { return x4_data[idx]; }
|
||||||
|
const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using base = _reserved_vector_base<T, N>;
|
using base = _reserved_vector_base<T>;
|
||||||
using iterator = typename base::iterator;
|
using iterator = typename base::iterator;
|
||||||
using const_iterator = typename base::const_iterator;
|
using const_iterator = typename base::const_iterator;
|
||||||
reserved_vector() : base(0) {}
|
using reverse_iterator = typename base::reverse_iterator;
|
||||||
|
using const_reverse_iterator = typename base::const_reverse_iterator;
|
||||||
|
prereserved_vector() : x0_size(0), x4_data(nullptr) {}
|
||||||
|
prereserved_vector(size_t size, T* data) : x0_size(size), x4_data(data) {}
|
||||||
|
|
||||||
reserved_vector(const reserved_vector& other) : base(other.x0_size)
|
void set_size(size_t n) { x0_size = n; }
|
||||||
{
|
void set_data(T* data) { x4_data = data; }
|
||||||
for (size_t i=0 ; i<base::x0_size ; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(other.base::_value(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
reserved_vector& operator=(const reserved_vector& other)
|
size_t size() const noexcept { return x0_size; }
|
||||||
{
|
bool empty() const noexcept { return x0_size == 0; }
|
||||||
size_t i = 0;
|
const T* data() const noexcept { return x4_data; }
|
||||||
if (other.base::x0_size > base::x0_size)
|
T* data() noexcept { return x4_data; }
|
||||||
{
|
|
||||||
for (; i<base::x0_size ; ++i)
|
|
||||||
base::_value(i) = other.base::_value(i);
|
|
||||||
for (; i<other.base::x0_size ; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(other.base::_value(i));
|
|
||||||
}
|
|
||||||
else if (other.base::x0_size < base::x0_size)
|
|
||||||
{
|
|
||||||
for (; i<other.base::x0_size ; ++i)
|
|
||||||
base::_value(i) = other.base::_value(i);
|
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
|
||||||
for (; i<base::x0_size ; ++i)
|
|
||||||
base::destroy(base::_value(i));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (; i<other.base::x0_size ; ++i)
|
|
||||||
base::_value(i) = other.base::_value(i);
|
|
||||||
}
|
|
||||||
base::x0_size = other.base::x0_size;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
reserved_vector(reserved_vector&& other) : base(other.x0_size)
|
T& back() { return _value(x0_size - 1); }
|
||||||
{
|
T& front() { return _value(0); }
|
||||||
for (size_t i=0 ; i<base::x0_size ; ++i)
|
const T& back() const { return _value(x0_size - 1); }
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(std::forward<T>(other.base::_value(i)));
|
const T& front() const { return _value(0); }
|
||||||
}
|
|
||||||
|
|
||||||
reserved_vector& operator=(reserved_vector&& other)
|
const_iterator begin() const noexcept { return const_iterator(std::addressof(_value(0))); }
|
||||||
{
|
const_iterator end() const noexcept { return const_iterator(std::addressof(_value(x0_size))); }
|
||||||
size_t i = 0;
|
iterator begin() noexcept { return iterator(std::addressof(_value(0))); }
|
||||||
if (other.base::x0_size > base::x0_size)
|
iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); }
|
||||||
{
|
const_iterator cbegin() const noexcept { return begin(); }
|
||||||
for (; i<base::x0_size ; ++i)
|
const_iterator cend() const noexcept { return end(); }
|
||||||
base::_value(i) = std::forward<T>(other.base::_value(i));
|
|
||||||
for (; i<other.base::x0_size ; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(std::forward<T>(other.base::_value(i)));
|
|
||||||
}
|
|
||||||
else if (other.base::x0_size < base::x0_size)
|
|
||||||
{
|
|
||||||
for (; i<other.base::x0_size ; ++i)
|
|
||||||
base::_value(i) = std::forward<T>(other.base::_value(i));
|
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
|
||||||
for (; i<base::x0_size ; ++i)
|
|
||||||
base::destroy(base::_value(i));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (; i<other.base::x0_size ; ++i)
|
|
||||||
base::_value(i) = std::forward<T>(other.base::_value(i));
|
|
||||||
}
|
|
||||||
base::x0_size = other.base::x0_size;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~reserved_vector()
|
const_reverse_iterator rbegin() const noexcept
|
||||||
{
|
{ return const_reverse_iterator(std::addressof(_value(x0_size - 1))); }
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
const_reverse_iterator rend() const noexcept { return const_reverse_iterator(std::addressof(_value(-1))); }
|
||||||
for (size_t i=0 ; i<base::x0_size ; ++i)
|
reverse_iterator rbegin() noexcept { return reverse_iterator(std::addressof(_value(x0_size - 1))); }
|
||||||
base::destroy(base::_value(i));
|
reverse_iterator rend() noexcept { return reverse_iterator(std::addressof(_value(-1))); }
|
||||||
}
|
const_reverse_iterator crbegin() const noexcept { return rbegin(); }
|
||||||
|
const_reverse_iterator crend() const noexcept { return rend(); }
|
||||||
|
|
||||||
void push_back(const T& d)
|
T& operator[](size_t idx) { return _value(idx); }
|
||||||
{
|
const T& operator[](size_t idx) const { return _value(idx); }
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "push_back() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size)))) T(d);
|
|
||||||
++base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(T&& d)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "push_back() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size)))) T(std::forward<T>(d));
|
|
||||||
++base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class... _Args>
|
|
||||||
void emplace_back(_Args&&... args)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "emplace_back() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size)))) T(std::forward<_Args>(args)...);
|
|
||||||
++base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back()
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == 0)
|
|
||||||
Log.report(logvisor::Fatal, "pop_back() called on empty rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
--base::x0_size;
|
|
||||||
base::destroy(base::_value(base::x0_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator insert(const_iterator pos, const T& value)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
auto target_it = base::_const_cast_iterator(pos);
|
|
||||||
if (pos == base::cend())
|
|
||||||
{
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size)))) T(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size))))
|
|
||||||
T(std::forward<T>(base::_value(base::x0_size - 1)));
|
|
||||||
for (auto it = base::end() - 1; it != target_it; --it)
|
|
||||||
*it = std::forward<T>(*(it - 1));
|
|
||||||
*target_it = value;
|
|
||||||
}
|
|
||||||
++base::x0_size;
|
|
||||||
return target_it;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator insert(const_iterator pos, T&& value)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
auto target_it = base::_const_cast_iterator(pos);
|
|
||||||
if (pos == base::cend())
|
|
||||||
{
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size)))) T(std::forward<T>(value));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(base::x0_size))))
|
|
||||||
T(std::forward<T>(base::_value(base::x0_size - 1)));
|
|
||||||
for (auto it = base::end() - 1; it != target_it; --it)
|
|
||||||
*it = std::forward<T>(*(it - 1));
|
|
||||||
*target_it = std::forward<T>(value);
|
|
||||||
}
|
|
||||||
++base::x0_size;
|
|
||||||
return target_it;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(size_t size)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (size > N)
|
|
||||||
Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
if (size > base::x0_size)
|
|
||||||
{
|
|
||||||
for (size_t i = base::x0_size; i < size; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T();
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
else if (size < base::x0_size)
|
|
||||||
{
|
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
|
||||||
for (size_t i = size; i < base::x0_size; ++i)
|
|
||||||
base::destroy(base::_value(i));
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(size_t size, const T& value)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (size > N)
|
|
||||||
Log.report(logvisor::Fatal, "resized() call overflows rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
if (size > base::x0_size)
|
|
||||||
{
|
|
||||||
for (size_t i = base::x0_size; i < size; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(value);
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
else if (size < base::x0_size)
|
|
||||||
{
|
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
|
||||||
for (size_t i = size; i < base::x0_size; ++i)
|
|
||||||
base::destroy(base::_value(i));
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator erase(const_iterator pos)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == 0)
|
|
||||||
Log.report(logvisor::Fatal, "erase() called on empty rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
for (auto it = base::_const_cast_iterator(pos) + 1; it != base::end(); ++it)
|
|
||||||
*(it - 1) = std::forward<T>(*it);
|
|
||||||
--base::x0_size;
|
|
||||||
base::destroy(base::_value(base::x0_size));
|
|
||||||
return base::_const_cast_iterator(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
|
||||||
for (auto it = base::begin(); it != base::end(); ++it)
|
|
||||||
base::destroy(*it);
|
|
||||||
base::x0_size = 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Vector backed by statically-allocated array with default-initialized elements
|
|
||||||
*/
|
|
||||||
template <class T, size_t N>
|
|
||||||
class prereserved_vector : public _reserved_vector_base<T, N>
|
|
||||||
{
|
|
||||||
void _init()
|
|
||||||
{
|
|
||||||
for (auto& i : base::x4_data)
|
|
||||||
::new (static_cast<void*>(std::addressof(i._value))) T();
|
|
||||||
}
|
|
||||||
void _deinit()
|
|
||||||
{
|
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
|
||||||
for (auto& i : base::x4_data)
|
|
||||||
base::destroy(i._value);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
using base = _reserved_vector_base<T, N>;
|
|
||||||
using iterator = typename base::iterator;
|
|
||||||
using const_iterator = typename base::const_iterator;
|
|
||||||
prereserved_vector() : base(1) { _init(); }
|
|
||||||
|
|
||||||
prereserved_vector(const prereserved_vector& other) : base(other.x0_size)
|
|
||||||
{
|
|
||||||
for (size_t i=0 ; i<N ; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(other.base::_value(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
prereserved_vector& operator=(const prereserved_vector& other)
|
|
||||||
{
|
|
||||||
for (size_t i=0 ; i<N ; ++i)
|
|
||||||
base::_value(i) = other.base::_value(i);
|
|
||||||
base::x0_size = other.base::x0_size;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
prereserved_vector(prereserved_vector&& other) : base(other.x0_size)
|
|
||||||
{
|
|
||||||
for (size_t i=0 ; i<N ; ++i)
|
|
||||||
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(std::forward<T>(other.base::_value(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
prereserved_vector& operator=(prereserved_vector&& other)
|
|
||||||
{
|
|
||||||
for (size_t i=0 ; i<N ; ++i)
|
|
||||||
base::_value(i) = std::forward<T>(other.base::_value(i));
|
|
||||||
base::x0_size = other.base::x0_size;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~prereserved_vector() { _deinit(); }
|
|
||||||
|
|
||||||
void set_size(size_t n)
|
|
||||||
{
|
|
||||||
if (n <= N)
|
|
||||||
base::x0_size = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_data(const T* data) { memmove(base::x4_data, data, sizeof(T) * base::x0_size); }
|
|
||||||
|
|
||||||
void push_back(const T& d)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "push_back() called on full rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
base::_value(base::x0_size) = d;
|
|
||||||
++base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(T&& d)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "push_back() called on full rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
base::_value(base::x0_size) = std::forward<T>(d);
|
|
||||||
++base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class... _Args>
|
|
||||||
void emplace_back(_Args&&... args)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "emplace_back() called on full rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
base::_value(base::x0_size) = T(std::forward<_Args>(args)...);
|
|
||||||
++base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_back()
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == 0)
|
|
||||||
Log.report(logvisor::Fatal, "pop_back() called on empty rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
--base::x0_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator insert(const_iterator pos, const T& value)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
auto target_it = base::_const_cast_iterator(pos);
|
|
||||||
if (pos == base::cend())
|
|
||||||
{
|
|
||||||
*target_it = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto it = base::end(); it != target_it; --it)
|
|
||||||
*it = std::forward<T>(*(it - 1));
|
|
||||||
*target_it = value;
|
|
||||||
}
|
|
||||||
++base::x0_size;
|
|
||||||
return target_it;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator insert(const_iterator pos, T&& value)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == N)
|
|
||||||
Log.report(logvisor::Fatal, "insert() called on full rstl::reserved_vector.");
|
|
||||||
#endif
|
|
||||||
auto target_it = base::_const_cast_iterator(pos);
|
|
||||||
if (pos == base::cend())
|
|
||||||
{
|
|
||||||
*target_it = std::forward<T>(value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto it = base::end(); it != target_it; --it)
|
|
||||||
*it = std::forward<T>(*(it - 1));
|
|
||||||
*target_it = std::forward<T>(value);
|
|
||||||
}
|
|
||||||
++base::x0_size;
|
|
||||||
return target_it;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(size_t size)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (size > N)
|
|
||||||
Log.report(logvisor::Fatal, "resized() call overflows rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(size_t size, const T& value)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (size > N)
|
|
||||||
Log.report(logvisor::Fatal, "resized() call overflows rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
if (size > base::x0_size)
|
|
||||||
{
|
|
||||||
for (size_t i = base::x0_size; i < size; ++i)
|
|
||||||
base::_value(i) = T(value);
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
else if (size < base::x0_size)
|
|
||||||
{
|
|
||||||
base::x0_size = size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator erase(const_iterator pos)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (base::x0_size == 0)
|
|
||||||
Log.report(logvisor::Fatal, "erase() called on empty rstl::prereserved_vector.");
|
|
||||||
#endif
|
|
||||||
for (auto it = base::_const_cast_iterator(pos) + 1; it != base::end(); ++it)
|
|
||||||
*(it - 1) = std::forward<T>(*it);
|
|
||||||
--base::x0_size;
|
|
||||||
return base::_const_cast_iterator(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() { base::x0_size = 0; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class ForwardIt, class T>
|
template<class ForwardIt, class T>
|
||||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
||||||
Subproject commit f1d71e3e86f241ebd959b0a4e07f77913b34be63
|
Subproject commit 5c6e64c53f831b405e23dc2a105a16259dc5a076
|
Loading…
Reference in New Issue