4#include "../Foundation/InitializerList.h"
5#include "../Foundation/LibC.h"
6#include "../Foundation/TypeTraits.h"
10template <
typename Type>
18template<
typename U>
struct SpanSizeOfType {
static constexpr auto size =
sizeof(U); };
19template<>
struct SpanSizeOfType<void> {
static constexpr auto size = 1; };
20template<>
struct SpanSizeOfType<const void> {
static constexpr auto size = 1; };
30template <
typename Type>
36 using VoidType =
typename TypeTraits::SameConstnessAs<Type, void>::type;
42 SizeType sizeElements;
45 template <
size_t N,
typename U = Type, EnableNotVo
id<U> = true>
46 constexpr Span(U (&itemsArray)[N]) : items(itemsArray), sizeElements(N)
50 constexpr Span() : items(nullptr), sizeElements(0) {}
59 template <
typename U = Type>
60 constexpr Span(TypeIfNotVoid<U>& type) : items(&type), sizeElements(1)
65 template <
typename U = Type>
66 constexpr Span(std::initializer_list<TypeIfNotVoid<U>> list) : items(nullptr), sizeElements(0)
70 sizeElements = list.size();
75 template <
typename U = Type>
operator Span< TypeIfNotVoid<U>>() {
return {items, sizeElements}; }
76 operator Span<const void>()
const {
return Span<const void>(items, sizeElements * detail::SpanSizeOfType<Type>::size); }
77 operator Span<void>() {
return Span<void>(items, sizeElements * detail::SpanSizeOfType<Type>::size); }
83 template <
typename T> [[nodiscard]]
static Span<Type> reinterpret_object(T& value) {
return {
reinterpret_cast<Type*
>(&value),
sizeof(T) / detail::SpanSizeOfType<Type>::size}; }
97 template <
typename T> [[nodiscard]] T* start_lifetime_as_array() const noexcept
101 void* p =
const_cast<void*
>(
static_cast<const void*
>(
data()));
102 return sizeElements == 0 ?
static_cast<const T*
>(p) : launder(
static_cast<const T*
>(::memmove(p, p,
sizeof(T) * sizeElements)));
105 template <
typename T> [[nodiscard]] T* start_lifetime_as_array() noexcept
108 return sizeElements == 0 ?
static_cast<T*
>(p) : launder(
static_cast<T*
>(::memmove(p, p,
sizeof(T) * sizeElements)));
111 template <
typename T> [[nodiscard]]
const T* start_lifetime_as() const noexcept
113 void* p =
const_cast<void*
>(
static_cast<const void*
>(
data()));
114 return launder(
static_cast<const T*
>(::memmove(p, p,
sizeof(T))));
117 template <
typename T> [[nodiscard]] T* start_lifetime_as() noexcept
120 return launder(
static_cast<T*
>(::memmove(p, p,
sizeof(T))));
126 [[nodiscard]]
constexpr const Type*
begin()
const {
return items; }
130 [[nodiscard]]
constexpr const Type*
end()
const {
return items + sizeElements; }
134 [[nodiscard]]
constexpr const Type*
data()
const {
return items; }
138 [[nodiscard]]
constexpr Type*
begin() {
return items; }
142 [[nodiscard]]
constexpr Type*
end() {
return items + sizeElements; }
146 [[nodiscard]]
constexpr Type*
data() {
return items; }
154 [[nodiscard]]
constexpr SizeType
sizeInBytes()
const {
return sizeElements * detail::SpanSizeOfType<Type>::size; }
162 [[nodiscard]]
constexpr bool sliceStart(SizeType offsetInElements,
Span& destination)
const
179 [[nodiscard]]
constexpr bool sliceStartLength(SizeType offsetInElements, SizeType lengthInElements,
180 Span& destination)
const
184 destination =
Span(items + offsetInElements, lengthInElements);
195 const auto diff = other.items - items;
196 if (diff < 0 or
static_cast<SizeType
>(diff) >
sizeInBytes())
202 output =
Span(items,
static_cast<SizeType
>(diff) / detail::SpanSizeOfType<Type>::size);
209 [[nodiscard]]
constexpr bool empty()
const {
return sizeElements == 0; }
217 template <
typename U>
218 [[nodiscard]]
constexpr bool contains(
const U& value, SizeType* index =
nullptr)
const
220 return find([&](
auto& current) {
return current == value; }, index);
228 template <
typename Lambda>
229 [[nodiscard]]
constexpr bool find(Lambda&& lambda, SizeType* index =
nullptr)
const
231 for (SizeType idx = 0; idx < sizeElements; ++idx)
233 if (lambda(items[idx]))
246 template <
typename U = Type> TypeIfNotVoid<U>& operator[](SizeType idx) {
return items[idx]; }
247 template <
typename U = Type>
const TypeIfNotVoid<U>& operator[](SizeType idx)
const {
return items[idx]; }
251 template <
typename IntType>
254 if (idx >= 0 and idx <
static_cast<IntType
>(sizeElements))
260 template <
typename IntType>
261 const Type*
get(IntType idx)
const
263 if (idx >= 0 and idx <
static_cast<IntType
>(sizeElements))
269 template <
typename U>
280 template <
typename U>
291#if SC_PLATFORM_WINDOWS
292#define SC_NATIVE_STR(str) L##str
294#define SC_NATIVE_STR(str) str
301 constexpr SpanStringView(
const char*
string,
size_t stringLength) : text(
string, stringLength) {}
303 constexpr SpanStringView(
const char (&charLiteral)[N]) : text(charLiteral)
310 if (N < text.sizeInElements() + 1)
312 ::memcpy(&buffer[0], text.data(), text.sizeInElements());
324 constexpr SpanString(
char (&buffer)[N]) : text(buffer)
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:32
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:83
constexpr bool find(Lambda &&lambda, SizeType *index=nullptr) const
Finds the first item in span matching criteria given by the lambda.
Definition: Span.h:229
constexpr const Type * data() const
Returns pointer to first element of the span.
Definition: Span.h:134
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:89
Span< T > reinterpret_as_span_of()
Reinterprets the current span as an array of the specified type.
Definition: Span.h:95
const Type * get(IntType idx) const
Gets the item at given index or nullptr if index is negative or bigger than size.
Definition: Span.h:261
Span< const T > reinterpret_as_span_of() const
Reinterprets the current span as an array of the specified type.
Definition: Span.h:92
constexpr SizeType sizeInBytes() const
Size of Span in bytes.
Definition: Span.h:154
bool memcmpWith(const Span< U > other) const
Compares this span with another one byte by byte.
Definition: Span.h:270
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:162
constexpr bool contains(const U &value, SizeType *index=nullptr) const
Check if the current span contains a given value.
Definition: Span.h:218
constexpr Span()
Builds an empty Span.
Definition: Span.h:50
constexpr Type * begin()
Returns pointer to first element of the span.
Definition: Span.h:138
constexpr Type * end()
Returns pointer to one after the last element of the span.
Definition: Span.h:142
constexpr const Type * begin() const
Returns pointer to first element of the span.
Definition: Span.h:126
Type * get(IntType idx)
Gets the item at given index or nullptr if index is negative or bigger than size.
Definition: Span.h:252
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:179
bool memcpyTo(Span< U > &other) const
Bitwise copies contents of this Span over another (non-overlapping)
Definition: Span.h:281
constexpr Span(Type *items, SizeType sizeInElements)
Builds a Span from an array.
Definition: Span.h:55
constexpr Type * data()
Returns pointer to first element of the span.
Definition: Span.h:146
bool sliceFromStartUntil(Span other, Span &output) const
Creates another Span shorter or equal than the current one such that its end equals other....
Definition: Span.h:193
constexpr bool empty() const
Check if Span is empty.
Definition: Span.h:209
constexpr SizeType sizeInElements() const
Size of Span in elements.
Definition: Span.h:150
constexpr Span(std::initializer_list< TypeIfNotVoid< U > > list)
Span specialized constructor (mainly used for converting const char* to StringView)
Definition: Span.h:66
constexpr const Type * end() const
Returns pointer to one after the last element of the span.
Definition: Span.h:130
constexpr Span(TypeIfNotVoid< U > &type)
Builds a Span from a single object.
Definition: Span.h:60
An writable view over an ASCII string (to avoid including Strings library)
Definition: Span.h:322
An read-only view over an ASCII string (to avoid including Strings library)
Definition: Span.h:299
bool writeNullTerminated(char(&buffer)[N]) const
Writes current string view over a sized char array buffer, adding a null terminator.
Definition: Span.h:308
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