mirror of https://github.com/AxioDL/metaforce.git
Implement array-based rstl::reserved_vector
This commit is contained in:
parent
10092821c8
commit
27cee61765
|
@ -86,7 +86,6 @@ CPlayerState::CPlayerState(CBitStreamReader& stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& scanStates = g_MemoryCardSys->GetScanStates();
|
const auto& scanStates = g_MemoryCardSys->GetScanStates();
|
||||||
x170_scanTimes.reserve(scanStates.size());
|
|
||||||
for (const auto& state : scanStates)
|
for (const auto& state : scanStates)
|
||||||
{
|
{
|
||||||
float time = stream.ReadEncoded(1) ? 1.f : 0.f;
|
float time = stream.ReadEncoded(1) ? 1.f : 0.f;
|
||||||
|
@ -438,7 +437,6 @@ void CPlayerState::InitializeScanTimes()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto& scanStates = g_MemoryCardSys->GetScanStates();
|
const auto& scanStates = g_MemoryCardSys->GetScanStates();
|
||||||
x170_scanTimes.reserve(scanStates.size());
|
|
||||||
for (const auto& state : scanStates)
|
for (const auto& state : scanStates)
|
||||||
x170_scanTimes.emplace_back(state.first, 0.f);
|
x170_scanTimes.emplace_back(state.first, 0.f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,14 @@ CPASAnimParm::UParmValue CPASAnimInfo::GetAnimParmValue(u32 idx) const
|
||||||
{
|
{
|
||||||
if (idx >= x4_parms.size())
|
if (idx >= x4_parms.size())
|
||||||
return CPASAnimParm::UParmValue{};
|
return CPASAnimParm::UParmValue{};
|
||||||
return x4_parms.at(idx);
|
return x4_parms[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
CPASAnimParm CPASAnimInfo::GetAnimParmData(u32 idx, CPASAnimParm::EParmType type) const
|
CPASAnimParm CPASAnimInfo::GetAnimParmData(u32 idx, CPASAnimParm::EParmType type) const
|
||||||
{
|
{
|
||||||
if (idx >= x4_parms.size())
|
if (idx >= x4_parms.size())
|
||||||
return CPASAnimParm::NoParameter();
|
return CPASAnimParm::NoParameter();
|
||||||
const CPASAnimParm::UParmValue& parm = x4_parms.at(idx);
|
const CPASAnimParm::UParmValue& parm = x4_parms[idx];
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,7 +38,6 @@ CParticleElectric::CParticleElectric(const TToken<CElectricDescription>& token)
|
||||||
if (desc->x40_SSWH)
|
if (desc->x40_SSWH)
|
||||||
{
|
{
|
||||||
x450_27_haveSSWH = true;
|
x450_27_haveSSWH = true;
|
||||||
x1e0_swooshGenerators.reserve(x154_SCNT);
|
|
||||||
for (int i=0 ; i<x154_SCNT ; ++i)
|
for (int i=0 ; i<x154_SCNT ; ++i)
|
||||||
{
|
{
|
||||||
x1e0_swooshGenerators.emplace_back(new CParticleSwoosh(desc->x40_SSWH.m_token, x150_SSEG));
|
x1e0_swooshGenerators.emplace_back(new CParticleSwoosh(desc->x40_SSWH.m_token, x150_SSEG));
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "CDependencyGroup.hpp"
|
#include "CDependencyGroup.hpp"
|
||||||
#include "CMorphBall.hpp"
|
#include "CMorphBall.hpp"
|
||||||
#include "CPlayer.hpp"
|
#include "CPlayer.hpp"
|
||||||
#include "CMorphBallShadow.hpp"
|
|
||||||
#include "CSimplePool.hpp"
|
#include "CSimplePool.hpp"
|
||||||
#include "CGameLight.hpp"
|
#include "CGameLight.hpp"
|
||||||
|
|
||||||
|
|
|
@ -4414,8 +4414,8 @@ const zeus::CTransform& CPlayer::GetFirstPersonCameraTransform(const CStateManag
|
||||||
return mgr.GetCameraManager()->GetFirstPersonCamera()->GetGunFollowTransform();
|
return mgr.GetCameraManager()->GetFirstPersonCamera()->GetGunFollowTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
TUniqueId CPlayer::CheckEnemiesAgainstOrbitZone(const std::vector<TUniqueId>& list, EPlayerZoneInfo info,
|
TUniqueId CPlayer::CheckEnemiesAgainstOrbitZone(const rstl::reserved_vector<TUniqueId, 1024>& list,
|
||||||
EPlayerZoneType zone, CStateManager& mgr) const
|
EPlayerZoneInfo info, EPlayerZoneType zone, CStateManager& mgr) const
|
||||||
{
|
{
|
||||||
zeus::CVector3f eyePos = GetEyePosition();
|
zeus::CVector3f eyePos = GetEyePosition();
|
||||||
zeus::CVector3f lookDir = x34_transform.basis[1].normalized();
|
zeus::CVector3f lookDir = x34_transform.basis[1].normalized();
|
||||||
|
|
|
@ -563,8 +563,8 @@ public:
|
||||||
bool ValidateObjectForMode(TUniqueId, CStateManager& mgr) const;
|
bool ValidateObjectForMode(TUniqueId, CStateManager& mgr) const;
|
||||||
TUniqueId FindAimTargetId(CStateManager& mgr);
|
TUniqueId FindAimTargetId(CStateManager& mgr);
|
||||||
TUniqueId GetAimTarget() const { return x3f4_aimTarget; }
|
TUniqueId GetAimTarget() const { return x3f4_aimTarget; }
|
||||||
TUniqueId CheckEnemiesAgainstOrbitZone(const std::vector<TUniqueId>&, EPlayerZoneInfo, EPlayerZoneType,
|
TUniqueId CheckEnemiesAgainstOrbitZone(const rstl::reserved_vector<TUniqueId, 1024>&, EPlayerZoneInfo,
|
||||||
CStateManager& mgr) const;
|
EPlayerZoneType, CStateManager& mgr) const;
|
||||||
TUniqueId FindOrbitTargetId(CStateManager& mgr);
|
TUniqueId FindOrbitTargetId(CStateManager& mgr);
|
||||||
void UpdateOrbitableObjects(CStateManager& mgr);
|
void UpdateOrbitableObjects(CStateManager& mgr);
|
||||||
TUniqueId FindBestOrbitableObject(const std::vector<TUniqueId>&, EPlayerZoneInfo, CStateManager& mgr) const;
|
TUniqueId FindBestOrbitableObject(const std::vector<TUniqueId>&, EPlayerZoneInfo, CStateManager& mgr) const;
|
||||||
|
|
494
Runtime/rstl.hpp
494
Runtime/rstl.hpp
|
@ -5,85 +5,487 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "optional.hpp"
|
#include "optional.hpp"
|
||||||
|
#include <logvisor/logvisor.hpp>
|
||||||
|
|
||||||
namespace rstl
|
namespace rstl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static logvisor::Module Log("rstl");
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using optional_object = std::experimental::optional<T>;
|
using optional_object = std::experimental::optional<T>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Vector reserved on construction
|
* @brief Base vector backed by statically-allocated array
|
||||||
*/
|
*/
|
||||||
template <class T, size_t N>
|
template <class T, size_t N>
|
||||||
class reserved_vector : public std::vector<T>
|
class _reserved_vector_base
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
reserved_vector() { this->reserve(N); }
|
explicit _reserved_vector_base(size_t _init_sz) : x0_size(_init_sz) {}
|
||||||
reserved_vector(size_t n, const T& val) : std::vector<T>(n, val) {}
|
size_t x0_size;
|
||||||
};
|
uint8_t x4_data[N][sizeof(T)];
|
||||||
|
T& _value(ssize_t idx) { return reinterpret_cast<T&>(x4_data[idx]); }
|
||||||
template <class T, size_t N>
|
const T& _value(ssize_t idx) const { return reinterpret_cast<const T&>(x4_data[idx]); }
|
||||||
class prereserved_vector
|
|
||||||
{
|
|
||||||
size_t x0_size = 1;
|
|
||||||
T x4_data[N];
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
T* m_val;
|
|
||||||
public:
|
|
||||||
iterator(T* val) : m_val(val) {}
|
|
||||||
T& operator*() const { return *m_val; }
|
|
||||||
T* operator->() const { return m_val; }
|
|
||||||
iterator& operator++() { ++m_val; return *this; }
|
|
||||||
bool operator!=(const iterator& other) const { return m_val != other.m_val; }
|
|
||||||
bool operator==(const iterator& other) const { return m_val == other.m_val; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class const_iterator
|
class const_iterator
|
||||||
{
|
{
|
||||||
T* m_val;
|
friend class _reserved_vector_base;
|
||||||
|
protected:
|
||||||
|
const T* m_val;
|
||||||
|
explicit const_iterator(const T* val) : m_val(val) {}
|
||||||
public:
|
public:
|
||||||
const_iterator(const T* val) : m_val(val) {}
|
using value_type = T;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
|
||||||
const T& operator*() const { return *m_val; }
|
const T& operator*() const { return *m_val; }
|
||||||
const T* operator->() const { return m_val; }
|
const T* operator->() const { return m_val; }
|
||||||
const_iterator& operator++() { ++m_val; return *this; }
|
const_iterator& operator++() { ++m_val; return *this; }
|
||||||
|
const_iterator& operator--() { --m_val; return *this; }
|
||||||
|
const_iterator operator++(int) { auto ret = *this; ++m_val; return ret; }
|
||||||
|
const_iterator operator--(int) { auto ret = *this; --m_val; return ret; }
|
||||||
bool operator!=(const const_iterator& other) const { return m_val != other.m_val; }
|
bool operator!=(const const_iterator& other) const { return m_val != other.m_val; }
|
||||||
bool operator==(const const_iterator& other) const { return m_val == other.m_val; }
|
bool operator==(const const_iterator& other) const { return m_val == other.m_val; }
|
||||||
|
const_iterator operator+(std::ptrdiff_t i) const { return const_iterator(m_val + i); }
|
||||||
|
const_iterator operator-(std::ptrdiff_t i) const { return const_iterator(m_val - i); }
|
||||||
|
const_iterator& operator+=(std::ptrdiff_t i) { m_val += i; return *this; }
|
||||||
|
const_iterator& operator-=(std::ptrdiff_t i) { m_val -= i; return *this; }
|
||||||
|
std::ptrdiff_t operator-(const const_iterator& it) const { return m_val - it.m_val; }
|
||||||
|
bool operator>(const const_iterator& it) const { return m_val > it.m_val; }
|
||||||
|
bool operator<(const const_iterator& it) const { return m_val < it.m_val; }
|
||||||
|
bool operator>=(const const_iterator& it) const { return m_val >= it.m_val; }
|
||||||
|
bool operator<=(const const_iterator& it) const { return m_val <= it.m_val; }
|
||||||
|
const T& operator[](std::ptrdiff_t i) const { return m_val[i]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_size(size_t n)
|
class iterator : public const_iterator
|
||||||
{
|
{
|
||||||
if (n <= N)
|
friend class _reserved_vector_base;
|
||||||
x0_size = n;
|
explicit iterator(T* val) : const_iterator(val) {}
|
||||||
|
public:
|
||||||
|
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; }
|
||||||
|
iterator operator++(int) { auto ret = *this; ++const_iterator::m_val; return ret; }
|
||||||
|
iterator operator--(int) { auto ret = *this; --const_iterator::m_val; return ret; }
|
||||||
|
iterator operator+(std::ptrdiff_t i) const { return iterator(const_cast<T*>(const_iterator::m_val) + i); }
|
||||||
|
iterator operator-(std::ptrdiff_t i) const { return iterator(const_cast<T*>(const_iterator::m_val) - i); }
|
||||||
|
iterator& operator+=(std::ptrdiff_t i) { const_iterator::m_val += i; return *this; }
|
||||||
|
iterator& operator-=(std::ptrdiff_t i) { const_iterator::m_val -= i; return *this; }
|
||||||
|
std::ptrdiff_t operator-(const iterator& it) const { return const_iterator::m_val - it.m_val; }
|
||||||
|
T& operator[](std::ptrdiff_t i) const { return const_cast<T*>(const_iterator::m_val)[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_reverse_iterator
|
||||||
|
{
|
||||||
|
friend class _reserved_vector_base;
|
||||||
|
protected:
|
||||||
|
const T* m_val;
|
||||||
|
explicit const_reverse_iterator(const T* val) : m_val(val) {}
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
|
||||||
|
const T& operator*() const { return *m_val; }
|
||||||
|
const T* operator->() const { return m_val; }
|
||||||
|
const_reverse_iterator& operator++() { --m_val; return *this; }
|
||||||
|
const_reverse_iterator& operator--() { ++m_val; return *this; }
|
||||||
|
const_reverse_iterator operator++(int) { auto ret = *this; --m_val; return ret; }
|
||||||
|
const_reverse_iterator operator--(int) { auto ret = *this; ++m_val; return ret; }
|
||||||
|
bool operator!=(const const_reverse_iterator& other) const { return m_val != other.m_val; }
|
||||||
|
bool operator==(const const_reverse_iterator& other) const { return m_val == other.m_val; }
|
||||||
|
const_reverse_iterator operator+(std::ptrdiff_t i) const { return const_reverse_iterator(m_val - i); }
|
||||||
|
const_reverse_iterator operator-(std::ptrdiff_t i) const { return const_reverse_iterator(m_val + i); }
|
||||||
|
const_reverse_iterator& operator+=(std::ptrdiff_t i) { m_val -= i; return *this; }
|
||||||
|
const_reverse_iterator& operator-=(std::ptrdiff_t i) { m_val += i; return *this; }
|
||||||
|
std::ptrdiff_t operator-(const const_reverse_iterator& it) const { return it.m_val - m_val; }
|
||||||
|
bool operator>(const const_iterator& it) const { return it.m_val > m_val; }
|
||||||
|
bool operator<(const const_iterator& it) const { return it.m_val < m_val; }
|
||||||
|
bool operator>=(const const_iterator& it) const { return it.m_val >= m_val; }
|
||||||
|
bool operator<=(const const_iterator& it) const { return it.m_val <= m_val; }
|
||||||
|
const T& operator[](std::ptrdiff_t i) const { return m_val[-i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class reverse_iterator : public const_reverse_iterator
|
||||||
|
{
|
||||||
|
friend class _reserved_vector_base;
|
||||||
|
explicit reverse_iterator(T* val) : const_reverse_iterator(val) {}
|
||||||
|
public:
|
||||||
|
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; }
|
||||||
|
reverse_iterator operator++(int) { auto ret = *this; --const_reverse_iterator::m_val; return ret; }
|
||||||
|
reverse_iterator operator--(int) { auto ret = *this; ++const_reverse_iterator::m_val; return ret; }
|
||||||
|
reverse_iterator operator+(std::ptrdiff_t i) const
|
||||||
|
{ return reverse_iterator(const_cast<T*>(const_reverse_iterator::m_val) - i); }
|
||||||
|
reverse_iterator operator-(std::ptrdiff_t i) const
|
||||||
|
{ return reverse_iterator(const_cast<T*>(const_reverse_iterator::m_val) + i); }
|
||||||
|
reverse_iterator& operator+=(std::ptrdiff_t i) { const_reverse_iterator::m_val -= i; return *this; }
|
||||||
|
reverse_iterator& operator-=(std::ptrdiff_t i) { const_reverse_iterator::m_val += i; return *this; }
|
||||||
|
std::ptrdiff_t operator-(const reverse_iterator& it) const { return it.m_val - const_reverse_iterator::m_val; }
|
||||||
|
T& operator[](std::ptrdiff_t i) const { return const_cast<T*>(const_reverse_iterator::m_val)[-i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t size() const noexcept { return x0_size; }
|
||||||
|
bool empty() const noexcept { return x0_size == 0; }
|
||||||
|
const T* data() const noexcept { return std::addressof(_value(0)); }
|
||||||
|
T* data() noexcept { return std::addressof(_value(0)); }
|
||||||
|
|
||||||
|
T& back() { return _value(x0_size - 1); }
|
||||||
|
T& front() { return _value(0); }
|
||||||
|
const T& back() const { return _value(x0_size - 1); }
|
||||||
|
const T& front() const { return _value(0); }
|
||||||
|
|
||||||
|
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))); }
|
||||||
|
iterator begin() noexcept { return iterator(std::addressof(_value(0))); }
|
||||||
|
iterator end() noexcept { return iterator(std::addressof(_value(x0_size))); }
|
||||||
|
const_iterator cbegin() const noexcept { return begin(); }
|
||||||
|
const_iterator cend() const noexcept { return end(); }
|
||||||
|
|
||||||
|
const_reverse_iterator rbegin() const noexcept
|
||||||
|
{ return const_reverse_iterator(std::addressof(_value(x0_size - 1))); }
|
||||||
|
const_reverse_iterator rend() const noexcept { return const_reverse_iterator(std::addressof(_value(-1))); }
|
||||||
|
reverse_iterator rbegin() noexcept { return reverse_iterator(std::addressof(_value(x0_size - 1))); }
|
||||||
|
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(); }
|
||||||
|
|
||||||
|
T& operator[](size_t idx) { 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
|
||||||
|
*/
|
||||||
|
template <class T, size_t N>
|
||||||
|
class reserved_vector : public _reserved_vector_base<T, N>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using base = _reserved_vector_base<T, N>;
|
||||||
|
using iterator = typename base::iterator;
|
||||||
|
using const_iterator = typename base::const_iterator;
|
||||||
|
reserved_vector() : base(0) {}
|
||||||
|
~reserved_vector()
|
||||||
|
{
|
||||||
|
for (size_t i=0 ; i<base::x0_size ; ++i)
|
||||||
|
std::default_delete<T>()(std::addressof(base::_value(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_data(const T* data) { memmove(x4_data, data, sizeof(T) * x0_size); }
|
|
||||||
|
|
||||||
size_t size() const { return x0_size; }
|
|
||||||
|
|
||||||
T& back() const { return x4_data[(x0_size == 0) ? 0 : x0_size - 1]; }
|
|
||||||
T& front() const { return x4_data[0]; }
|
|
||||||
const_iterator cbegin() const { return const_iterator(&x4_data[0]); }
|
|
||||||
const_iterator cend() const { return const_iterator(&x4_data[x0_size - 1]); }
|
|
||||||
iterator begin() { return iterator(&x4_data[0]); }
|
|
||||||
iterator end() { return iterator(&x4_data[x0_size - 1]); }
|
|
||||||
|
|
||||||
T& operator[](size_t idx) { return x4_data[idx]; }
|
|
||||||
const T& operator[](size_t idx) const { return x4_data[idx]; }
|
|
||||||
void push_back(const T& d)
|
void push_back(const T& d)
|
||||||
{
|
{
|
||||||
x4_data[x0_size] = d;
|
#ifndef NDEBUG
|
||||||
++x0_size;
|
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)
|
void push_back(T&& d)
|
||||||
{
|
{
|
||||||
x4_data[x0_size] = std::move(d);
|
#ifndef NDEBUG
|
||||||
++x0_size;
|
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;
|
||||||
|
std::default_delete<T>()(std::addressof(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) - 1;
|
||||||
|
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) - 1;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
for (size_t i = size; i < base::x0_size; ++i)
|
||||||
|
std::default_delete<T>()(std::addressof(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)
|
||||||
|
{
|
||||||
|
for (size_t i = size; i < base::x0_size; ++i)
|
||||||
|
std::default_delete<T>()(std::addressof(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;
|
||||||
|
std::default_delete<T>()(std::addressof(base::_value(base::x0_size)));
|
||||||
|
return base::_const_cast_iterator(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
for (auto it = base::begin(); it != base::end(); ++it)
|
||||||
|
std::default_delete<T>()(std::addressof(*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))) T;
|
||||||
|
}
|
||||||
|
void _deinit()
|
||||||
|
{
|
||||||
|
for (auto& i : base::x4_data)
|
||||||
|
std::default_delete<T>()(reinterpret_cast<T*>(std::addressof(i)));
|
||||||
|
}
|
||||||
|
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() { _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) - 1;
|
||||||
|
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) - 1;
|
||||||
|
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>
|
||||||
|
|
Loading…
Reference in New Issue