11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
18PROMEKI_NAMESPACE_BEGIN
21template <
typename T>
class List;
22template <
typename T,
size_t N>
class Array;
41template <
typename T>
class Span {
44 using Iterator =
typename std::span<T>::iterator;
47 using ConstIterator =
typename std::span<const T>::iterator;
50 using RevIterator =
typename std::span<T>::reverse_iterator;
53 using ConstRevIterator =
typename std::span<const T>::reverse_iterator;
63 Span(T *ptr,
size_t count) : d(ptr, count) {}
69 Span(List<T> &list) : d(list.data(), list.size()) {}
76 template <
size_t N> Span(T (&arr)[N]) : d(arr, N) {}
83 template <
size_t N> Span(Array<T, N> &arr) : d(arr.data(), N) {}
86 Span(
const Span &other) =
default;
89 Span &operator=(
const Span &other) =
default;
99 template <
typename U,
typename = std::enable_if_t<std::is_convertible_v<U (*)[], T (*)[]>>>
100 Span(
const Span<U> &other) : d(other.data(), other.size()) {}
105 Iterator begin() noexcept {
return d.begin(); }
108 ConstIterator begin() const noexcept {
return std::span<const T>(d.data(), d.size()).begin(); }
111 Iterator end() noexcept {
return d.end(); }
114 ConstIterator end() const noexcept {
return std::span<const T>(d.data(), d.size()).end(); }
117 ConstIterator constBegin() const noexcept {
return begin(); }
120 ConstIterator constEnd() const noexcept {
return end(); }
123 RevIterator rbegin() noexcept {
return d.rbegin(); }
126 RevIterator revBegin() noexcept {
return d.rbegin(); }
129 RevIterator rend() noexcept {
return d.rend(); }
132 RevIterator revEnd() noexcept {
return d.rend(); }
135 ConstRevIterator crbegin() const noexcept {
return std::span<const T>(d.data(), d.size()).rbegin(); }
138 ConstRevIterator constRevBegin() const noexcept {
return crbegin(); }
141 ConstRevIterator crend() const noexcept {
return std::span<const T>(d.data(), d.size()).rend(); }
144 ConstRevIterator constRevEnd() const noexcept {
return crend(); }
153 T &operator[](
size_t index) {
return d[index]; }
156 const T &operator[](
size_t index)
const {
return d[index]; }
159 T &front() {
return d.front(); }
162 const T &front()
const {
return d.front(); }
165 T &back() {
return d.back(); }
168 const T &back()
const {
return d.back(); }
171 T *data() noexcept {
return d.data(); }
174 const T *data() const noexcept {
return d.data(); }
179 bool isEmpty() const noexcept {
return d.empty(); }
182 size_t size() const noexcept {
return d.size(); }
185 size_t sizeBytes() const noexcept {
return d.size_bytes(); }
195 Span subspan(
size_t offset,
size_t count)
const {
return Span(d.data() + offset, count); }
202 Span first(
size_t count)
const {
return Span(d.data(), count); }
209 Span last(
size_t count)
const {
return Span(d.data() + d.size() - count, count); }
218 template <
typename Func>
void forEach(Func &&func)
const {
219 for (
size_t i = 0; i < d.size(); ++i) func(d[i]);