4#include "../Algorithms/AlgorithmRemove.h"
5#include "../Foundation/Segment.h"
6#include "../Foundation/Segment.inl"
7#include "../Foundation/TypeTraits.h"
16struct SegmentNonTrivial
18 static void destruct(SegmentHeader& header,
size_t bytesOffset,
size_t numBytes)
20 forEach(header, bytesOffset, numBytes, [](
auto, T& item) { item.~T(); });
22 static void copyConstructSingle(SegmentHeader& header,
size_t bytesOffset,
const T* value,
size_t numBytes,
size_t)
24 forEach(header, bytesOffset, numBytes, [value](
auto, T& item) { placementNew(item, *value); });
26 static void copyConstruct(SegmentHeader& dest,
size_t bytesOffset,
const T* src,
size_t numBytes)
28 forEach(dest, bytesOffset, numBytes, [src](
auto idx, T& item) { placementNew(item, src[idx]); });
30 static void copyAssign(SegmentHeader& dest,
size_t bytesOffset,
const T* src,
size_t numBytes)
32 forEach(dest, bytesOffset, numBytes, [src](
auto idx, T& item) { item = src[idx]; });
34 static void moveConstruct(SegmentHeader& dest,
size_t bytesOffset, T* src,
size_t numBytes)
36 forEach(dest, bytesOffset, numBytes, [src](
auto idx, T& item) { placementNew(item,
move(src[idx])); });
38 static void moveAssign(SegmentHeader& dest,
size_t bytesOffset, T* src,
size_t numBytes)
40 forEach(dest, bytesOffset, numBytes, [src](
auto idx, T& item) { item =
move(src[idx]); });
43 static void copyInsert(SegmentHeader& dest,
size_t startOffsetBytes,
const T* src,
size_t numBytes)
45 T* data = getData(dest, 0);
47 const size_t numElements = dest.sizeBytes /
sizeof(T);
48 const size_t numToInsert = numBytes /
sizeof(T);
49 const size_t insertStartIdx = startOffsetBytes /
sizeof(T);
50 const size_t insertEndIdx = insertStartIdx + numToInsert;
52 if (insertStartIdx == numElements)
55 for (
size_t idx = numElements; idx < numElements + numToInsert; ++idx)
57 placementNew(data[idx], src[idx - numElements]);
63 for (
size_t idx = numElements; idx < numElements + numToInsert; ++idx)
68 if (idx >= numToInsert)
70 placementNew(data[idx],
move(data[idx - numToInsert]));
75 for (
size_t idx = numElements - 1; idx >= insertStartIdx + numToInsert; --idx)
77 if (idx >= numToInsert)
79 data[idx] =
move(data[idx - numToInsert]);
84 for (
size_t idx = insertStartIdx; idx < insertEndIdx; ++idx)
87 if (idx < numElements)
89 data[idx] = src[idx - insertStartIdx];
93 placementNew(data[idx], src[idx - insertStartIdx]);
99 static void remove(SegmentHeader& dest,
size_t fromBytesOffset,
size_t toBytesOffset)
101 T* data = getData(dest, 0);
103 const size_t numElements = dest.sizeBytes /
sizeof(T);
104 const size_t startIdx = fromBytesOffset /
sizeof(T);
105 const size_t endIdx = toBytesOffset /
sizeof(T);
106 const size_t numToRemove = (endIdx - startIdx);
108 for (
size_t idx = startIdx; idx < numElements - numToRemove; ++idx)
110 data[idx] =
move(data[idx + numToRemove]);
112 for (
size_t idx = numElements - numToRemove; idx < numElements; ++idx)
119 static T* getData(SegmentHeader& header,
size_t byteOffset) {
return header.getData<T>() + byteOffset /
sizeof(T); }
121 static size_t getSize(SegmentHeader& header) {
return header.sizeBytes /
sizeof(T); }
123 template <
typename Lambda>
124 static void forEach(SegmentHeader& header,
size_t byteOffset,
size_t numBytes, Lambda&& lambda)
126 T* data = getData(header, byteOffset);
127 const size_t numElements = numBytes /
sizeof(T);
128 for (
size_t idx = 0; idx < numElements; ++idx)
130 lambda(idx, data[idx]);
143 static void destruct(SegmentHeader& header,
size_t bytesOffset,
size_t numBytes)
145 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
146 SegmentTrivial::destruct(header, bytesOffset, numBytes);
148 SegmentNonTrivial<T>::destruct(header, bytesOffset, numBytes);
151 static void copyConstructSingle(SegmentHeader& header,
size_t bytesOffset,
const T* value,
size_t numBytes,
154 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
155 SegmentTrivial::copyConstructSingle(header, bytesOffset, value, numBytes, sizeOfValue);
157 SegmentNonTrivial<T>::copyConstructSingle(header, bytesOffset, value, numBytes, sizeOfValue);
160 static void copyConstruct(SegmentHeader& dest,
size_t bytesOffset,
const T* src,
size_t numBytes)
162 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
163 SegmentTrivial::copyConstruct(dest, bytesOffset, src, numBytes);
165 SegmentNonTrivial<T>::copyConstruct(dest, bytesOffset, src, numBytes);
168 static void copyAssign(SegmentHeader& dest,
size_t bytesOffset,
const T* src,
size_t numBytes)
170 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
171 SegmentTrivial::copyAssign(dest, bytesOffset, src, numBytes);
173 SegmentNonTrivial<T>::copyAssign(dest, bytesOffset, src, numBytes);
176 static void moveConstruct(SegmentHeader& dest,
size_t bytesOffset, T* src,
size_t numBytes)
178 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
179 SegmentTrivial::moveConstruct(dest, bytesOffset, src, numBytes);
181 SegmentNonTrivial<T>::moveConstruct(dest, bytesOffset, src, numBytes);
184 static void moveAssign(SegmentHeader& dest,
size_t bytesOffset, T* src,
size_t numBytes)
186 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
187 SegmentTrivial::moveAssign(dest, bytesOffset, src, numBytes);
189 SegmentNonTrivial<T>::moveAssign(dest, bytesOffset, src, numBytes);
192 static void copyInsert(SegmentHeader& dest,
size_t bytesOffset,
const T* src,
size_t numBytes)
194 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
195 SegmentTrivial::copyInsert(dest, bytesOffset, src, numBytes);
197 SegmentNonTrivial<T>::copyInsert(dest, bytesOffset, src, numBytes);
200 static void remove(SegmentHeader& dest,
size_t fromBytesOffset,
size_t toBytesOffset)
202 if SC_LANGUAGE_IF_CONSTEXPR (TypeTraits::IsTriviallyCopyable<T>::value)
203 SegmentTrivial::remove(dest, fromBytesOffset, toBytesOffset);
205 SegmentNonTrivial<T>::remove(dest, fromBytesOffset, toBytesOffset);
213 static SegmentHeader* allocateNewHeader(
size_t newCapacityInBytes)
215 return SegmentAllocator::allocateNewHeader(newCapacityInBytes);
222 return SegmentAllocator::reallocateExistingHeader(src, newCapacityInBytes);
227 SegmentHeader* newHeader = allocateNewHeader(newCapacityInBytes);
228 if (newHeader !=
nullptr)
231 T* tsrc = src.getData<T>();
232 Internal::ObjectVTable<T>::moveConstruct(*newHeader, 0, tsrc, src.sizeBytes);
233 Internal::ObjectVTable<T>::destruct(src, 0, src.sizeBytes);
239 static void destroyHeader(
SegmentHeader& header) { SegmentAllocator::destroyHeader(header); }
261 using Parent::Parent;
269 template <
typename U>
270 [[nodiscard]]
bool contains(
const U& value,
size_t* index =
nullptr)
const
280 template <
typename Lambda>
281 [[nodiscard]]
bool find(Lambda&& lambda,
size_t* index =
nullptr)
const
290 template <
typename Lambda>
293 T* itBeg = Parent::begin();
294 T* itEnd = Parent::end();
297 const size_t numBytes =
static_cast<size_t>(itEnd - it) *
sizeof(T);
298 const size_t offBytes =
static_cast<size_t>(it - itBeg) *
sizeof(T);
300 Parent::header->sizeBytes -=
static_cast<decltype(Parent::header-
>sizeBytes)>(numBytes);
308 template <
typename U>
309 [[nodiscard]]
bool remove(
const U& value)
311 return removeAll([&](
auto& item) {
return item == value; });
ForwardIterator removeIf(ForwardIterator first, ForwardIterator last, UnaryPredicate &&predicate)
Removes all items in the given range, satisfying the given predicate.
Definition: AlgorithmRemove.h:22
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition: Compiler.h:269
A slice of contiguous memory, prefixed by and header containing size and capacity.
Definition: Segment.h:35
Span< const T > toSpanConst() const SC_LANGUAGE_LIFETIME_BOUND
Obtains a Span of internal contents.
Definition: Segment.h:147
IsTriviallyCopyable evaluates to true if the type T can be trivially copied, false otherwise.
Definition: TypeTraits.h:60
A contiguous sequence of heap allocated elements.
Definition: Vector.h:257
bool contains(const U &value, size_t *index=nullptr) const
Check if the current array contains a given value.
Definition: Vector.h:270
bool removeAll(Lambda &&criteria)
Removes all items matching criteria given by Lambda.
Definition: Vector.h:291
bool remove(const U &value)
Removes all values equal to value
Definition: Vector.h:309
bool find(Lambda &&lambda, size_t *index=nullptr) const
Finds the first item in array matching criteria given by the lambda.
Definition: Vector.h:281