Sane C++ Libraries
C++ Platform Abstraction Libraries
Span.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/InitializerList.h"
5#include "../Foundation/TypeTraits.h" // SameConstnessAs
6
7namespace SC
8{
9template <typename Type>
10struct Span;
11} // namespace SC
12
15
18template <typename Type>
20{
21 using SizeType = size_t;
22 using VoidType = typename TypeTraits::SameConstnessAs<Type, void>::type;
23
24 template <size_t N>
25 constexpr Span(Type (&_items)[N]) : items(_items), sizeElements(N)
26 {}
27
29 constexpr Span() : items(nullptr), sizeElements(0) {}
30
34 constexpr Span(Type* items, SizeType sizeInElements) : items(items), sizeElements(sizeInElements) {}
35
38 constexpr Span(Type& type) : items(&type), sizeElements(1) {}
39
42 constexpr Span(std::initializer_list<Type> list) : items(nullptr), sizeElements(0)
43 {
44 // We need this two step initialization to avoid warnings on all compilers
45 items = list.begin();
46 sizeElements = list.size();
47 }
48
50 operator Span<const Type>() const { return {items, sizeElements}; }
51
56 template <typename T>
57 [[nodiscard]] static Span<Type> reinterpret_object(T& value)
58 {
59 return {reinterpret_cast<Type*>(&value), sizeof(T) / sizeof(Type)};
60 }
61
66 [[nodiscard]] static Span<Type> reinterpret_bytes(VoidType* rawMemory, SizeType sizeInBytes)
67 {
68 return Span(reinterpret_cast<Type*>(rawMemory), sizeInBytes / sizeof(Type));
69 }
70
72 template <typename T>
74 {
75 return Span<const T>(reinterpret_cast<const T*>(items), sizeInBytes() / sizeof(T));
76 }
77
80 [[nodiscard]] constexpr const Type* begin() const { return items; }
81
84 [[nodiscard]] constexpr const Type* end() const { return items + sizeElements; }
85
88 [[nodiscard]] constexpr const Type* data() const { return items; }
89
92 [[nodiscard]] constexpr Type* begin() { return items; }
93
96 [[nodiscard]] constexpr Type* end() { return items + sizeElements; }
97
100 [[nodiscard]] constexpr Type* data() { return items; }
101
104 [[nodiscard]] constexpr SizeType sizeInElements() const { return sizeElements; }
105
108 [[nodiscard]] constexpr SizeType sizeInBytes() const { return sizeElements * sizeof(Type); }
109
116 [[nodiscard]] constexpr bool sliceStart(SizeType offsetInElements, Span& destination) const
117 {
118 if (offsetInElements <= sizeInElements())
119 {
120 destination = Span(items + offsetInElements, (sizeInElements() - offsetInElements));
121 return true;
122 }
123 return false;
124 }
125
133 [[nodiscard]] constexpr bool sliceStartLength(SizeType offsetInElements, SizeType lengthInElements,
134 Span& destination) const
135 {
136 if (offsetInElements + lengthInElements <= sizeInElements())
137 {
138 destination = Span(items + offsetInElements, lengthInElements);
139 return true;
140 }
141 return false;
142 }
143
146 [[nodiscard]] constexpr bool empty() const { return sizeElements == 0; }
147
148 [[nodiscard]] constexpr bool contains(const Type& type, SizeType* index = nullptr) const
149 {
150 for (SizeType idx = 0; idx < sizeElements; ++idx)
151 {
152 if (items[idx] == type)
153 {
154 if (index)
155 {
156 *index = idx;
157 }
158 return true;
159 }
160 }
161 return false;
162 }
163
164 Type& operator[](SizeType idx) { return items[idx]; }
165
166 const Type& operator[](SizeType idx) const { return items[idx]; }
167
168 private:
169 Type* items;
170 SizeType sizeElements;
171};
172
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:20
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:57
constexpr const Type * data() const
Returns pointer to first element of the span.
Definition: Span.h:88
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:66
constexpr SizeType sizeInBytes() const
Size of Span in bytes.
Definition: Span.h:108
constexpr Span(std::initializer_list< Type > list)
Span specialized constructor (mainly used for converting const char* to StringView)
Definition: Span.h:42
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:116
constexpr Span()
Builds an empty Span.
Definition: Span.h:29
constexpr Type * begin()
Returns pointer to first element of the span.
Definition: Span.h:92
constexpr Type * end()
Returns pointer to one after the last element of the span.
Definition: Span.h:96
constexpr const Type * begin() const
Returns pointer to first element of the span.
Definition: Span.h:80
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:133
constexpr Span(Type *items, SizeType sizeInElements)
Builds a Span from an array.
Definition: Span.h:34
Span< const T > reinterpret_as_array_of() const
Reinterprets the current span as an array of the specified type.
Definition: Span.h:73
constexpr Type * data()
Returns pointer to first element of the span.
Definition: Span.h:100
constexpr bool empty() const
Check if Span is empty.
Definition: Span.h:146
constexpr SizeType sizeInElements() const
Size of Span in elements.
Definition: Span.h:104
constexpr const Type * end() const
Returns pointer to one after the last element of the span.
Definition: Span.h:84
constexpr Span(Type &type)
Builds a Span from a single object.
Definition: Span.h:38