[ox/std] Make Vector use std::allocator

This commit is contained in:
Gary Talent 2021-11-06 12:37:16 -05:00
parent 380dd1cd76
commit 263ed4f7e7

View File

@ -12,6 +12,7 @@
#include "initializerlist.hpp" #include "initializerlist.hpp"
#include "iterator.hpp" #include "iterator.hpp"
#include "math.hpp" #include "math.hpp"
#include "memory.hpp"
#include "new.hpp" #include "new.hpp"
#include "types.hpp" #include "types.hpp"
#include "utility.hpp" #include "utility.hpp"
@ -23,6 +24,7 @@ namespace detail {
template<typename T, std::size_t Size = 100> template<typename T, std::size_t Size = 100>
struct SmallVector { struct SmallVector {
private: private:
std::allocator<T> m_allocator;
AllocAlias<T> m_data[Size] = {}; AllocAlias<T> m_data[Size] = {};
public: public:
@ -34,7 +36,7 @@ struct SmallVector {
if (cap <= Size) { if (cap <= Size) {
*items = reinterpret_cast<T*>(m_data); *items = reinterpret_cast<T*>(m_data);
} else { } else {
*items = reinterpret_cast<T*>(new AllocAlias<T>[cap]); *items = m_allocator.allocate(cap);
} }
} }
@ -60,9 +62,9 @@ struct SmallVector {
} }
} }
constexpr void clearItems(AllocAlias<T> *items) noexcept { constexpr void clearItems(T *items, std::size_t n) noexcept {
if (items != m_data) { if (static_cast<void*>(items) != static_cast<void*>(m_data)) {
delete[] items; m_allocator.deallocate(items, n);
} }
} }
@ -70,13 +72,15 @@ struct SmallVector {
template<typename T> template<typename T>
struct SmallVector<T, 0> { struct SmallVector<T, 0> {
private:
std::allocator<T> m_allocator;
public: public:
SmallVector() noexcept = default; SmallVector() noexcept = default;
SmallVector(SmallVector&) noexcept = default; SmallVector(SmallVector&) noexcept = default;
SmallVector(SmallVector&&) noexcept = default; SmallVector(SmallVector&&) noexcept = default;
protected: protected:
constexpr void initItems(T **items, std::size_t cap) noexcept { constexpr void initItems(T **items, std::size_t cap) noexcept {
*items = reinterpret_cast<T*>(new AllocAlias<T>[cap]); *items = m_allocator.allocate(cap);
} }
[[maybe_unused]] [[maybe_unused]]
@ -87,8 +91,8 @@ struct SmallVector<T, 0> {
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 {
} }
constexpr void clearItems(AllocAlias<T> *items) noexcept { constexpr void clearItems(T *items, std::size_t n) noexcept {
delete[] items; m_allocator.deallocate(items, n);
} }
}; };
@ -382,7 +386,7 @@ Vector<T, SmallVectorSize>::Vector(Vector &&other) noexcept {
template<typename T, std::size_t SmallVectorSize> template<typename T, std::size_t SmallVectorSize>
Vector<T, SmallVectorSize>::~Vector() { Vector<T, SmallVectorSize>::~Vector() {
clear(); clear();
this->clearItems(reinterpret_cast<AllocAlias<T>*>(m_items)); this->clearItems(m_items, m_cap);
m_items = nullptr; m_items = nullptr;
} }
@ -403,7 +407,7 @@ template<typename T, std::size_t SmallVectorSize>
constexpr Vector<T, SmallVectorSize> &Vector<T, SmallVectorSize>::operator=(const Vector &other) { constexpr Vector<T, SmallVectorSize> &Vector<T, SmallVectorSize>::operator=(const Vector &other) {
if (this != &other) { if (this != &other) {
clear(); clear();
this->clearItems(reinterpret_cast<AllocAlias<T>*>(m_items)); this->clearItems(m_items, m_cap);
m_items = nullptr; m_items = nullptr;
m_size = other.m_size; m_size = other.m_size;
m_cap = other.m_cap; m_cap = other.m_cap;
@ -419,7 +423,7 @@ template<typename T, std::size_t SmallVectorSize>
constexpr Vector<T, SmallVectorSize> &Vector<T, SmallVectorSize>::operator=(Vector &&other) noexcept { constexpr Vector<T, SmallVectorSize> &Vector<T, SmallVectorSize>::operator=(Vector &&other) noexcept {
if (this != &other) { if (this != &other) {
clear(); clear();
this->clearItems(reinterpret_cast<AllocAlias<T>*>(m_items)); this->clearItems(m_items, m_cap);
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;
@ -604,7 +608,7 @@ void Vector<T, SmallVectorSize>::expandCap(std::size_t cap) {
for (std::size_t i = itRange; i < m_cap; i++) { for (std::size_t i = itRange; i < m_cap; i++) {
new (&m_items[i]) T; new (&m_items[i]) T;
} }
this->clearItems(reinterpret_cast<AllocAlias<T>*>(oldItems)); this->clearItems(m_items, m_cap);
} }
} }