[ox/std] Improve Vector::iterator to better conform to std::vector::iterator

This commit is contained in:
Gary Talent 2021-07-30 19:36:26 -05:00
parent 6165f63d09
commit 68f829ff2d
3 changed files with 46 additions and 6 deletions

View File

@ -9,6 +9,8 @@
#pragma once
#ifndef OX_USE_STDLIB
#include "types.hpp"
namespace std {
struct input_iterator_tag {
@ -29,12 +31,14 @@ struct random_access_iterator_tag: public bidirectional_iterator_tag {
struct contiguous_iterator_tag: public random_access_iterator_tag {
};
template<typename Category, typename T>
template<typename Category, typename T, typename DiffType = std::ptrdiff_t,
typename PointerType = T*, typename ReferenceType = T&>
struct iterator {
using iterator_category = Category;
using value_type = T;
using pointer = T*;
using reference = T&;
using difference_type = DiffType;
};
}

View File

@ -161,3 +161,9 @@ static_assert(sizeof(uint16_t) == 2, "uint16_t is wrong size");
static_assert(sizeof(uint32_t) == 4, "uint32_t is wrong size");
static_assert(sizeof(uint64_t) == 8, "uint64_t is wrong size");
static_assert(sizeof(uintptr_t) == sizeof(void*), "uintptr_t is wrong size");
#ifndef OX_USE_STDLIB
namespace std {
using ptrdiff_t = uintptr_t;
}
#endif

View File

@ -101,6 +101,10 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
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<size_type>(m_offset - s, 0), m_max);
@ -109,6 +113,15 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
}
}
constexpr typename std::iterator<std::bidirectional_iterator_tag, T>::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<size_type>(m_offset + s, m_max), m_max);
@ -187,9 +200,7 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
explicit Vector(std::size_t size) noexcept;
#if __has_include(<initializer_list>)
Vector(std::initializer_list<T> list) noexcept;
#endif
Vector(const Vector &other);
@ -279,6 +290,14 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
void pop_back();
/**
* Removes an item from the Vector.
* @param pos iterator at the point to remove
* @return Error if index is out of bounds
*/
template<typename RefType, bool reverse>
Error erase(const iterator<RefType, reverse> &pos);
/**
* Removes an item from the Vector.
* @param pos position of item to remove
@ -299,6 +318,14 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
};
template<typename T, std::size_t SmallVectorSize, typename RefType, bool reverse>
using VectorIt = typename Vector<T, SmallVectorSize>::template iterator<RefType, reverse>;
template<typename T, std::size_t SmallVectorSize, typename RefType, bool reverse>
VectorIt<T, SmallVectorSize, RefType, reverse> operator+(std::size_t n, const VectorIt<T, SmallVectorSize, RefType, reverse> &a) {
return a + n;
}
template<typename T, std::size_t SmallVectorSize>
Vector<T, SmallVectorSize>::Vector(std::size_t size) noexcept {
m_size = size;
@ -522,6 +549,12 @@ void Vector<T, SmallVectorSize>::pop_back() {
m_items[m_size].~T();
}
template<typename T, std::size_t SmallVectorSize>
template<typename RefType, bool reverse>
Error Vector<T, SmallVectorSize>::erase(const iterator<RefType, reverse> &pos) {
return erase(pos.offset());
}
template<typename T, std::size_t SmallVectorSize>
Error Vector<T, SmallVectorSize>::erase(std::size_t pos) {
if (pos >= m_size) {
@ -554,9 +587,6 @@ void Vector<T, SmallVectorSize>::expandCap(std::size_t cap) {
for (std::size_t i = 0; i < itRange; i++) {
m_items[i] = move(oldItems[i]);
}
for (std::size_t i = itRange; i < m_cap; i++) {
new (&m_items[i]) T;
}
this->clearItems(bit_cast<AllocAlias<T>*>(oldItems));
}
}