[ox/std] Fix problems with Vector using operator= where constructors should be used

This commit is contained in:
Gary Talent 2021-07-31 03:36:40 -05:00
parent d8a0a5f50d
commit 313b35f605

View File

@ -38,6 +38,17 @@ struct SmallVector {
} }
} }
constexpr void moveConstructItemsFrom(T **items, SmallVector &src, const std::size_t count, const std::size_t cap) noexcept {
if (cap <= Size) {
const auto dstItems = bit_cast<T*>(m_data);
const auto srcItems = bit_cast<T*>(src.m_data);
for (auto i = 0u; i < count; ++i) {
new (&dstItems[i]) T(move(srcItems[i]));
}
*items = bit_cast<T*>(m_data);
}
}
constexpr void moveItemsFrom(T **items, SmallVector &src, const std::size_t count, const std::size_t cap) noexcept { constexpr void moveItemsFrom(T **items, SmallVector &src, const std::size_t count, const std::size_t cap) noexcept {
if (cap <= Size) { if (cap <= Size) {
const auto dstItems = bit_cast<T*>(m_data); const auto dstItems = bit_cast<T*>(m_data);
@ -68,6 +79,10 @@ struct SmallVector<T, 0> {
*items = bit_cast<T*>(new AllocAlias<T>[cap]); *items = bit_cast<T*>(new AllocAlias<T>[cap]);
} }
[[maybe_unused]]
constexpr void moveConstructItemsFrom(T**, SmallVector&, const std::size_t, const std::size_t) noexcept {
}
[[maybe_unused]] [[maybe_unused]]
constexpr void moveItemsFrom(T**, SmallVector&, const std::size_t, const std::size_t) noexcept { constexpr void moveItemsFrom(T**, SmallVector&, const std::size_t, const std::size_t) noexcept {
} }
@ -284,7 +299,7 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
void insert(std::size_t pos, const T &val); void insert(std::size_t pos, const T &val);
template<typename... Args> template<typename... Args>
void emplace_back(Args&&... args); T &emplace_back(Args&&... args);
void push_back(const T &item); void push_back(const T &item);
@ -349,7 +364,7 @@ Vector<T, SmallVectorSize>::Vector(const Vector &other) {
m_cap = other.m_cap; m_cap = other.m_cap;
this->initItems(&m_items, other.m_cap); this->initItems(&m_items, other.m_cap);
for (std::size_t i = 0; i < m_size; ++i) { for (std::size_t i = 0; i < m_size; ++i) {
m_items[i] = other.m_items[i]; new (&m_items[i]) T(other.m_items[i]);
} }
} }
@ -358,7 +373,7 @@ Vector<T, SmallVectorSize>::Vector(Vector &&other) noexcept {
m_size = other.m_size; m_size = other.m_size;
m_cap = other.m_cap; m_cap = other.m_cap;
m_items = other.m_items; m_items = other.m_items;
this->moveItemsFrom(&m_items, other, m_size, m_cap); this->moveConstructItemsFrom(&m_items, other, m_size, m_cap);
other.m_size = 0; other.m_size = 0;
other.m_cap = 0; other.m_cap = 0;
other.m_items = nullptr; other.m_items = nullptr;
@ -489,7 +504,7 @@ constexpr void Vector<T, SmallVectorSize>::resize(std::size_t size) {
} }
if (m_size < size) { if (m_size < size) {
for (std::size_t i = m_size; i < size; i++) { for (std::size_t i = m_size; i < size; i++) {
m_items[i] = {}; new (&m_items[i]) T();
} }
} else { } else {
for (std::size_t i = size; i < m_size; i++) { for (std::size_t i = size; i < m_size; i++) {
@ -524,12 +539,13 @@ void Vector<T, SmallVectorSize>::insert(std::size_t pos, const T &val) {
template<typename T, std::size_t SmallVectorSize> template<typename T, std::size_t SmallVectorSize>
template<typename... Args> template<typename... Args>
void Vector<T, SmallVectorSize>::emplace_back(Args&&... args) { T &Vector<T, SmallVectorSize>::emplace_back(Args&&... args) {
if (m_size == m_cap) { if (m_size == m_cap) {
expandCap(m_cap ? m_cap * 2 : 100); expandCap(m_cap ? m_cap * 2 : 100);
} }
new (&m_items[m_size]) T{forward<Args>(args)...}; auto out = new (&m_items[m_size]) T{forward<Args>(args)...};
++m_size; ++m_size;
return *out;
} }
template<typename T, std::size_t SmallVectorSize> template<typename T, std::size_t SmallVectorSize>