[ox] Add StringView, Writer system, Preloader system
This commit is contained in:
89
deps/ox/src/ox/std/vector.hpp
vendored
89
deps/ox/src/ox/std/vector.hpp
vendored
@@ -22,38 +22,6 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename PlatSpec>
|
||||
struct VectorMemMap {
|
||||
typename PlatSpec::size_t size = 0;
|
||||
typename PlatSpec::size_t cap = 0;
|
||||
typename PlatSpec::PtrType items = 0;
|
||||
uint8_t allocator = 0;
|
||||
};
|
||||
|
||||
template<typename PlatSpec>
|
||||
[[nodiscard]]
|
||||
constexpr auto sizeOf(const VectorMemMap<PlatSpec> &t) noexcept {
|
||||
constexpr auto padding = [](std::size_t size, std::size_t al) {
|
||||
return size - size % al;
|
||||
};
|
||||
std::size_t size = 0;
|
||||
size += sizeof(t.size);
|
||||
size += padding(size, PlatSpec::alignOf(t.cap));
|
||||
size += sizeof(t.cap);
|
||||
size += padding(size, PlatSpec::alignOf(t.items));
|
||||
size += sizeof(t.items);
|
||||
size += padding(size, PlatSpec::alignOf(t.allocator));
|
||||
size += sizeof(t.allocator);
|
||||
return size;
|
||||
}
|
||||
|
||||
template<typename PlatSpec>
|
||||
[[nodiscard]]
|
||||
constexpr auto alignOf(const VectorMemMap<PlatSpec>&) noexcept {
|
||||
const typename PlatSpec::size_t i = 0;
|
||||
return PlatSpec::alignOf(i);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, typename Allocator, std::size_t Size = 1>
|
||||
@@ -75,12 +43,12 @@ struct VectorAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void moveConstructItemsFrom(T **items, VectorAllocator &src, const std::size_t count, const std::size_t cap) noexcept {
|
||||
constexpr void moveConstructItemsFrom(T **items, VectorAllocator *src, const std::size_t count, const std::size_t cap) noexcept {
|
||||
// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM,
|
||||
// try removing it later
|
||||
if (cap <= Size && count <= Size) {
|
||||
const auto dstItems = reinterpret_cast<T*>(m_data.data());
|
||||
const auto srcItems = reinterpret_cast<T*>(src.m_data.data());
|
||||
const auto srcItems = reinterpret_cast<T*>(src->m_data.data());
|
||||
for (auto i = 0u; i < count; ++i) {
|
||||
std::construct_at<T>(&dstItems[i], std::move(srcItems[i]));
|
||||
}
|
||||
@@ -88,12 +56,12 @@ struct VectorAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr void moveItemsFrom(T **items, VectorAllocator &src, const std::size_t count, const std::size_t cap) noexcept {
|
||||
constexpr void moveItemsFrom(T **items, VectorAllocator *src, const std::size_t count, const std::size_t cap) noexcept {
|
||||
// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM,
|
||||
// try removing it later
|
||||
if (cap <= Size && count <= Size) {
|
||||
const auto dstItems = reinterpret_cast<T*>(m_data.data());
|
||||
const auto srcItems = reinterpret_cast<T*>(src.m_data.data());
|
||||
const auto srcItems = reinterpret_cast<T*>(src->m_data.data());
|
||||
for (std::size_t i = 0; i < count; ++i) {
|
||||
dstItems[i] = std::move(srcItems[i]);
|
||||
}
|
||||
@@ -124,11 +92,11 @@ struct VectorAllocator<T, Allocator, 0> {
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
constexpr void moveConstructItemsFrom(T**, VectorAllocator&, const std::size_t, const std::size_t) noexcept {
|
||||
constexpr void moveConstructItemsFrom(T**, VectorAllocator*, const std::size_t, const std::size_t) noexcept {
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
constexpr void moveItemsFrom(T**, VectorAllocator&, const std::size_t, const std::size_t) noexcept {
|
||||
constexpr void moveItemsFrom(T**, VectorAllocator*, const std::size_t, const std::size_t) noexcept {
|
||||
}
|
||||
|
||||
constexpr void deallocate(T *items, std::size_t cap) noexcept {
|
||||
@@ -142,7 +110,7 @@ struct VectorAllocator<T, Allocator, 0> {
|
||||
}
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize = 0, typename Allocator = std::allocator<T>>
|
||||
class Vector {
|
||||
class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
@@ -257,7 +225,6 @@ class Vector {
|
||||
std::size_t m_size = 0;
|
||||
std::size_t m_cap = 0;
|
||||
T *m_items = nullptr;
|
||||
detail::VectorAllocator<T, Allocator, SmallVectorSize> m_allocator;
|
||||
|
||||
public:
|
||||
constexpr Vector() noexcept = default;
|
||||
@@ -408,8 +375,7 @@ class Vector {
|
||||
*/
|
||||
constexpr Error unordered_erase(std::size_t pos);
|
||||
|
||||
private:
|
||||
constexpr void expandCap(std::size_t cap);
|
||||
constexpr void reserve(std::size_t cap);
|
||||
|
||||
};
|
||||
|
||||
@@ -425,7 +391,7 @@ template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(std::size_t size) noexcept {
|
||||
m_size = size;
|
||||
m_cap = m_size;
|
||||
m_allocator.allocate(&m_items, m_cap);
|
||||
this->allocate(&m_items, m_cap);
|
||||
for (std::size_t i = 0; i < size; ++i) {
|
||||
std::construct_at(&m_items[i]);
|
||||
}
|
||||
@@ -442,7 +408,7 @@ template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr Vector<T, SmallVectorSize, Allocator>::Vector(const Vector &other) {
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_allocator.allocate(&m_items, other.m_cap);
|
||||
this->allocate(&m_items, other.m_cap);
|
||||
for (std::size_t i = 0; i < m_size; ++i) {
|
||||
std::construct_at(&m_items[i], other.m_items[i]);
|
||||
}
|
||||
@@ -453,7 +419,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(Vector &&other) noexcept
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_items = other.m_items;
|
||||
m_allocator.moveConstructItemsFrom(&m_items, other.m_allocator, m_size, m_cap);
|
||||
this->moveConstructItemsFrom(&m_items, &other, m_size, m_cap);
|
||||
other.m_size = 0;
|
||||
other.m_cap = 0;
|
||||
other.m_items = nullptr;
|
||||
@@ -462,7 +428,7 @@ constexpr Vector<T, SmallVectorSize, Allocator>::Vector(Vector &&other) noexcept
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr Vector<T, SmallVectorSize, Allocator>::~Vector() {
|
||||
clear();
|
||||
m_allocator.deallocate(m_items, m_cap);
|
||||
this->deallocate(m_items, m_cap);
|
||||
m_items = nullptr;
|
||||
}
|
||||
|
||||
@@ -483,11 +449,11 @@ template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allocator>::operator=(const Vector &other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
m_allocator.deallocate(m_items, m_cap);
|
||||
this->deallocate(m_items, m_cap);
|
||||
m_items = nullptr;
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_allocator.allocate(&m_items, other.m_cap);
|
||||
this->allocate(&m_items, other.m_cap);
|
||||
for (std::size_t i = 0; i < m_size; i++) {
|
||||
std::construct_at(&m_items[i], other.m_items[i]);
|
||||
}
|
||||
@@ -499,11 +465,11 @@ template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allocator>::operator=(Vector &&other) noexcept {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
m_allocator.deallocate(m_items, m_cap);
|
||||
this->deallocate(m_items, m_cap);
|
||||
m_size = other.m_size;
|
||||
m_cap = other.m_cap;
|
||||
m_items = other.m_items;
|
||||
m_allocator.moveItemsFrom(&m_items, other.m_allocator, m_size, m_cap);
|
||||
this->moveItemsFrom(&m_items, &other, m_size, m_cap);
|
||||
other.m_size = 0;
|
||||
other.m_cap = 0;
|
||||
other.m_items = nullptr;
|
||||
@@ -580,7 +546,7 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::clear() {
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::resize(std::size_t size) {
|
||||
if (m_cap < size) {
|
||||
expandCap(size);
|
||||
reserve(size * 2);
|
||||
}
|
||||
if (m_size < size) {
|
||||
for (std::size_t i = m_size; i < size; i++) {
|
||||
@@ -606,9 +572,9 @@ constexpr bool Vector<T, SmallVectorSize, Allocator>::contains(const T &v) const
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, std::size_t cnt, const T &val) {
|
||||
// TODO: insert should ideally have its own expandCap
|
||||
// TODO: insert should ideally have its own reserve
|
||||
if (m_size + cnt > m_cap) {
|
||||
expandCap(m_cap ? m_size + cnt : initialSize);
|
||||
reserve(m_cap ? m_size + cnt : initialSize);
|
||||
}
|
||||
if (pos < m_size) {
|
||||
for (auto i = m_size + cnt - 1; i > pos; --i) {
|
||||
@@ -625,9 +591,9 @@ constexpr void Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, st
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::insert(std::size_t pos, const T &val) {
|
||||
// TODO: insert should ideally have its own expandCap
|
||||
// TODO: insert should ideally have its own reserve
|
||||
if (m_size == m_cap) {
|
||||
expandCap(m_cap ? m_cap * 2 : initialSize);
|
||||
reserve(m_cap ? m_cap * 2 : initialSize);
|
||||
}
|
||||
if (pos < m_size) {
|
||||
for (auto i = m_size; i > pos; --i) {
|
||||
@@ -644,7 +610,7 @@ template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
template<typename... Args>
|
||||
constexpr T &Vector<T, SmallVectorSize, Allocator>::emplace_back(Args&&... args) {
|
||||
if (m_size == m_cap) {
|
||||
expandCap(m_cap ? m_cap * 2 : initialSize);
|
||||
reserve(m_cap ? m_cap * 2 : initialSize);
|
||||
}
|
||||
auto out = std::construct_at(&m_items[m_size], ox::forward<Args>(args)...);
|
||||
++m_size;
|
||||
@@ -654,7 +620,7 @@ constexpr T &Vector<T, SmallVectorSize, Allocator>::emplace_back(Args&&... args)
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::push_back(const T &item) {
|
||||
if (m_size == m_cap) {
|
||||
expandCap(m_cap ? m_cap * 2 : initialSize);
|
||||
reserve(m_cap ? m_cap * 2 : initialSize);
|
||||
}
|
||||
std::construct_at(&m_items[m_size], item);
|
||||
++m_size;
|
||||
@@ -696,18 +662,21 @@ constexpr Error Vector<T, SmallVectorSize, Allocator>::unordered_erase(std::size
|
||||
}
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::expandCap(std::size_t cap) {
|
||||
constexpr void Vector<T, SmallVectorSize, Allocator>::reserve(std::size_t cap) {
|
||||
if (cap <= m_cap) {
|
||||
return;
|
||||
}
|
||||
const auto oldItems = m_items;
|
||||
const auto oldCap = m_cap;
|
||||
m_cap = cap;
|
||||
m_allocator.allocate(&m_items, cap);
|
||||
this->allocate(&m_items, cap);
|
||||
if (oldItems) { // move over old items
|
||||
const auto itRange = ox::min(cap, m_size);
|
||||
for (std::size_t i = 0; i < itRange; ++i) {
|
||||
std::construct_at(&m_items[i], std::move(oldItems[i]));
|
||||
oldItems[i].~T();
|
||||
}
|
||||
m_allocator.deallocate(oldItems, oldCap);
|
||||
this->deallocate(oldItems, oldCap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user