[ox/std] Add Span type
This commit is contained in:
parent
b6f86551e9
commit
206b2825c8
106
deps/ox/src/ox/std/array.hpp
vendored
106
deps/ox/src/ox/std/array.hpp
vendored
@ -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
|
* 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
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@ -28,109 +28,7 @@ class Array {
|
|||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
|
||||||
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
||||||
struct iterator: public Iterator<std::bidirectional_iterator_tag, T> {
|
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
|
||||||
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<size_type>(m_offset - s, 0), m_max);
|
|
||||||
} else {
|
|
||||||
return iterator(m_t, min<size_type>(m_offset + s, m_max), m_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr typename 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);
|
|
||||||
} else {
|
|
||||||
return iterator(m_t, max<size_type>(m_offset - s, 0), m_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator &operator+=(size_type s) noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
m_offset = max<size_type>(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<size_type>(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:
|
private:
|
||||||
T m_items[ArraySize]{};
|
T m_items[ArraySize]{};
|
||||||
|
116
deps/ox/src/ox/std/iterator.hpp
vendored
116
deps/ox/src/ox/std/iterator.hpp
vendored
@ -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
|
* 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
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "math.hpp"
|
||||||
|
|
||||||
#if !__has_include(<iterator>)
|
#if !__has_include(<iterator>)
|
||||||
#include "stddef.hpp"
|
#include "stddef.hpp"
|
||||||
|
|
||||||
@ -48,4 +50,116 @@ struct Iterator {
|
|||||||
using difference_type = DiffType;
|
using difference_type = DiffType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename RefType, typename PtrType, bool reverse = false>
|
||||||
|
struct SpanIterator {
|
||||||
|
public:
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using value_type = T;
|
||||||
|
using pointer = T*;
|
||||||
|
using reference = T&;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PtrType m_t = nullptr;
|
||||||
|
std::size_t m_offset = 0;
|
||||||
|
std::size_t m_max = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr SpanIterator() noexcept = default;
|
||||||
|
|
||||||
|
constexpr SpanIterator(PtrType t, std::size_t offset, std::size_t max) noexcept:
|
||||||
|
m_t(t),
|
||||||
|
m_offset(offset),
|
||||||
|
m_max(max) {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto offset() const noexcept {
|
||||||
|
return m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SpanIterator operator+(std::size_t s) const noexcept {
|
||||||
|
if constexpr(reverse) {
|
||||||
|
return SpanIterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
||||||
|
} else {
|
||||||
|
return SpanIterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto operator-(const SpanIterator &other) const noexcept {
|
||||||
|
if constexpr(reverse) {
|
||||||
|
return m_offset + other.m_offset;
|
||||||
|
} else {
|
||||||
|
return m_offset - other.m_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SpanIterator operator-(std::size_t s) const noexcept {
|
||||||
|
if constexpr(reverse) {
|
||||||
|
return SpanIterator(m_t, min<std::size_t>(m_offset + s, m_max), m_max);
|
||||||
|
} else {
|
||||||
|
return SpanIterator(m_t, max<std::size_t>(m_offset - s, 0), m_max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SpanIterator &operator+=(std::size_t s) noexcept {
|
||||||
|
if constexpr(reverse) {
|
||||||
|
m_offset = max<std::size_t>(m_offset - s, 0);
|
||||||
|
} else {
|
||||||
|
m_offset = min(m_offset + s, m_max);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SpanIterator &operator-=(std::size_t s) noexcept {
|
||||||
|
if constexpr(reverse) {
|
||||||
|
m_offset = min(m_offset + s, m_max);
|
||||||
|
} else {
|
||||||
|
m_offset = max<std::size_t>(m_offset - s, 0);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SpanIterator &operator++() noexcept {
|
||||||
|
return operator+=(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr SpanIterator &operator--() noexcept {
|
||||||
|
return operator-=(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr RefType operator*() const noexcept {
|
||||||
|
return m_t[m_offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr RefType operator[](std::size_t s) const noexcept {
|
||||||
|
return m_t[s];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator<(const SpanIterator &other) const noexcept {
|
||||||
|
return m_offset < other.m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator>(const SpanIterator &other) const noexcept {
|
||||||
|
return m_offset > other.m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator<=(const SpanIterator &other) const noexcept {
|
||||||
|
return m_offset <= other.m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator>=(const SpanIterator &other) const noexcept {
|
||||||
|
return m_offset >= other.m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator==(const SpanIterator &other) const noexcept {
|
||||||
|
return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator!=(const SpanIterator &other) const noexcept {
|
||||||
|
return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
134
deps/ox/src/ox/std/span.hpp
vendored
Normal file
134
deps/ox/src/ox/std/span.hpp
vendored
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "bit.hpp"
|
||||||
|
#include "iterator.hpp"
|
||||||
|
#include "typetraits.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
#include "vector.hpp"
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Span {
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T *m_items{};
|
||||||
|
const std::size_t m_size{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
|
||||||
|
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
||||||
|
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
|
||||||
|
|
||||||
|
template<std::size_t sz>
|
||||||
|
constexpr Span(ox::Array<T, sz> const&a) noexcept:
|
||||||
|
m_items(a.data()),
|
||||||
|
m_size(a.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t sz>
|
||||||
|
constexpr Span(ox::Vector<T, sz> const&v) noexcept:
|
||||||
|
m_items(v.data()),
|
||||||
|
m_size(v.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t sz>
|
||||||
|
constexpr Span(const T a[sz]) noexcept:
|
||||||
|
m_items(a),
|
||||||
|
m_size(sz) {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr Span(const T *a, std::size_t sz) noexcept:
|
||||||
|
m_items(a),
|
||||||
|
m_size(sz) {
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr iterator<> begin() noexcept {
|
||||||
|
return iterator<>(m_items, 0, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr iterator<> end() noexcept {
|
||||||
|
return iterator<>(m_items, m_size, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*> begin() const noexcept {
|
||||||
|
return iterator<const T&, const T*>(m_items, 0, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*> end() const noexcept {
|
||||||
|
return iterator<const T&, const T*>(m_items, m_size, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*> cbegin() const noexcept {
|
||||||
|
return iterator<const T&, const T*>(m_items, 0, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*> cend() const noexcept {
|
||||||
|
return iterator<const T&, const T*>(m_items, m_size, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<T&, T*, true> rbegin() noexcept {
|
||||||
|
return iterator<T&, T*, true>(m_items, m_size - 1, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<T&, T*, true> rend() noexcept {
|
||||||
|
return iterator<T&, T*, true>(m_items, MaxValue<size_type>, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*, true> crbegin() const noexcept {
|
||||||
|
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*, true> crend() const noexcept {
|
||||||
|
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*, true> rbegin() const noexcept {
|
||||||
|
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr iterator<const T&, const T*, true> rend() const noexcept {
|
||||||
|
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr T &operator[](std::size_t i) noexcept {
|
||||||
|
return m_items[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const T &operator[](std::size_t i) const noexcept {
|
||||||
|
return m_items[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr std::size_t size() const noexcept {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
constexpr bool empty() const noexcept {
|
||||||
|
return m_size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
103
deps/ox/src/ox/std/vector.hpp
vendored
103
deps/ox/src/ox/std/vector.hpp
vendored
@ -131,108 +131,7 @@ class Vector: detail::VectorAllocator<T, Allocator, SmallVectorSize> {
|
|||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
|
||||||
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
||||||
struct iterator: public Iterator<std::bidirectional_iterator_tag, T> {
|
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
|
||||||
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<size_type>(m_offset - s, 0), m_max);
|
|
||||||
} else {
|
|
||||||
return iterator(m_t, min<size_type>(m_offset + s, m_max), m_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr auto 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);
|
|
||||||
} else {
|
|
||||||
return iterator(m_t, max<size_type>(m_offset - s, 0), m_max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr iterator &operator+=(size_type s) noexcept {
|
|
||||||
if constexpr(reverse) {
|
|
||||||
m_offset = max<size_type>(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<size_type>(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:
|
private:
|
||||||
static constexpr auto initialCap = SmallVectorSize > 0 ? SmallVectorSize : 50;
|
static constexpr auto initialCap = SmallVectorSize > 0 ? SmallVectorSize : 50;
|
||||||
|
Loading…
Reference in New Issue
Block a user