4#include "Internal/Segment.h"
9template <
typename T,
int N>
15struct SC::ArrayAllocator
17 [[nodiscard]]
static SegmentHeader* reallocate(SegmentHeader* oldHeader,
size_t newSize);
18 [[nodiscard]]
static SegmentHeader* allocate(SegmentHeader* oldHeader,
size_t numNewBytes,
void* selfPointer);
19 static void release(SegmentHeader* oldHeader);
22 static T* getItems(SegmentHeader* header)
24 return reinterpret_cast<T*
>(
reinterpret_cast<char*
>(header) +
sizeof(SegmentHeader));
27 static const T* getItems(
const SegmentHeader* header)
29 return reinterpret_cast<const T*
>(
reinterpret_cast<const char*
>(header) +
sizeof(SegmentHeader));
41template <
typename T,
int N>
45 static_assert(N > 0,
"Array must have N > 0");
47 SegmentItems<T> segmentHeader;
53 using Parent = SegmentItems<T>;
54 using Operations = SegmentOperations<ArrayAllocator, T>;
57 template <
typename,
int>
66 Array(std::initializer_list<T> list);
69 ~Array() { Operations::destroy(&segmentHeader); }
117 [[nodiscard]]
const T&
operator[](
size_t index)
const;
127 [[nodiscard]]
bool push_front(T&& element) {
return insertMove(0, &element, 1); }
132 [[nodiscard]]
bool push_back(
const T& element);
137 [[nodiscard]]
bool push_back(T&& element);
149 [[nodiscard]] T&
front();
153 [[nodiscard]]
const T&
front()
const;
157 [[nodiscard]] T&
back();
161 [[nodiscard]]
const T&
back()
const;
172 [[nodiscard]]
bool resize(
size_t newSize,
const T& value = T());
183 void clear() { Operations::clear(SegmentItems<T>::getSegment(items)); }
198 [[nodiscard]]
size_t size()
const {
return segmentHeader.size(); }
202 [[nodiscard]]
size_t capacity()
const {
return segmentHeader.capacity(); }
206 [[nodiscard]] T*
begin() SC_LANGUAGE_LIFETIME_BOUND {
return items; }
209 [[nodiscard]]
const T*
begin() const SC_LANGUAGE_LIFETIME_BOUND {
return items; }
212 [[nodiscard]] T*
end() SC_LANGUAGE_LIFETIME_BOUND {
return items +
size(); }
215 [[nodiscard]]
const T*
end() const SC_LANGUAGE_LIFETIME_BOUND {
return items +
size(); }
218 [[nodiscard]] T*
data() SC_LANGUAGE_LIFETIME_BOUND {
return items; }
221 [[nodiscard]]
const T*
data() const SC_LANGUAGE_LIFETIME_BOUND {
return items; }
237 template <
typename U>
244 template <
typename U>
253 template <
typename U>
254 [[nodiscard]]
bool contains(
const U& value,
size_t* foundIndex =
nullptr)
const;
261 template <
typename Lambda>
262 [[nodiscard]]
bool find(Lambda&& lambda,
size_t* foundIndex =
nullptr)
const;
267 [[nodiscard]]
bool removeAt(
size_t index);
273 template <
typename Lambda>
274 [[nodiscard]]
bool removeAll(Lambda&& criteria);
280 template <
typename U>
281 [[nodiscard]]
bool remove(
const U& value);
284 [[nodiscard]]
bool insertMove(
size_t idx, T* src,
size_t srcSize);
298inline SC::SegmentHeader* SC::ArrayAllocator::reallocate(SegmentHeader* oldHeader,
size_t newSize)
300 if (newSize <= oldHeader->sizeBytes)
306inline SC::SegmentHeader* SC::ArrayAllocator::allocate(SegmentHeader* oldHeader,
size_t numNewBytes,
void* selfPointer)
310 oldHeader->initDefaults();
314inline void SC::ArrayAllocator::release(SegmentHeader* oldHeader) {
SC_COMPILER_UNUSED(oldHeader); }
320template <
typename T,
int N>
323 static_assert(
alignof(
Array) ==
alignof(
uint64_t),
"Array Alignment");
324 segmentHeader.sizeBytes = 0;
325 segmentHeader.capacityBytes =
sizeof(T) * N;
328template <
typename T,
int N>
331 segmentHeader.capacityBytes =
sizeof(T) * N;
332 const auto sz =
min(
static_cast<int>(list.size()), N);
333 Parent::copyConstructMultiple(items, 0,
static_cast<size_t>(sz), list.begin());
334 segmentHeader.setSize(
static_cast<size_t>(sz));
337template <
typename T,
int N>
340 const size_t numElements = size();
345template <
typename T,
int N>
348 const size_t numElements = size();
353template <
typename T,
int N>
356 const size_t numElements = size();
358 return items[numElements - 1];
361template <
typename T,
int N>
364 const size_t numElements = size();
366 return items[numElements - 1];
368template <
typename T,
int N>
371 segmentHeader.sizeBytes = 0;
372 segmentHeader.capacityBytes =
sizeof(T) * N;
376template <
typename T,
int N>
379 segmentHeader.sizeBytes = 0;
380 segmentHeader.capacityBytes =
sizeof(T) * N;
381 (void)appendMove(other.toSpan());
384template <
typename T,
int N>
388 static_assert(M <= N,
"Unsafe operation, cannot report failure inside constructor, use append instead");
389 segmentHeader.sizeBytes = 0;
390 segmentHeader.capacityBytes =
sizeof(T) * N;
394template <
typename T,
int N>
398 static_assert(M <= N,
"Unsafe operation, cannot report failure inside constructor, use appendMove instead");
399 segmentHeader.sizeBytes = 0;
400 segmentHeader.capacityBytes =
sizeof(T) * N;
401 (void)appendMove(other.items, other.
size());
404template <
typename T,
int N>
411template <
typename T,
int N>
418template <
typename T,
int N>
423 T* oldItems = Array::items;
424 bool res = Operations::assign(oldItems, other.items, other.
size());
431template <
typename T,
int N>
436 Operations::clear(SegmentItems<T>::getSegment(items));
437 if (appendMove(other.
toSpan()))
439 Operations::clear(SegmentItems<T>::getSegment(other.items));
445template <
typename T,
int N>
452 bool res = copy(oldItems, other.
data(), other.
size());
459template <
typename T,
int N>
466 if (appendMove(other.items, other.
size()))
474template <
typename T,
int N>
478 return Operations::push_back(oldItems, element);
481template <
typename T,
int N>
485 return Operations::push_back(oldItems,
move(element));
488template <
typename T,
int N>
491 return Operations::pop_back(items);
494template <
typename T,
int N>
497 return Operations::pop_front(items);
500template <
typename T,
int N>
505 return Operations::template resizeInternal<IsTrivial, true>(oldItems, newSize, &value);
508template <
typename T,
int N>
513 return Operations::template resizeInternal<IsTrivial, false>(oldItems, newSize,
nullptr);
516template <
typename T,
int N>
520 return Operations::template insert<true>(oldItems, idx, data.
data(), data.
sizeInElements());
523template <
typename T,
int N>
527 return Operations::template insert<true>(oldItems, size(), data.
data(), data.
sizeInElements());
530template <
typename T,
int N>
535 return Operations::template insert<true>(oldItems, size(), data.
data(), data.
sizeInElements());
538template <
typename T,
int N>
542 if (appendMove({src.data(), src.size()}))
550template <
typename T,
int N>
555 items, 0, size(), [&](
const T& element) {
return element == value; }, foundIndex);
558template <
typename T,
int N>
559template <
typename Lambda>
565template <
typename T,
int N>
568 return Operations::removeAt(items, index);
571template <
typename T,
int N>
572template <
typename Lambda>
575 return SegmentItems<T>::removeAll(items, 0, size(), forward<Lambda>(criteria));
578template <
typename T,
int N>
582 return SegmentItems<T>::removeAll(items, 0, size(), [&](
const auto& it) {
return it == value; });
585template <
typename T,
int N>
589 return Operations::template insert<false>(oldItems, size(), data.
data(), data.
sizeInElements());
592template <
typename T,
int N>
596 return Operations::template insert<false>(oldItems, idx, src, srcSize);
constexpr const T & min(const T &t1, const T &t2)
Finds the minimum of two values.
Definition: Compiler.h:300
constexpr ForwardIterator findIf(ForwardIterator first, ForwardIterator last, UnaryPredicate &&predicate)
Find item satisfying the given predicate.
Definition: AlgorithmFind.h:23
#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_COMPILER_EXTERN
Define compiler-specific export macros for DLL visibility.
Definition: Compiler.h:74
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition: Assert.h:66
#define SC_COMPILER_UNUSED(param)
Silence an unused variable or unused parameter warning.
Definition: Compiler.h:139
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition: Compiler.h:269
char native_char_t
The native char for the platform (wchar_t (4 bytes) on Windows, char (1 byte) everywhere else )
Definition: PrimitiveTypes.h:34
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition: PrimitiveTypes.h:42
A contiguous sequence of elements kept inside its inline storage.
Definition: Array.h:43
bool resize(size_t newSize, const T &value=T())
Resizes this array to newSize, preserving existing elements.
Definition: Array.h:501
Span< const T > toSpanConst() const SC_LANGUAGE_LIFETIME_BOUND
Returns a Span wrapping the entire of current array.
Definition: Array.h:103
bool removeAll(Lambda &&criteria)
Removes all items matching criteria given by Lambda.
Definition: Array.h:573
T * end() SC_LANGUAGE_LIFETIME_BOUND
Gets pointer to one after last element of the array.
Definition: Array.h:212
T & operator[](size_t index)
Access item at index.
Definition: Array.h:405
bool remove(const U &value)
Removes all values equal to value
Definition: Array.h:580
bool reserve(size_t newCapacity)
Reserves memory for newCapacity elements, allocating memory if necessary.
Definition: Array.h:166
bool append(Span< const T > data)
Appends a range of items copying them at the end of array.
Definition: Array.h:524
bool resizeWithoutInitializing(size_t newSize)
Resizes this array to newSize, preserving existing elements.
Definition: Array.h:509
size_t size() const
Gets size of the array.
Definition: Array.h:198
bool insert(size_t idx, Span< const T > data)
Inserts a range of items copying them at given index.
Definition: Array.h:517
bool push_back(const T &element)
Appends an element copying it at the end of the Array.
Definition: Array.h:475
bool contains(const U &value, size_t *foundIndex=nullptr) const
Check if the current array contains a given value.
Definition: Array.h:552
bool isEmpty() const
Check if the array is empty.
Definition: Array.h:194
bool appendMove(U &&src)
Appends another array moving its contents at the end of array.
Definition: Array.h:540
T * data() SC_LANGUAGE_LIFETIME_BOUND
Gets pointer to first element of the array.
Definition: Array.h:218
const T * begin() const SC_LANGUAGE_LIFETIME_BOUND
Gets pointer to first element of the array.
Definition: Array.h:209
bool push_front(T &&element)
Moves an element in front of the Array, at position 0.
Definition: Array.h:127
bool pop_back()
Removes the last element of the array.
Definition: Array.h:489
size_t capacity() const
Gets capacity of the array.
Definition: Array.h:202
const T * data() const SC_LANGUAGE_LIFETIME_BOUND
Gets pointer to first element of the array.
Definition: Array.h:221
bool pop_front()
Removes the first element of the array.
Definition: Array.h:495
bool removeAt(size_t index)
Removes an item at a given index.
Definition: Array.h:566
Array & operator=(const Array &other)
Move assigns another array to this one.
Definition: Array.h:419
T * begin() SC_LANGUAGE_LIFETIME_BOUND
Gets pointer to first element of the array.
Definition: Array.h:206
bool push_front(const T &element)
Copies an element in front of the Array, at position 0.
Definition: Array.h:122
void clear()
Removes all elements from container, calling destructor for each of them.
Definition: Array.h:183
T & front()
Access the first element of the Array.
Definition: Array.h:338
T & back()
Access the last element of the Array.
Definition: Array.h:354
void clearWithoutInitializing()
Sets size() to zero, without calling destructor on elements.
Definition: Array.h:186
const T * end() const SC_LANGUAGE_LIFETIME_BOUND
Gets pointer to one after last element of the array.
Definition: Array.h:215
bool find(Lambda &&lambda, size_t *foundIndex=nullptr) const
Finds the first item in array matching criteria given by the lambda.
Definition: Array.h:560
Span< T > toSpan() SC_LANGUAGE_LIFETIME_BOUND
Returns a Span wrapping the entire of current array.
Definition: Array.h:107
~Array()
Destroys the Array, releasing allocated memory.
Definition: Array.h:69
Array()
Constructs an empty Array.
Definition: Array.h:321
bool shrink_to_fit()
This operation is a no-op on Array.
Definition: Array.h:190
String with compile time configurable inline storage (small string optimization)
Definition: SmallString.h:21
A Vector that can hold up to N elements inline and > N on heap.
Definition: SmallVector.h:27
View over a contiguous sequence of items (pointer + size in elements).
Definition: Span.h:21
constexpr const Type * data() const
Returns pointer to first element of the span.
Definition: Span.h:89
constexpr SizeType sizeInElements() const
Size of Span in elements.
Definition: Span.h:105
IsTriviallyCopyable evaluates to true if the type T can be trivially copied, false otherwise.
Definition: TypeTraits.h:60