4#include "../Foundation/InitializerList.h"
5#include "../Foundation/LibC.h"
6#include "../Foundation/TypeTraits.h"
10template <
typename Type>
16template<
typename U>
struct SpanSizeOfType {
static constexpr auto size =
sizeof(U); };
17template<>
struct SpanSizeOfType<void> {
static constexpr auto size = 1; };
18template<>
struct SpanSizeOfType<const void> {
static constexpr auto size = 1; };
27template <
typename Type>
33 using VoidType =
typename TypeTraits::SameConstnessAs<Type, void>::type;
39 SizeType sizeElements;
42 template <
size_t N,
typename U = Type, EnableNotVo
id<U> = true>
43 constexpr Span(U (&itemsArray)[N]) : items(itemsArray), sizeElements(N)
47 constexpr Span() : items(nullptr), sizeElements(0) {}
52 constexpr Span(Type* items, SizeType sizeInElements) : items(items), sizeElements(sizeInElements) {}
56 template <
typename U = Type>
57 constexpr Span(TypeIfNotVoid<U>& type) : items(&type), sizeElements(1)
62 template <
typename U = Type>
63 constexpr Span(std::initializer_list<TypeIfNotVoid<U>> list) : items(nullptr), sizeElements(0)
67 sizeElements = list.size();
74 operator Span<void>() {
return Span<void>(items, sizeElements * detail::SpanSizeOfType<Type>::size); }
80 template <
typename T> [[nodiscard]]
static Span<Type> reinterpret_object(T& value) {
return {
reinterpret_cast<Type*
>(&value),
sizeof(T) / detail::SpanSizeOfType<Type>::size}; }
86 [[nodiscard]]
static Span<Type> reinterpret_bytes(VoidType* rawMemory, SizeType sizeInBytes) {
return Span(
reinterpret_cast<Type*
>(rawMemory), sizeInBytes / detail::SpanSizeOfType<Type>::size); }
94 template <
typename T> [[nodiscard]] T* start_lifetime_as_array() const noexcept
98 void* p =
const_cast<void*
>(
static_cast<const void*
>(data()));
99 return sizeElements == 0 ?
static_cast<const T*
>(p) : launder(static_cast<const T*>(::memmove(p, p, sizeof(T) * sizeElements)));
102 template <
typename T> [[nodiscard]] T* start_lifetime_as_array() noexcept
105 return sizeElements == 0 ?
static_cast<T*
>(p) : launder(static_cast<T*>(::memmove(p, p, sizeof(T) * sizeElements)));
108 template <
typename T> [[nodiscard]]
const T* start_lifetime_as() const noexcept
110 void* p =
const_cast<void*
>(
static_cast<const void*
>(data()));
111 return launder(
static_cast<const T*
>(::memmove(p, p,
sizeof(T))));
114 template <
typename T> [[nodiscard]] T* start_lifetime_as() noexcept
117 return launder(
static_cast<T*
>(::memmove(p, p,
sizeof(T))));
120 [[nodiscard]]
constexpr const Type* begin()
const {
return items; }
121 [[nodiscard]]
constexpr const Type* end()
const {
return items + sizeElements; }
122 [[nodiscard]]
constexpr const Type* data()
const {
return items; }
123 [[nodiscard]]
constexpr Type* begin() {
return items; }
124 [[nodiscard]]
constexpr Type* end() {
return items + sizeElements; }
125 [[nodiscard]]
constexpr Type* data() {
return items; }
127 [[nodiscard]]
constexpr SizeType sizeInElements()
const {
return sizeElements; }
128 [[nodiscard]]
constexpr SizeType sizeInBytes()
const {
return sizeElements * detail::SpanSizeOfType<Type>::size; }
130 [[nodiscard]]
constexpr bool empty()
const {
return sizeElements == 0; }
132 template <
typename U = Type> TypeIfNotVoid<U>& operator[](SizeType idx) {
return items[idx]; }
133 template <
typename U = Type>
const TypeIfNotVoid<U>& operator[](SizeType idx)
const {
return items[idx]; }
142 [[nodiscard]]
constexpr bool sliceStart(SizeType offsetInElements,
Span& destination)
const
144 if (offsetInElements <= sizeInElements())
146 destination =
Span(items + offsetInElements, (sizeInElements() - offsetInElements));
159 [[nodiscard]]
constexpr bool sliceStartLength(SizeType offsetInElements, SizeType lengthInElements,
160 Span& destination)
const
162 if (offsetInElements + lengthInElements <= sizeInElements())
164 destination =
Span(items + offsetInElements, lengthInElements);
unsigned long size_t
Platform independent unsigned size type.
Definition PrimitiveTypes.h:56
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
static Span< Type > reinterpret_object(T &value)
Constructs a Span reinterpreting memory pointed by object of type T as a type Type
Definition Span.h:80
static Span< Type > reinterpret_bytes(VoidType *rawMemory, SizeType sizeInBytes)
Construct a span reinterpreting raw memory (void* or const void*) to Type or const Type
Definition Span.h:86
Span< T > reinterpret_as_span_of()
Reinterprets the current span as an array of the specified type.
Definition Span.h:92
Span< const T > reinterpret_as_span_of() const
Reinterprets the current span as an array of the specified type.
Definition Span.h:89
constexpr bool sliceStart(SizeType offsetInElements, Span &destination) const
Creates another Span, starting at an offset in elements from current Span, until end.
Definition Span.h:142
constexpr Span()
Builds an empty Span.
Definition Span.h:47
constexpr bool sliceStartLength(SizeType offsetInElements, SizeType lengthInElements, Span &destination) const
Creates another Span, starting at an offset in elements from current Span of specified length.
Definition Span.h:159
constexpr Span(Type *items, SizeType sizeInElements)
Builds a Span from an array.
Definition Span.h:52
constexpr Span(std::initializer_list< TypeIfNotVoid< U > > list)
Span specialized constructor (mainly used for converting const char* to StringView)
Definition Span.h:63
constexpr Span(TypeIfNotVoid< U > &type)
Builds a Span from a single object.
Definition Span.h:57
EnableIf conditionally defines a type if a boolean template parameter is true.
Definition TypeTraits.h:25
IsSame evaluates to true if the provided types T and U are the same, false otherwise.
Definition TypeTraits.h:29