2024-03-28 15:34:43 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <vector>
|
2024-03-31 15:42:05 +02:00
|
|
|
#include <array>
|
2024-03-28 15:34:43 +01:00
|
|
|
|
|
|
|
// non owning view
|
|
|
|
template<typename T>
|
2024-05-26 21:32:44 +02:00
|
|
|
struct Span {
|
2024-03-28 15:34:43 +01:00
|
|
|
const T* ptr {nullptr};
|
|
|
|
uint64_t size {0};
|
|
|
|
|
2024-03-31 15:42:05 +02:00
|
|
|
constexpr Span(const Span&) = default;
|
|
|
|
constexpr Span(Span&&) = default;
|
2024-03-28 15:34:43 +01:00
|
|
|
constexpr Span(void) {}
|
|
|
|
constexpr Span(const T* ptr_, uint64_t size_) : ptr(ptr_), size(size_) {}
|
2024-03-31 15:42:05 +02:00
|
|
|
constexpr Span(T* ptr_, uint64_t size_) : ptr(ptr_), size(size_) {}
|
2024-03-28 15:34:43 +01:00
|
|
|
constexpr explicit Span(const std::vector<T>& vec) : ptr(vec.data()), size(vec.size()) {}
|
2024-03-31 15:42:05 +02:00
|
|
|
constexpr explicit Span(std::vector<T>& vec) : ptr(vec.data()), size(vec.size()) {}
|
|
|
|
template<size_t N> constexpr explicit Span(const std::array<T, N>& arr) : ptr(arr.data()), size(arr.size()) {}
|
|
|
|
template<size_t N> constexpr explicit Span(std::array<T, N>& arr) : ptr(arr.data()), size(arr.size()) {}
|
|
|
|
|
|
|
|
Span& operator=(const Span& other) {
|
|
|
|
ptr = other.ptr;
|
|
|
|
size = other.size;
|
|
|
|
return *this;
|
|
|
|
}
|
2024-03-28 15:34:43 +01:00
|
|
|
|
|
|
|
explicit operator std::vector<T>() const {
|
|
|
|
return std::vector<T>{ptr, ptr+size};
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr const T& operator[](uint64_t i) const {
|
|
|
|
if (i > size) {
|
|
|
|
throw std::out_of_range("accessed span out of range");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ptr[i];
|
|
|
|
}
|
|
|
|
|
2024-04-10 13:26:54 +02:00
|
|
|
constexpr bool operator==(const Span& other) const {
|
|
|
|
if (empty() || size != other.size) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < size; i++) {
|
|
|
|
if ((*this)[i] != other[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-03-31 15:42:05 +02:00
|
|
|
#if 0
|
|
|
|
constexpr T& operator[](uint64_t i) {
|
|
|
|
if (i > size) {
|
|
|
|
throw std::out_of_range("accessed span out of range");
|
|
|
|
}
|
|
|
|
|
|
|
|
return ptr[i];
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-03-28 15:34:43 +01:00
|
|
|
constexpr const T* cbegin(void) const { return ptr; }
|
|
|
|
constexpr const T* cend(void) const { return ptr+size; }
|
|
|
|
constexpr const T* begin(void) const { return ptr; }
|
|
|
|
constexpr const T* end(void) const { return ptr+size; }
|
|
|
|
|
|
|
|
constexpr bool empty(void) const { return ptr == nullptr || size == 0; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// useful alias
|
|
|
|
using ByteSpan = Span<uint8_t>;
|
2024-03-31 15:42:05 +02:00
|
|
|
using ConstByteSpan = Span<const uint8_t>; // TODO: make use of?
|
2024-03-28 15:34:43 +01:00
|
|
|
|