4#include "../Foundation/Assert.h"
5#include "../Foundation/Span.h"
12 static constexpr uint32_t MaxCapacity = (~static_cast<uint32_t>(0)) >> 1;
17 uint32_t isFollowedByInlineBuffer : 1;
19 template <
typename T> T* getData() {
return reinterpret_cast<T*
>(
reinterpret_cast<char*
>(
this) +
sizeof(*
this)); }
20 template <
typename T>
const T* getData()
const {
return reinterpret_cast<const T*
>(
reinterpret_cast<const char*
>(
this) +
sizeof(*
this)); }
33template <
typename VTable>
36 using T =
typename VTable::Type;
60 [[nodiscard]]
bool resize(
size_t newSize,
const T& value = T());
63 [[nodiscard]]
bool reserve(
size_t newCapacity);
91 [[nodiscard]]
bool push_back(
const T& value) {
return resize(size() + 1, value); }
97 [[nodiscard]]
bool push_front(
const T& value) {
return insert(0, value); }
102 [[nodiscard]]
bool pop_back(T* removedValue =
nullptr);
107 [[nodiscard]]
bool pop_front(T* removedValue =
nullptr);
112 [[nodiscard]]
const T*
data() const SC_LANGUAGE_LIFETIME_BOUND
114 return header ==
nullptr ? nullptr :
reinterpret_cast<const T*
>(
reinterpret_cast<const char*
>(header) +
sizeof(
SegmentHeader));
118 [[nodiscard]] T*
data() SC_LANGUAGE_LIFETIME_BOUND
120 return header ==
nullptr ? nullptr :
reinterpret_cast<T*
>(
reinterpret_cast<char*
>(header) +
sizeof(
SegmentHeader));
123 [[nodiscard]] T* begin() SC_LANGUAGE_LIFETIME_BOUND {
return data(); }
124 [[nodiscard]]
const T* begin() const SC_LANGUAGE_LIFETIME_BOUND {
return data(); }
125 [[nodiscard]] T* end() SC_LANGUAGE_LIFETIME_BOUND {
return data() + size(); }
126 [[nodiscard]]
const T* end() const SC_LANGUAGE_LIFETIME_BOUND {
return data() + size(); }
128 [[nodiscard]] T& back() SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *(data() + size() - 1);}
129 [[nodiscard]] T& front() SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *data();}
130 [[nodiscard]] T& operator[](
size_t idx) SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_DEBUG(idx < size());
return *(data() + idx);}
131 [[nodiscard]]
const T& back() const SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *(data() + size() - 1);}
132 [[nodiscard]]
const T& front() const SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *data();}
133 [[nodiscard]]
const T& operator[](
size_t idx)
const SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_DEBUG(idx < size());
return *(data() + idx);}
138 [[nodiscard]]
bool isInlineBuffer()
const {
return header !=
nullptr and header->isInlineBuffer; }
141 [[nodiscard]]
bool isEmpty()
const {
return header ==
nullptr or header->sizeBytes == 0; }
144 [[nodiscard]]
Span<T> toSpan() SC_LANGUAGE_LIFETIME_BOUND {
return {data(), size()}; }
150 [[nodiscard]]
size_t size()
const {
return header ==
nullptr ? 0 : header->sizeBytes /
sizeof(T); }
153 [[nodiscard]]
size_t capacity() {
return header ==
nullptr ? 0 : header->capacityBytes /
sizeof(T); }
164 [[nodiscard]]
bool removeAt(
size_t index) {
return removeRange(index, 1); }
190 static void destruct(
SegmentHeader& header,
size_t bytesOffset,
size_t numBytes);
191 static void copyConstructSingle(
SegmentHeader& dest,
size_t bytesOffset,
const void* value,
size_t numBytes,
193 static void copyConstruct(
SegmentHeader& dest,
size_t bytesOffset,
const void* src,
size_t numBytes);
194 static void copyAssign(
SegmentHeader& dest,
size_t bytesOffset,
const void* src,
size_t numBytes);
195 static void copyInsert(
SegmentHeader& dest,
size_t bytesOffset,
const void* src,
size_t numBytes);
196 static void moveConstruct(
SegmentHeader& dest,
size_t bytesOffset,
void* src,
size_t numBytes);
197 static void moveAssign(
SegmentHeader& dest,
size_t bytesOffset,
void* src,
size_t numBytes);
198 static void remove(
SegmentHeader& dest,
size_t fromBytesOffset,
size_t toBytesOffset);
204 static SegmentHeader* allocateNewHeader(
size_t newCapacityInBytes);
#define SC_ASSERT_DEBUG(e)
Assert expression e to be true.
Definition: Assert.h:82
#define SC_COMPILER_EXPORT
Macro for symbol visibility in non-MSVC compilers.
Definition: Compiler.h:78
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition: Assert.h:66
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
Basic allocator for SC::Segment using Memory functions.
Definition: Segment.h:203
A slice of contiguous memory, prefixed by and header containing size and capacity.
Definition: Segment.h:35
Segment(SegmentHeader &inlineHeader, uint32_t capacityInBytes)
Builds a Segment with an inlineHeader of given capacity in bytes.
bool pop_back(T *removedValue=nullptr)
Removes the last element of the segment.
bool appendMove(Segment &&other)
Moves contents of another segment to the end of this segment.
size_t size() const
Returns current size.
Definition: Segment.h:150
bool append(Span< const T > span)
Appends a Span to the end of the segment.
void clear()
Sets size to zero without freeing any memory (use shrink_to_fit() to free memory)
bool shrink_to_fit()
Ensures capacity == size re-allocating (if capacity>size) or freeing ( if size==0) memory.
bool removeRange(size_t start, size_t length)
Removes the range [start, start + length] from the segment.
bool resize(size_t newSize, const T &value=T())
Re-allocates to the requested new size, preserving its contents and setting new items to value.
bool resizeWithoutInitializing(size_t newSize)
Re-allocates to the requested new size, preserving its contents.
bool isEmpty() const
Check if is empty (size() == 0)
Definition: Segment.h:141
size_t capacity()
Returns current capacity (always >= of size())
Definition: Segment.h:153
bool isInlineBuffer() const
Returns true if an inline buffer is in use (false if segment is heap allocated).
Definition: Segment.h:138
bool push_front(const T &value)
Appends a single element to the start of the segment.
Definition: Segment.h:97
T * data() SC_LANGUAGE_LIFETIME_BOUND
Access data owned by the segment or nullptr if segment is empty.
Definition: Segment.h:118
bool assign(Span< const T > span)
Replaces contents with contents of the span.
bool insert(size_t index, Span< const T > data)
Insert a span at the given index.
const T * data() const SC_LANGUAGE_LIFETIME_BOUND
Access data owned by the segment or nullptr if segment is empty.
Definition: Segment.h:112
Span< const T > toSpanConst() const SC_LANGUAGE_LIFETIME_BOUND
Obtains a Span of internal contents.
Definition: Segment.h:147
bool removeAt(size_t index)
Removes the element at index.
Definition: Segment.h:164
bool push_back(T &&value)
Moves a single element to the end of the segment.
bool append(Span< const U > span)
Appends a Span of items convertible to T to the end of the segment.
bool push_back(const T &value)
Appends a single element to the end of the segment.
Definition: Segment.h:91
bool reserve(size_t newCapacity)
Reserves capacity to avoid heap-allocation during a future append, assign or resize.
void unsafeSetHeader(SegmentHeader *newHeader)
Sets the internal header handled by this class.
Definition: Segment.h:173
bool pop_front(T *removedValue=nullptr)
Removes the first element of the segment.
bool assignMove(Segment &&other)
Replaces content moving (possibly "stealing") content of another segment.
Span< T > toSpan() SC_LANGUAGE_LIFETIME_BOUND
Obtains a Span of internal contents.
Definition: Segment.h:144
SegmentHeader * unsafeGetHeader() const
Get the internal header handled by this class.
Definition: Segment.h:176
Allows SC::Segment handle trivial types.
Definition: Segment.h:189
View over a contiguous sequence of items (pointer + size in elements).
Definition: Span.h:24