[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 #pragma once
#ifndef OX_USE_STDLIB #ifndef OX_USE_STDLIB
#include "types.hpp"
namespace std { namespace std {
struct input_iterator_tag { 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 { 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 { struct iterator {
using iterator_category = Category; using iterator_category = Category;
using value_type = T; using value_type = T;
using pointer = T*; using pointer = T*;
using reference = 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(uint32_t) == 4, "uint32_t is wrong size");
static_assert(sizeof(uint64_t) == 8, "uint64_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"); 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; m_max = max;
} }
constexpr auto offset() const noexcept {
return m_offset;
}
constexpr iterator operator+(size_type s) const noexcept { constexpr iterator operator+(size_type s) const noexcept {
if constexpr(reverse) { if constexpr(reverse) {
return iterator(m_t, max<size_type>(m_offset - s, 0), m_max); 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 { constexpr iterator operator-(size_type s) const noexcept {
if constexpr(reverse) { if constexpr(reverse) {
return iterator(m_t, min<size_type>(m_offset + s, m_max), m_max); 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; explicit Vector(std::size_t size) noexcept;
#if __has_include(<initializer_list>)
Vector(std::initializer_list<T> list) noexcept; Vector(std::initializer_list<T> list) noexcept;
#endif
Vector(const Vector &other); Vector(const Vector &other);
@ -279,6 +290,14 @@ class Vector: detail::SmallVector<T, SmallVectorSize> {
void pop_back(); 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. * Removes an item from the Vector.
* @param pos position of item to remove * @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> template<typename T, std::size_t SmallVectorSize>
Vector<T, SmallVectorSize>::Vector(std::size_t size) noexcept { Vector<T, SmallVectorSize>::Vector(std::size_t size) noexcept {
m_size = size; m_size = size;
@ -522,6 +549,12 @@ void Vector<T, SmallVectorSize>::pop_back() {
m_items[m_size].~T(); 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> template<typename T, std::size_t SmallVectorSize>
Error Vector<T, SmallVectorSize>::erase(std::size_t pos) { Error Vector<T, SmallVectorSize>::erase(std::size_t pos) {
if (pos >= m_size) { 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++) { for (std::size_t i = 0; i < itRange; i++) {
m_items[i] = move(oldItems[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)); this->clearItems(bit_cast<AllocAlias<T>*>(oldItems));
} }
} }