diff --git a/deps/ox/src/ox/model/walk.hpp b/deps/ox/src/ox/model/walk.hpp index a0add7d4..4fd8eed1 100644 --- a/deps/ox/src/ox/model/walk.hpp +++ b/deps/ox/src/ox/model/walk.hpp @@ -51,7 +51,7 @@ constexpr DataWalker::DataWalker(DescriptorType *type, T fieldHandler template constexpr Result DataWalker::type() const noexcept { oxRequire(out, m_typeStack.back()); - return out; + return *out; } template diff --git a/deps/ox/src/ox/preloader/preloader.hpp b/deps/ox/src/ox/preloader/preloader.hpp index bd38f43a..3a2f53dc 100644 --- a/deps/ox/src/ox/preloader/preloader.hpp +++ b/deps/ox/src/ox/preloader/preloader.hpp @@ -271,7 +271,7 @@ constexpr ox::Error Preloader::endAlloc() noexcept { if (m_allocStack.empty()) { return m_writer.seekp(0, ox::ios_base::end); } - const auto &si = m_allocStack.back().unwrap(); + const auto &si = *m_allocStack.back().unwrap(); oxReturnError(m_writer.seekp(si.restore, si.seekdir)); m_allocStack.pop_back(); return {}; @@ -354,7 +354,7 @@ constexpr ox::Error Preloader::fieldVector( template constexpr bool Preloader::unionCheckAndIt() noexcept { - auto &u = m_unionIdx.back().unwrap(); + auto &u = *m_unionIdx.back().unwrap(); return u.checkAndIterate(); } diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 8619fe3c..fee31ea2 100644 --- a/deps/ox/src/ox/std/string.hpp +++ b/deps/ox/src/ox/std/string.hpp @@ -528,7 +528,7 @@ constexpr void BasicString::set(const BasicString std::size_t strBytes = src.bytes(); m_buff.resize(strBytes); copy_n(src.begin(), strBytes, m_buff.data()); - m_buff.back().value = 0; + *m_buff.back().value = 0; } template @@ -536,7 +536,7 @@ constexpr void BasicString::set(CRStringView str) noexcept { std::size_t strBytes = str.bytes(); m_buff.resize(strBytes + 1); copy_n(str.data(), strBytes, m_buff.data()); - m_buff.back().value = 0; + *m_buff.back().value = 0; } template @@ -544,7 +544,7 @@ constexpr void BasicString::set(const char *str) noexcept { std::size_t strBytes = ox_strlen(str) + 1; m_buff.resize(strBytes); copy_n(str, strBytes, m_buff.data()); - m_buff.back().value = 0; + *m_buff.back().value = 0; } template @@ -552,7 +552,7 @@ constexpr void BasicString::set(const char8_t *str) noexcept std::size_t strBytes = ox_strlen(str) + 1; m_buff.resize(strBytes); memcpy(m_buff.data(), str, strBytes); - m_buff.back().value = 0; + *m_buff.back().value = 0; } extern template class BasicString<8>; diff --git a/deps/ox/src/ox/std/test/tests.cpp b/deps/ox/src/ox/std/test/tests.cpp index 8ad2e3f3..3c81933f 100644 --- a/deps/ox/src/ox/std/test/tests.cpp +++ b/deps/ox/src/ox/std/test/tests.cpp @@ -20,8 +20,8 @@ static std::map tests = { ox::heapmgr::initHeap(&buff[0], &buff[buff.size()-1]); auto a1 = static_cast(ox::heapmgr::malloc(5)); auto a2 = static_cast(ox::heapmgr::malloc(5)); - oxAssert(a1 >= &buff.front().value && a1 < &buff.back().value, "malloc is broken"); - oxAssert(a2 >= &buff.front().value && a2 < &buff.back().value && a2 > a1 + 5, "malloc is broken"); + oxAssert(a1 >= buff.front().unwrap() && a1 < buff.back().unwrap(), "malloc is broken"); + oxAssert(a2 >= buff.front().unwrap() && a2 < buff.back().unwrap() && a2 > a1 + 5, "malloc is broken"); return OxError(0); } }, diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index a00a3073..8e029e41 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2022 gary@drinkingtea.net + * Copyright 2015 - 2023 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -31,7 +31,7 @@ struct VectorAllocator { private: ox::Array, Size> m_data = {}; Allocator m_allocator; - public: + protected: constexpr VectorAllocator() noexcept = default; constexpr VectorAllocator(const VectorAllocator&) noexcept = default; constexpr VectorAllocator(VectorAllocator&&) noexcept = default; @@ -45,7 +45,11 @@ 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 <= m_data.size() && count <= m_data.size()) { @@ -58,7 +62,11 @@ 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 <= m_data.size() && count <= m_data.size()) { @@ -84,7 +92,7 @@ template struct VectorAllocator { private: Allocator m_allocator; - public: + protected: constexpr VectorAllocator() noexcept = default; constexpr VectorAllocator(const VectorAllocator&) noexcept = default; constexpr VectorAllocator(VectorAllocator&&) noexcept = default; @@ -94,7 +102,11 @@ struct VectorAllocator { } [[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]] @@ -310,16 +322,16 @@ class Vector: detail::VectorAllocator { constexpr const T &operator[](std::size_t i) const noexcept; [[nodiscard]] - Result front() noexcept; + constexpr Result front() noexcept; [[nodiscard]] - Result front() const noexcept; + constexpr Result front() const noexcept; [[nodiscard]] - constexpr Result back() noexcept; + constexpr Result back() noexcept; [[nodiscard]] - constexpr Result back() const noexcept; + constexpr Result back() const noexcept; [[nodiscard]] constexpr std::size_t size() const noexcept; @@ -382,13 +394,18 @@ class Vector: detail::VectorAllocator { constexpr void reserve(std::size_t cap); + private: + constexpr void reserveInsert(std::size_t cap, std::size_t pos, std::size_t offset = 1); + }; template using VectorIt = typename Vector::template iterator; template -constexpr VectorIt operator+(std::size_t n, const VectorIt &a) { +constexpr VectorIt operator+( + std::size_t n, + const VectorIt &a) { return a + n; } @@ -451,7 +468,8 @@ constexpr bool Vector::operator==(const Vector &o } template -constexpr Vector &Vector::operator=(const Vector &other) { +constexpr Vector &Vector::operator=( + const Vector &other) { if (this != &other) { clear(); this->deallocate(m_items, m_cap); @@ -467,7 +485,8 @@ constexpr Vector &Vector -constexpr Vector &Vector::operator=(Vector &&other) noexcept { +constexpr Vector &Vector::operator=( + Vector &&other) noexcept { if (this != &other) { clear(); this->deallocate(m_items, m_cap); @@ -493,39 +512,35 @@ constexpr const T &Vector::operator[](std::size_t } template -Result Vector::front() noexcept { +constexpr Result Vector::front() noexcept { if (!m_size) { - AllocAlias v; - return {*reinterpret_cast(&v), OxError(1)}; + return {nullptr, OxError(1)}; } - return m_items[0]; + return &m_items[0]; } template -Result Vector::front() const noexcept { +constexpr Result Vector::front() const noexcept { if (!m_size) { - AllocAlias v; - return {*reinterpret_cast(&v), OxError(1)}; + return {nullptr, OxError(1)}; } - return m_items[0]; + return &m_items[0]; } template -constexpr Result Vector::back() noexcept { +constexpr Result Vector::back() noexcept { if (!m_size) { - AllocAlias v; - return {*reinterpret_cast(&v), OxError(1)}; + return {nullptr, OxError(1)}; } - return m_items[m_size - 1]; + return &m_items[m_size - 1]; } template -constexpr Result Vector::back() const noexcept { +constexpr Result Vector::back() const noexcept { if (!m_size) { - AllocAlias v; - return {*reinterpret_cast(&v), OxError(1)}; + return {nullptr, OxError(1)}; } - return m_items[m_size - 1]; + return &m_items[m_size - 1]; } template @@ -578,18 +593,25 @@ constexpr bool Vector::contains(const T &v) const template constexpr typename Vector::template iterator<> Vector::insert(std::size_t pos, std::size_t cnt, const T &val) { - // TODO: insert should ideally have its own reserve if (m_size + cnt > m_cap) { - reserve(m_cap ? m_size + cnt : initialSize); - } - if (pos < m_size) { - for (auto i = m_size + cnt - 1; i > pos; --i) { - std::construct_at(&m_items[i], std::move(m_items[i - cnt])); + reserveInsert(m_cap ? m_size + cnt : initialSize, pos, cnt); + if (pos < m_size) { + m_items[pos] = val; + } else { + for (auto i = 0u; i < cnt; ++i) { + std::construct_at(&m_items[pos + i], val); + } } - m_items[pos] = val; } else { - for (auto i = 0u; i < cnt; ++i) { - std::construct_at(&m_items[pos + i], val); + if (pos < m_size) { + for (auto i = m_size + cnt - 1; i > pos; --i) { + std::construct_at(&m_items[i], std::move(m_items[i - cnt])); + } + m_items[pos] = val; + } else { + for (auto i = 0u; i < cnt; ++i) { + std::construct_at(&m_items[pos + i], val); + } } } ++m_size; @@ -599,17 +621,22 @@ Vector::insert(std::size_t pos, std::size_t cnt, template constexpr typename Vector::template iterator<> Vector::insert(std::size_t pos, const T &val) { - // TODO: insert should ideally have its own reserve if (m_size == m_cap) { - reserve(m_cap ? m_cap * 2 : initialSize); - } - if (pos < m_size) { - for (auto i = m_size; i > pos; --i) { - std::construct_at(&m_items[i], std::move(m_items[i - 1])); + reserveInsert(m_cap ? m_cap * 2 : initialSize, pos); + if (pos < m_size) { + m_items[pos] = val; + } else { + std::construct_at(&m_items[pos], val); } - m_items[pos] = val; } else { - std::construct_at(&m_items[pos], val); + if (pos < m_size) { + for (auto i = m_size; i > pos; --i) { + std::construct_at(&m_items[i], std::move(m_items[i - 1])); + } + m_items[pos] = val; + } else { + std::construct_at(&m_items[pos], val); + } } ++m_size; return begin() + pos; @@ -619,17 +646,21 @@ template template constexpr typename Vector::template iterator<> Vector::emplace(std::size_t pos, Args&&... args) { - // TODO: insert should ideally have its own reserve if (m_size == m_cap) { - reserve(m_cap ? m_cap * 2 : initialSize); - } - if (pos < m_size) { - for (auto i = m_size; i > pos; --i) { - std::construct_at(&m_items[i], std::move(m_items[i - 1])); + reserveInsert(m_cap ? m_cap * 2 : initialSize); + if (pos < m_size) { + m_items[pos].~T(); } - m_items[pos].~T(); + std::construct_at(&m_items[pos], ox::forward(args)...); + } else { + if (pos < m_size) { + for (auto i = m_size; i > pos; --i) { + std::construct_at(&m_items[i], std::move(m_items[i - 1])); + } + m_items[pos].~T(); + } + std::construct_at(&m_items[pos], ox::forward(args)...); } - std::construct_at(&m_items[pos], ox::forward(args)...); ++m_size; return begin() + pos; } @@ -661,12 +692,14 @@ constexpr void Vector::pop_back() { } template -constexpr Result::template iterator> Vector::erase(const iterator<> &pos) { +constexpr Result::template iterator> +Vector::erase(const iterator<> &pos) { return erase(pos.offset()); } template -constexpr Result::template iterator> Vector::erase(std::size_t pos) { +constexpr Result::template iterator> +Vector::erase(std::size_t pos) { if (pos >= m_size) { return OxError(1, "Vector::erase failed: pos is greater than Vector size"); } @@ -708,6 +741,33 @@ constexpr void Vector::reserve(std::size_t cap) { } } +template +constexpr void Vector::reserveInsert( + std::size_t cap, + std::size_t pos, + std::size_t offset) { + if (cap <= m_cap) { + return; + } + const auto oldItems = m_items; + const auto oldCap = m_cap; + m_cap = cap; + this->allocate(&m_items, cap); + if (oldItems) { // move over old items + auto itRange = ox::min(m_size, pos); + for (std::size_t i = 0; i < itRange; ++i) { + std::construct_at(&m_items[i], std::move(oldItems[i])); + oldItems[i].~T(); + } + itRange = m_size; + for (std::size_t i = pos; i < itRange; ++i) { + std::construct_at(&m_items[i + offset], std::move(oldItems[i])); + oldItems[i].~T(); + } + this->deallocate(oldItems, oldCap); + } +} + template [[nodiscard]]