4#include "../Foundation/Assert.h"
5#include "../Foundation/Span.h"
6#include "../Memory/Memory.h"
12enum class SegmentAllocator
20struct SC_MEMORY_EXPORT SegmentHeader;
21struct alignas(uint64_t) SegmentHeader
23 static constexpr uint32_t MaxCapacity = (~static_cast<uint32_t>(0)) >> 1;
25 SegmentHeader(uint32_t capacity = 0, SegmentAllocator allocator = SegmentAllocator::Global)
28 allocatorType =
static_cast<uint32_t>(allocator);
29 capacityBytes = capacity;
30 hasInlineData = capacity > 0;
38struct SC_MEMORY_EXPORT SegmentHeaderOffset
46struct SC_MEMORY_EXPORT SegmentSelfRelativePointer :
protected SegmentHeaderOffset
50 SC_COMPILER_FORCE_INLINE const T* data() const noexcept {
return offset == 0 ? nullptr : toPtr(toOffset(
this) + offset); }
51 SC_COMPILER_FORCE_INLINE bool isInline() const noexcept {
return (offset ==
sizeof(SegmentHeaderOffset) +
sizeof(uint64_t)) and header.hasInlineData; }
54 struct InlineData :
public SegmentHeaderOffset
63 SC_COMPILER_FORCE_INLINE static auto toOffset(
const volatile void* src)
noexcept {
return reinterpret_cast<PtrOffset
>(src); }
65 SC_COMPILER_FORCE_INLINE void setData(T* mem)
noexcept { offset = mem ==
nullptr ? 0 : toOffset(mem) - toOffset(
this); }
66 SC_COMPILER_FORCE_INLINE T* getInlineData() noexcept {
return (T*)
reinterpret_cast<volatile InlineData*
>(
this)->data; }
67 SC_COMPILER_FORCE_INLINE auto getInlineCapacity() noexcept {
return reinterpret_cast<volatile InlineData*
>(
this)->capacity; }
73struct SC_MEMORY_EXPORT SegmentTrivial
76 inline static void destruct(Span<T> data)
noexcept;
78 template <
typename U>
inline static void copyConstructAs(Span<T> data, Span<const U> value)
noexcept;
79 template <
typename U>
inline static void copyConstruct(Span<T> data,
const U* src)
noexcept;
80 template <
typename U>
inline static void copyAssign(Span<T> data,
const U* src)
noexcept;
81 template <
typename U>
inline static void copyInsert(Span<T> data, Span<const U> values)
noexcept;
82 template <
typename U>
inline static void moveConstruct(Span<T> data, U* src)
noexcept;
83 template <
typename U>
inline static void moveAssign(Span<T> data, U* src)
noexcept;
85 inline static void remove(Span<T> data,
size_t numElements)
noexcept;
89template <
typename ParentSegment,
typename CommonParent,
int N = 0,
90 SegmentAllocator Allocator = SegmentAllocator::ThreadLocal>
91struct SC_MEMORY_EXPORT SegmentCustom :
public ParentSegment
93 SegmentCustom() : ParentSegment(N, Allocator) {}
94 SegmentCustom(
const CommonParent& other) : SegmentCustom() { CommonParent::operator=(other); }
95 SegmentCustom(CommonParent&& other) : SegmentCustom() { CommonParent::operator=(
move(other)); }
97 SegmentCustom(
const SegmentCustom& other) : SegmentCustom() { ParentSegment::operator=(other); }
98 SegmentCustom(SegmentCustom&& other) : SegmentCustom() { ParentSegment::operator=(
move(other)); }
100 SegmentCustom& operator=(
const SegmentCustom& other) { ParentSegment::operator=(other);
return *
this; }
101 SegmentCustom& operator=(SegmentCustom&& other) { ParentSegment::operator=(
move(other));
return *
this; }
112template <
typename VTable>
113struct SC_MEMORY_EXPORT
Segment :
public VTable
116 using T =
typename VTable::Type;
117 Segment(
uint32_t capacityInBytes, SegmentAllocator allocator = SegmentAllocator::Global)
noexcept;
129 Segment(std::initializer_list<T> list)
noexcept;
136 [[nodiscard]]
bool resize(
size_t newSize,
const T& value = T()) noexcept;
139 [[nodiscard]]
bool reserve(
size_t capacity) noexcept;
142 template <typename U = T>
143 [[nodiscard]]
bool append(
Span<const U> span) noexcept;
146 template <typename VTable2>
147 [[nodiscard]]
bool appendMove(
Segment<VTable2>&& other) noexcept;
151 [[nodiscard]]
bool shrink_to_fit() noexcept;
154 void clear() noexcept;
158 template <typename U = T>
159 [[nodiscard]]
bool assign(
Span<const U> span) noexcept;
163 template <typename VTable2>
164 [[nodiscard]]
bool assignMove(
Segment<VTable2>&& other) noexcept;
167 [[nodiscard]]
bool push_back(const T& value) noexcept {
return resize(size() + 1, value); }
173 [[nodiscard]]
bool push_front(
const T& value)
noexcept {
return insert(0, value); }
178 [[nodiscard]]
bool pop_back(T* removedValue =
nullptr) noexcept;
183 [[nodiscard]]
bool pop_front(T* removedValue =
nullptr) noexcept;
186 [[nodiscard]] T* begin() noexcept SC_LANGUAGE_LIFETIME_BOUND {
return data(); }
187 [[nodiscard]]
const T* begin() const noexcept SC_LANGUAGE_LIFETIME_BOUND {
return data(); }
188 [[nodiscard]] T* end() noexcept SC_LANGUAGE_LIFETIME_BOUND {
return data() + size(); }
189 [[nodiscard]]
const T* end() const noexcept SC_LANGUAGE_LIFETIME_BOUND {
return data() + size(); }
191 [[nodiscard]] T& back() noexcept SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *(data() + size() - 1);}
192 [[nodiscard]] T& front() noexcept SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *data();}
193 [[nodiscard]]
const T& back() const noexcept SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *(data() + size() - 1);}
194 [[nodiscard]]
const T& front() const noexcept SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_RELEASE(not isEmpty());
return *data();}
196 [[nodiscard]] T& operator[](
size_t idx)
noexcept SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_DEBUG(idx < size());
return *(data() + idx);}
197 [[nodiscard]]
const T& operator[](
size_t idx)
const noexcept SC_LANGUAGE_LIFETIME_BOUND {
SC_ASSERT_DEBUG(idx < size());
return *(data() + idx);}
201 [[nodiscard]]
bool isEmpty() const noexcept {
return VTable::header.sizeBytes == 0; }
204 [[nodiscard]]
Span<T> toSpan() noexcept SC_LANGUAGE_LIFETIME_BOUND {
return {data(), size()}; }
210 [[nodiscard]]
size_t size() const noexcept {
return VTable::header.sizeBytes /
sizeof(T); }
213 [[nodiscard]]
size_t capacity() const noexcept {
return VTable::header.capacityBytes /
sizeof(T); }
219 [[nodiscard]]
bool removeRange(
size_t start,
size_t length)
noexcept;
224 [[nodiscard]]
bool removeAt(
size_t index)
noexcept {
return removeRange(index, 1); }
233 template <
typename VTable2>
#define SC_ASSERT_DEBUG(e)
Assert expression e to be true.
Definition Assert.h:63
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition Assert.h:48
#define SC_COMPILER_FORCE_INLINE
Macro for forcing inline functions.
Definition Compiler.h:46
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition Compiler.h:273
decltype(sizeof(0)) size_t
Platform independent unsigned size type.
Definition PrimitiveTypes.h:45
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:33
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:29
A slice of contiguous memory, prefixed by and header containing size and capacity.
Definition Segment.h:114
size_t size() const noexcept
Returns current size.
Definition Segment.h:210
bool resize(size_t newSize, const T &value=T()) noexcept
Re-allocates to the requested new size, preserving its contents and setting new items to value.
size_t capacity() const noexcept
Returns current capacity (always >= of size())
Definition Segment.h:213
Span< T > toSpan() noexcept SC_LANGUAGE_LIFETIME_BOUND
Obtains a Span of internal contents.
Definition Segment.h:204
bool isEmpty() const noexcept
Check if is empty (size() == 0)
Definition Segment.h:201
bool removeRange(size_t start, size_t length) noexcept
Removes the range [start, start + length] from the segment.
bool push_front(const T &value) noexcept
Appends a single element to the start of the segment.
Definition Segment.h:173
bool removeAt(size_t index) noexcept
Removes the element at index.
Definition Segment.h:224
bool pop_back(T *removedValue=nullptr) noexcept
Removes the last element of the segment.
bool push_back(T &&value) noexcept
Moves a single element to the end of the segment.
bool insert(size_t index, Span< const T > data) noexcept
Insert a span at the given index.
bool resizeWithoutInitializing(size_t newSize) noexcept
Re-allocates to the requested new size, preserving its contents.
Span< const T > toSpanConst() const noexcept SC_LANGUAGE_LIFETIME_BOUND
Obtains a Span of internal contents.
Definition Segment.h:207
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29