diff --git a/deps/ox/src/ox/std/array.hpp b/deps/ox/src/ox/std/array.hpp new file mode 100644 index 00000000..ed24782f --- /dev/null +++ b/deps/ox/src/ox/std/array.hpp @@ -0,0 +1,369 @@ +/* + * Copyright 2015 - 2022 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 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "bit.hpp" +#include "error.hpp" +#include "initializerlist.hpp" +#include "iterator.hpp" +#include "math.hpp" +#include "memory.hpp" +#include "new.hpp" +#include "types.hpp" +#include "utility.hpp" + +namespace ox { + +template +class Array { + + public: + using value_type = T; + using size_type = std::size_t; + + template + struct iterator: public std::iterator { + private: + PtrType m_t = nullptr; + size_type m_offset = 0; + size_type m_max = 0; + + public: + constexpr iterator() noexcept = default; + + constexpr iterator(PtrType t, size_type offset, size_type max) noexcept { + m_t = t; + m_offset = offset; + m_max = max; + } + + constexpr auto offset() const noexcept { + return m_offset; + } + + constexpr iterator operator+(size_type s) const noexcept { + if constexpr(reverse) { + return iterator(m_t, max(m_offset - s, 0), m_max); + } else { + return iterator(m_t, min(m_offset + s, m_max), m_max); + } + } + + constexpr typename std::iterator::difference_type + operator-(const iterator &other) const noexcept { + if constexpr(reverse) { + return m_offset + other.m_offset; + } else { + return m_offset - other.m_offset; + } + } + + constexpr iterator operator-(size_type s) const noexcept { + if constexpr(reverse) { + return iterator(m_t, min(m_offset + s, m_max), m_max); + } else { + return iterator(m_t, max(m_offset - s, 0), m_max); + } + } + + constexpr iterator &operator+=(size_type s) noexcept { + if constexpr(reverse) { + m_offset = max(m_offset - s, 0); + } else { + m_offset = min(m_offset + s, m_max); + } + return *this; + } + + constexpr iterator &operator-=(size_type s) noexcept { + if constexpr(reverse) { + m_offset = min(m_offset + s, m_max); + } else { + m_offset = max(m_offset - s, 0); + } + return *this; + } + + constexpr iterator &operator++() noexcept { + return operator+=(1); + } + + constexpr iterator &operator--() noexcept { + return operator-=(1); + } + + constexpr RefType operator*() const noexcept { + return m_t[m_offset]; + } + + constexpr RefType operator[](size_type s) const noexcept { + return m_t[s]; + } + + constexpr bool operator<(const iterator &other) const noexcept { + return m_offset < other.m_offset; + } + + constexpr bool operator>(const iterator &other) const noexcept { + return m_offset > other.m_offset; + } + + constexpr bool operator<=(const iterator &other) const noexcept { + return m_offset <= other.m_offset; + } + + constexpr bool operator>=(const iterator &other) const noexcept { + return m_offset >= other.m_offset; + } + + constexpr bool operator==(const iterator &other) const noexcept { + return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max; + } + + constexpr bool operator!=(const iterator &other) const noexcept { + return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max; + } + + }; + + private: + T m_items[ArraySize]; + + public: + constexpr Array() noexcept = default; + + explicit constexpr Array(std::size_t size) noexcept; + + constexpr Array(std::initializer_list list) noexcept; + + constexpr Array(const Array &other); + + constexpr Array(Array &&other) noexcept; + + ~Array(); + + constexpr iterator<> begin() noexcept { + return iterator<>(&m_items[0], 0, ArraySize); + } + + constexpr iterator<> end() noexcept { + return iterator<>(&m_items[0], ArraySize, ArraySize); + } + + constexpr iterator begin() const noexcept { + return iterator(&m_items[0], 0, ArraySize); + } + + constexpr iterator end() const noexcept { + return iterator(&m_items[0], ArraySize, ArraySize); + } + + constexpr iterator rbegin() noexcept { + return iterator(&m_items[0], ArraySize - 1, ArraySize); + } + + constexpr iterator rend() noexcept { + return iterator(&m_items[0], MaxValue, ArraySize); + } + + constexpr iterator rbegin() const noexcept { + return iterator(m_items, ArraySize - 1, ArraySize); + } + + constexpr iterator rend() const noexcept { + return iterator(m_items, MaxValue, ArraySize); + } + + constexpr bool operator==(const Array &other) const; + + constexpr Array &operator=(const Array &other); + + constexpr Array &operator=(Array &&other) noexcept; + + constexpr T &operator[](std::size_t i) noexcept; + + constexpr const T &operator[](std::size_t i) const noexcept; + + Result front() noexcept; + + Result front() const noexcept; + + Result back() noexcept; + + Result back() const noexcept; + + [[nodiscard]] + constexpr std::size_t size() const noexcept; + + [[nodiscard]] + constexpr bool empty() const noexcept; + + constexpr void clear(); + + constexpr void resize(std::size_t size); + + [[nodiscard]] + constexpr T *data() noexcept { + return m_items; + } + + [[nodiscard]] + constexpr const T *data() const noexcept { + return m_items; + } + + [[nodiscard]] + constexpr bool contains(const T&) const; + + constexpr void insert(std::size_t pos, const T &val); + + template + constexpr T &emplace_back(Args&&... args); + + constexpr void push_back(const T &item); + + constexpr void pop_back(); + + /** + * Removes an item from the Array. + * @param pos iterator at the point to remove + * @return Error if index is out of bounds + */ + constexpr Result> erase(const iterator<> &pos); + + /** + * Removes an item from the Array. + * @param pos position of item to remove + * @return Error if index is out of bounds + */ + constexpr Result> erase(std::size_t pos); + + /** + * Moves the last item in the Array to position pos and decrements the + * size by 1. + * @param pos position of item to remove + * @return Error if index is out of bounds + */ + constexpr Error unordered_erase(std::size_t pos); + + private: + constexpr void expandCap(std::size_t cap); + +}; + +template +using ArrayIt = typename Array::template iterator; + +template +constexpr ArrayIt operator+(std::size_t n, const ArrayIt &a) { + return a + n; +} + +template +constexpr Array::Array(std::size_t size) noexcept { + for (std::size_t i = 0; i < size; ++i) { + m_items[i] = {}; + } +} + +template +constexpr Array::Array(std::initializer_list list) noexcept { + for (auto &item : list) { + emplace_back(item); + } +} + +template +constexpr Array::Array(const Array &other) { + for (std::size_t i = 0; i < ArraySize; ++i) { + new (&m_items[i]) T(other.m_items[i]); + } +} + +template +constexpr Array::Array(Array &&other) noexcept { + if (this != &other) { + for (std::size_t i = 0; i < ArraySize; ++i) { + new (&m_items[i]) T(std::move(other.m_items[i])); + } + } +} + +template +Array::~Array() { +} + +template +constexpr bool Array::operator==(const Array &other) const { + for (std::size_t i = 0; i < ArraySize; i++) { + if (!(m_items[i] == other.m_items[i])) { + return false; + } + } + return true; +} + +template +constexpr Array &Array::operator=(const Array &other) { + if (this != &other) { + for (std::size_t i = 0; i < ArraySize; ++i) { + m_items[i] = other.m_items[i]; + } + } + return *this; + return *this; +} + +template +constexpr Array &Array::operator=(Array &&other) noexcept { + if (this != &other) { + for (std::size_t i = 0; i < ArraySize; ++i) { + m_items[i] = std::move(other.m_items[i]); + } + } + return *this; +} + +template +constexpr T &Array::operator[](std::size_t i) noexcept { + return m_items[i]; +} + +template +constexpr const T &Array::operator[](std::size_t i) const noexcept { + return m_items[i]; +} + +template +constexpr std::size_t Array::size() const noexcept { + return ArraySize; +} + +template +constexpr bool Array::contains(const T &v) const { + for (std::size_t i = 0; i < ArraySize; i++) { + if (m_items[i] == v) { + return true; + } + } + return false; +} + +template +constexpr void Array::expandCap(std::size_t cap) { + auto oldItems = m_items; + if (oldItems) { // move over old items + const auto itRange = ox::min(cap, ArraySize); + for (std::size_t i = 0; i < itRange; ++i) { + new (&m_items[i]) T(std::move(oldItems[i])); + } + } +} + +} diff --git a/deps/ox/src/ox/std/std.hpp b/deps/ox/src/ox/std/std.hpp index 02fa07b1..82e50bdd 100644 --- a/deps/ox/src/ox/std/std.hpp +++ b/deps/ox/src/ox/std/std.hpp @@ -8,6 +8,7 @@ #pragma once +#include "array.hpp" #include "assert.hpp" #include "bit.hpp" #include "bstring.hpp" diff --git a/deps/ox/src/ox/std/string.hpp b/deps/ox/src/ox/std/string.hpp index 07ad0958..c856b317 100644 --- a/deps/ox/src/ox/std/string.hpp +++ b/deps/ox/src/ox/std/string.hpp @@ -52,12 +52,12 @@ class BasicString { [[nodiscard]] constexpr auto cbegin() const noexcept { - return m_buff.cbegin(); + return m_buff.begin(); } [[nodiscard]] constexpr auto cend() const noexcept { - return m_buff.cend(); + return m_buff.end(); } [[nodiscard]] @@ -72,12 +72,12 @@ class BasicString { [[nodiscard]] constexpr auto crbegin() const noexcept { - return m_buff.crbegin(); + return m_buff.rbegin(); } [[nodiscard]] constexpr auto crend() const noexcept { - return m_buff.crend(); + return m_buff.rend(); } BasicString &operator=(const char *str) noexcept; diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index afcc0e55..dcbaa344 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -233,35 +233,35 @@ class Vector: detail::SmallVector { ~Vector(); - constexpr iterator<> begin() const noexcept { + constexpr iterator<> begin() noexcept { return iterator<>(m_items, 0, m_size); } - constexpr iterator<> end() const noexcept { + constexpr iterator<> end() noexcept { return iterator<>(m_items, m_size, m_size); } - constexpr iterator cbegin() const noexcept { + constexpr iterator begin() const noexcept { return iterator(m_items, 0, m_size); } - constexpr iterator cend() const noexcept { + constexpr iterator end() const noexcept { return iterator(m_items, m_size, m_size); } - constexpr iterator rbegin() const noexcept { + constexpr iterator rbegin() noexcept { return iterator(m_items, m_size - 1, m_size); } - constexpr iterator rend() const noexcept { + constexpr iterator rend() noexcept { return iterator(m_items, MaxValue, m_size); } - constexpr iterator crbegin() const noexcept { + constexpr iterator rbegin() const noexcept { return iterator(m_items, m_size - 1, m_size); } - constexpr iterator crend() const noexcept { + constexpr iterator rend() const noexcept { return iterator(m_items, MaxValue, m_size); }