From 206b2825c80a5b29246d695844c3801125b5e612 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 16 Sep 2023 18:32:06 -0500 Subject: [PATCH] [ox/std] Add Span type --- deps/ox/src/ox/std/array.hpp | 106 +------------------------ deps/ox/src/ox/std/iterator.hpp | 116 ++++++++++++++++++++++++++- deps/ox/src/ox/std/span.hpp | 134 ++++++++++++++++++++++++++++++++ deps/ox/src/ox/std/vector.hpp | 103 +----------------------- 4 files changed, 252 insertions(+), 207 deletions(-) create mode 100644 deps/ox/src/ox/std/span.hpp diff --git a/deps/ox/src/ox/std/array.hpp b/deps/ox/src/ox/std/array.hpp index dd49009f..1e0cc469 100644 --- a/deps/ox/src/ox/std/array.hpp +++ b/deps/ox/src/ox/std/array.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 @@ -28,109 +28,7 @@ class Array { using size_type = std::size_t; template - struct iterator: public 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 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; - } - - }; + using iterator = SpanIterator; private: T m_items[ArraySize]{}; diff --git a/deps/ox/src/ox/std/iterator.hpp b/deps/ox/src/ox/std/iterator.hpp index 917a84f0..4a32d450 100644 --- a/deps/ox/src/ox/std/iterator.hpp +++ b/deps/ox/src/ox/std/iterator.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 @@ -8,6 +8,8 @@ #pragma once +#include "math.hpp" + #if !__has_include() #include "stddef.hpp" @@ -48,4 +50,116 @@ struct Iterator { using difference_type = DiffType; }; + +template +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(m_offset - s, 0), m_max); + } else { + return SpanIterator(m_t, min(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(m_offset + s, m_max), m_max); + } else { + return SpanIterator(m_t, max(m_offset - s, 0), m_max); + } + } + + constexpr SpanIterator &operator+=(std::size_t s) noexcept { + if constexpr(reverse) { + m_offset = max(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(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; + } + +}; + } diff --git a/deps/ox/src/ox/std/span.hpp b/deps/ox/src/ox/std/span.hpp new file mode 100644 index 00000000..d317e969 --- /dev/null +++ b/deps/ox/src/ox/std/span.hpp @@ -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 +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 + using iterator = SpanIterator; + + template + constexpr Span(ox::Array const&a) noexcept: + m_items(a.data()), + m_size(a.size()) { + } + + template + constexpr Span(ox::Vector const&v) noexcept: + m_items(v.data()), + m_size(v.size()) { + } + + template + 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 begin() const noexcept { + return iterator(m_items, 0, m_size); + } + + [[nodiscard]] + constexpr iterator end() const noexcept { + return iterator(m_items, m_size, m_size); + } + + [[nodiscard]] + constexpr iterator cbegin() const noexcept { + return iterator(m_items, 0, m_size); + } + + [[nodiscard]] + constexpr iterator cend() const noexcept { + return iterator(m_items, m_size, m_size); + } + + [[nodiscard]] + constexpr iterator rbegin() noexcept { + return iterator(m_items, m_size - 1, m_size); + } + + [[nodiscard]] + constexpr iterator rend() noexcept { + return iterator(m_items, MaxValue, m_size); + } + + [[nodiscard]] + constexpr iterator crbegin() const noexcept { + return iterator(m_items, m_size - 1, m_size); + } + + [[nodiscard]] + constexpr iterator crend() const noexcept { + return iterator(m_items, MaxValue, m_size); + } + + [[nodiscard]] + constexpr iterator rbegin() const noexcept { + return iterator(m_items, m_size - 1, m_size); + } + + [[nodiscard]] + constexpr iterator rend() const noexcept { + return iterator(m_items, MaxValue, 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; + } + +}; + +} diff --git a/deps/ox/src/ox/std/vector.hpp b/deps/ox/src/ox/std/vector.hpp index e51c1dc0..69bfbc49 100644 --- a/deps/ox/src/ox/std/vector.hpp +++ b/deps/ox/src/ox/std/vector.hpp @@ -131,108 +131,7 @@ class Vector: detail::VectorAllocator { using size_type = std::size_t; template - struct iterator: public 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 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(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; - } - - }; + using iterator = SpanIterator; private: static constexpr auto initialCap = SmallVectorSize > 0 ? SmallVectorSize : 50;