mirror of https://github.com/AxioDL/metaforce.git
Better storage mechanism for reserved_vector with proper alignment
This commit is contained in:
parent
801938c844
commit
7d125e504a
|
@ -34,6 +34,10 @@ class CRainSplashGenerator
|
||||||
zeus::CVector3f x64_pos;
|
zeus::CVector3f x64_pos;
|
||||||
float x70_ = 0.f;
|
float x70_ = 0.f;
|
||||||
explicit SRainSplash(boo::IGraphicsDataFactory::Context& ctx);
|
explicit SRainSplash(boo::IGraphicsDataFactory::Context& ctx);
|
||||||
|
SRainSplash(const SRainSplash&) = delete;
|
||||||
|
SRainSplash& operator=(const SRainSplash&) = delete;
|
||||||
|
SRainSplash(SRainSplash&&) = default;
|
||||||
|
SRainSplash& operator=(SRainSplash&&) = default;
|
||||||
void Update(float dt, CStateManager& mgr);
|
void Update(float dt, CStateManager& mgr);
|
||||||
bool IsActive() const;
|
bool IsActive() const;
|
||||||
void Draw(float alpha, float dt, const zeus::CVector3f& pos) const;
|
void Draw(float alpha, float dt, const zeus::CVector3f& pos) const;
|
||||||
|
|
114
Runtime/rstl.hpp
114
Runtime/rstl.hpp
|
@ -25,11 +25,18 @@ template <class T, size_t N>
|
||||||
class _reserved_vector_base
|
class _reserved_vector_base
|
||||||
{
|
{
|
||||||
protected:
|
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) {}
|
explicit _reserved_vector_base(size_t _init_sz) : x0_size(_init_sz) {}
|
||||||
size_t x0_size;
|
size_t x0_size;
|
||||||
uint8_t x4_data[N][sizeof(T)];
|
storage_t x4_data[N];
|
||||||
T& _value(std::ptrdiff_t idx) { return reinterpret_cast<T&>(x4_data[idx]); }
|
T& _value(std::ptrdiff_t idx) { return x4_data[idx]._value; }
|
||||||
const T& _value(std::ptrdiff_t idx) const { return reinterpret_cast<const T&>(x4_data[idx]); }
|
const T& _value(std::ptrdiff_t idx) const { return x4_data[idx]._value; }
|
||||||
template <typename Tp>
|
template <typename Tp>
|
||||||
static void destroy(Tp& t, std::enable_if_t<std::is_destructible<Tp>::value &&
|
static void destroy(Tp& t, std::enable_if_t<std::is_destructible<Tp>::value &&
|
||||||
!std::is_trivially_destructible<Tp>::value>* = 0) { t.Tp::~Tp(); }
|
!std::is_trivially_destructible<Tp>::value>* = 0) { t.Tp::~Tp(); }
|
||||||
|
@ -187,6 +194,73 @@ public:
|
||||||
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) {}
|
reserved_vector() : base(0) {}
|
||||||
|
|
||||||
|
reserved_vector(const reserved_vector& other) : base(other.x0_size)
|
||||||
|
{
|
||||||
|
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 i = 0;
|
||||||
|
if (other.base::x0_size > base::x0_size)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
for (size_t i=0 ; i<base::x0_size ; ++i)
|
||||||
|
::new (static_cast<void*>(std::addressof(base::_value(i)))) T(std::forward<T>(other.base::_value(i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
reserved_vector& operator=(reserved_vector&& other)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
if (other.base::x0_size > base::x0_size)
|
||||||
|
{
|
||||||
|
for (; i<base::x0_size ; ++i)
|
||||||
|
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()
|
~reserved_vector()
|
||||||
{
|
{
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
|
@ -354,20 +428,50 @@ class prereserved_vector : public _reserved_vector_base<T, N>
|
||||||
void _init()
|
void _init()
|
||||||
{
|
{
|
||||||
for (auto& i : base::x4_data)
|
for (auto& i : base::x4_data)
|
||||||
::new (static_cast<void*>(std::addressof(i))) T;
|
::new (static_cast<void*>(std::addressof(i._value))) T;
|
||||||
}
|
}
|
||||||
void _deinit()
|
void _deinit()
|
||||||
{
|
{
|
||||||
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
if (std::is_destructible<T>::value && !std::is_trivially_destructible<T>::value)
|
||||||
for (auto& i : base::x4_data)
|
for (auto& i : base::x4_data)
|
||||||
base::destroy(reinterpret_cast<T&>(i));
|
base::destroy(i._value);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
using base = _reserved_vector_base<T, N>;
|
using base = _reserved_vector_base<T, N>;
|
||||||
using iterator = typename base::iterator;
|
using iterator = typename base::iterator;
|
||||||
using const_iterator = typename base::const_iterator;
|
using const_iterator = typename base::const_iterator;
|
||||||
prereserved_vector() : base(1) { _init(); }
|
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(); }
|
~prereserved_vector() { _deinit(); }
|
||||||
|
|
||||||
void set_size(size_t n)
|
void set_size(size_t n)
|
||||||
{
|
{
|
||||||
if (n <= N)
|
if (n <= N)
|
||||||
|
|
Loading…
Reference in New Issue