15template<
int MAX_ALLOCS,
class TYPE>
42 template <
typename ...ELEM_TYPE>
97template<
int MAX_ALLOCS,
class TYPE>
104 this->elements =
nullptr;
110template<
int MAX_ALLOCS,
class TYPE>
120template<
int MAX_ALLOCS,
class TYPE>
127 this->elements =
nullptr;
132 this->GrowTo(capacity);
138template<
int MAX_ALLOCS,
class TYPE>
145 this->elements =
nullptr;
151 this->GrowTo(initialSize);
152 this->count = initialSize;
154 for (i = 0; i < initialSize; i++)
156 this->elements[i] = initialValue;
163template<
int MAX_ALLOCS,
class TYPE>
170 this->elements =
nullptr;
172 static_assert(std::is_trivially_copyable<TYPE>::value,
"TYPE is not trivially copyable; Util::Array cannot be constructed from pointer of TYPE.");
175 const SizeT bytes = num *
sizeof(TYPE);
182template<
int MAX_ALLOCS,
class TYPE>
189 this->elements =
nullptr;
191 this->GrowTo((
SizeT)list.size());
192 this->count = (
SizeT)list.size();
194 for (i = 0; i < this->count; i++)
196 this->elements[i] = list.begin()[i];
203template<
int MAX_ALLOCS,
class TYPE>
213template<
int MAX_ALLOCS,
class TYPE>
219 if ((this->capacity > 0) && (rhs.
count <= this->capacity))
225 if (rhs.
count < this->count)
227 this->DestroyRange(rhs.
count, this->count);
229 this->grow = rhs.
grow;
230 this->count = rhs.
count;
244template<
int MAX_ALLOCS,
class TYPE>
253 if (rhs.elements != rhs.stackElements.data())
255 this->elements = rhs.elements;
256 rhs.elements =
nullptr;
261 this->MoveRange(this->elements, rhs.elements, rhs.count);
264 this->grow = rhs.grow;
265 this->count = rhs.count;
266 this->capacity = rhs.capacity;
276template<
int MAX_ALLOCS,
class TYPE>
277template<
typename ...ELEM_TYPE>
282 const int size =
sizeof...(elements) + 1;
284 TYPE res[size] = { first, elements... };
285 for (
IndexT i = 0; i < size; i++)
287 this->elements[this->count++] = res[i];
294template<
int MAX_ALLOCS,
class TYPE>
299 if (this->count == this->capacity)
303#if NEBULA_BOUNDSCHECKS
306 this->elements[this->count++] = std::move(elm);
312template<
int MAX_ALLOCS,
class TYPE>
317 if (this->count == this->capacity)
321#if NEBULA_BOUNDSCHECKS
324 this->elements[this->count++] = std::move(elm);
330template<
int MAX_ALLOCS,
class TYPE>
335 if (this->count == this->capacity)
339#if NEBULA_BOUNDSCHECKS
342 this->elements[this->count] = TYPE();
343 return this->elements[this->count++];
349template<
int MAX_ALLOCS,
class TYPE>
353#if NEBULA_BOUNDSCHECKS
354 n_assert(index <= this->count && (index >= 0));
356 if (index == this->count)
363 this->Move(index, index + 1);
364 this->elements[index] = elm;
371template<
int MAX_ALLOCS,
class TYPE>
374 SizeT num = this->Size();
379 return this->Size() - 1;
389 if (0 != (
half = num / 2))
391 mid = lo + ((num & 1) ?
half : (
half - 1));
392 if (elm < this->elements[mid])
397 else if (elm > this->elements[mid])
406 return this->InsertAtEndOfIdenticalRange(mid, elm);
411 if (elm < this->elements[lo])
413 this->Insert(lo, elm);
416 else if (elm > this->elements[lo])
418 this->Insert(lo + 1, elm);
425 return this->InsertAtEndOfIdenticalRange(lo, elm);
430#if NEBULA_BOUNDSCHECKS
433 this->Insert(lo, elm);
437 if (elm < this->elements[lo])
439 this->Insert(lo, elm);
442 else if (elm > this->elements[lo])
444 this->Insert(lo + 1, elm);
453 n_error(
"Array::InsertSorted: Can't happen!");
460template<
int MAX_ALLOCS,
class TYPE>
463 IndexT i = startIndex + 1;
464 for (; i < this->count; i++)
466 if (this->elements[i] != elm)
468 this->Insert(i, elm);
475 return (this->Size() - 1);
481template<
int MAX_ALLOCS,
class TYPE>
485 SizeT neededCapacity = this->count + src.
count;
486 if (neededCapacity > this->capacity)
488 this->GrowTo(neededCapacity);
493 for (i = 0; i < src.
count; i++)
495 this->elements[this->count + i] = src.
elements[i];
497 this->count += src.
count;
503template<
int MAX_ALLOCS,
class TYPE>
507 SizeT neededCapacity = this->count + count;
508 if (neededCapacity > this->capacity)
510 this->GrowTo(neededCapacity);
515 for (i = 0; i < count; i++)
517 this->elements[this->count + i] = arr[i];
519 this->count += count;
525template<
int MAX_ALLOCS,
class TYPE>
529 SizeT neededCapacity = this->count + count;
530 if (neededCapacity > this->capacity)
532 this->GrowTo(neededCapacity);
537 for (i = 0; i < count; i++)
539 this->elements[this->count + i] = TYPE();
541 TYPE* first = this->elements[this->count];
542 this->count += count;
549template<
int MAX_ALLOCS,
class TYPE>
553 if ((first + num) > this->count)
555 this->GrowTo(first + num);
556 this->count = first + num;
560 for (i = first; i < (first + num); i++)
562 this->elements[i] = elm;
569template<
int MAX_ALLOCS,
class TYPE>
573#if NEBULA_BOUNDSCHECKS
577 SizeT neededCapacity = this->count + count;
578 if (neededCapacity > this->capacity)
580 this->GrowTo(neededCapacity);
587template<
int MAX_ALLOCS,
class TYPE>
593 this->capacity = capacity;
594 this->count = capacity;
595 if (this->capacity > 0)
597 this->GrowTo(this->capacity);
608template<
int MAX_ALLOCS,
class TYPE>
612 if (num < this->count)
614 this->DestroyRange(num, this->count);
616 else if (num > this->capacity)
627template<
int MAX_ALLOCS,
class TYPE>
631 if (num > this->capacity)
635 this->count =
Math::max(num, this->count);
641template<
int MAX_ALLOCS,
class TYPE>
652template<
int MAX_ALLOCS,
class TYPE>
660 SizeT numFreeablePages = numUsedPages - numNeededPages;
663 this->capacity = this->count;
669template<
int MAX_ALLOCS,
class TYPE>
673#if NEBULA_BOUNDSCHECKS
678 if (0 == this->capacity)
680 growToSize = this->grow;
685 SizeT growBy = this->capacity >> 1;
694 growToSize = this->capacity + growBy;
696 this->GrowTo(growToSize);
702template<
int MAX_ALLOCS,
class TYPE>
706 if (this->elements ==
nullptr)
716 SizeT totalByteSize = newCapacity *
sizeof(TYPE);
722 if (totalBytesNeeded > MAX_ALLOCS *
sizeof(TYPE))
724 n_printf(
"[PinnedArray] MAX_ALLOCS '%d' and item size '%d' will waste '%d' byte(s) due to alignment of page size '%d'", MAX_ALLOCS,
sizeof(TYPE), totalBytesNeeded - MAX_ALLOCS *
sizeof(TYPE), pageSize);
727 SizeT roundedUpNewCapacity = totalBytesNeeded /
sizeof(TYPE);
729 if (totalBytesNeeded > offset)
732 SizeT commitSize =
Math::align((roundedUpNewCapacity - this->capacity) *
sizeof(TYPE), pageSize);
733 this->capacity = roundedUpNewCapacity;
742template<
int MAX_ALLOCS,
class TYPE>
748 if (this->capacity > 0)
751 this->DestroyRange(0, this->count);
754 this->elements =
nullptr;
762template<
int MAX_ALLOCS,
class TYPE>
766#if NEBULA_BOUNDSCHECKS
768 n_assert(this->stackElements.data() == this->elements);
772 this->grow = src.
grow;
773 this->count = src.
count;
775 for (i = 0; i < this->count; i++)
777 this->elements[i] = src.
elements[i];
784template<
int MAX_ALLOCS,
class TYPE>
788#if NEBULA_BOUNDSCHECKS
794 if (fromIndex == toIndex)
800 SizeT num = this->count - fromIndex;
803 SizeT neededSize = toIndex + num;
804 while (neededSize > this->capacity)
809 if (fromIndex > toIndex)
812 this->MoveRange(&this->elements[toIndex], &this->elements[fromIndex], num);
813 this->DestroyRange(fromIndex + num - 1, this->count);
819 for (i = num - 1; i >= 0; --i)
821 this->elements[toIndex + i] = this->elements[fromIndex + i];
825 this->DestroyRange(fromIndex, toIndex);
829 this->count = toIndex + num;
Nebula's dynamic array class.
Definition array.h:60
SizeT capacity
Definition array.h:248
SizeT count
Definition array.h:249
TYPE * elements
Definition array.h:250
SizeT grow
Definition array.h:247
Definition pinnedarray.h:17
void Copy(const PinnedArray< MAX_ALLOCS, TYPE > &src)
Copy from array.
Definition pinnedarray.h:764
IndexT InsertSorted(const TYPE &elm)
insert element into sorted array, return index where element was included
Definition pinnedarray.h:372
~PinnedArray()
Destructor.
Definition pinnedarray.h:205
void Delete()
Delete array.
Definition pinnedarray.h:744
PinnedArray(SizeT capacity, SizeT grow)
Construct from capacity and grow.
Definition pinnedarray.h:122
void GrowTo(SizeT newCapacity)
Grow array by size.
Definition pinnedarray.h:704
void Append(const TYPE &&elm)
Append single element as rhs.
Definition pinnedarray.h:314
PinnedArray(std::initializer_list< TYPE > list)
Construct from initializer list.
Definition pinnedarray.h:184
IndexT InsertAtEndOfIdenticalRange(IndexT startIndex, const TYPE &elm)
insert element at the first non-identical position, return index of inclusion position
Definition pinnedarray.h:461
void AppendArray(const TYPE *arr, const SizeT count)
Append contents of C array.
Definition pinnedarray.h:505
void Move(IndexT fromIndex, IndexT toIndex)
move elements, grows array if needed
Definition pinnedarray.h:786
void Reserve(const SizeT count)
Reserve an amount of memory (commits to memory)
Definition pinnedarray.h:571
void AppendArray(const PinnedArray< MAX_ALLOCS, TYPE > &src)
Append contents of another array.
Definition pinnedarray.h:483
void Fit()
Fit array to capacity.
Definition pinnedarray.h:654
void Realloc(SizeT capacity, SizeT grow)
Reallocate and clear.
Definition pinnedarray.h:589
void Insert(IndexT index, const TYPE &elm)
insert element before element at index
Definition pinnedarray.h:351
PinnedArray(SizeT initialSize, SizeT grow, const TYPE &initialValue)
Construct from initial commit size, grow and value.
Definition pinnedarray.h:140
TYPE * EmplaceArray(const SizeT count)
Emplace an array of elements and return pointer.
Definition pinnedarray.h:527
void Resize(SizeT num)
Resize to fit, destroys elements outside of new size.
Definition pinnedarray.h:610
TYPE & Emplace()
Emplace element and return reference to it.
Definition pinnedarray.h:332
void Extend(SizeT num)
Resize to fit the provided value, but don't shrink if the new size is smaller.
Definition pinnedarray.h:629
void Fill(IndexT first, SizeT num, const TYPE &elm)
Fill array with element.
Definition pinnedarray.h:551
void operator=(const PinnedArray< MAX_ALLOCS, TYPE > &rhs)
assignment operator
Definition pinnedarray.h:215
PinnedArray(const TYPE *const buf, SizeT num)
Construct from pointer and size.
Definition pinnedarray.h:165
void Grow()
Grow array using growth parameter.
Definition pinnedarray.h:671
void Append(const TYPE &elm)
Append single element.
Definition pinnedarray.h:296
void Append(const TYPE &first, const ELEM_TYPE &... elements)
Append multiple elements to the end of the array.
Definition pinnedarray.h:279
PinnedArray(const PinnedArray< MAX_ALLOCS, TYPE > &rhs)
Construct from other pinned array.
Definition pinnedarray.h:112
void Free()
Free memory.
Definition pinnedarray.h:643
void operator=(PinnedArray< MAX_ALLOCS, TYPE > &&rhs) noexcept
move operator
Definition pinnedarray.h:246
PinnedArray()
Default constructor.
Definition pinnedarray.h:99
void __cdecl n_error(const char *msg,...)
This function is called when a serious situation is encountered which requires abortion of the applic...
Definition debug.cc:138
void __cdecl n_printf(const char *msg,...)
Nebula's printf replacement.
Definition debug.cc:209
#define n_assert(exp)
Definition debug.h:50
__forceinline unsigned int align(unsigned int alignant, unsigned int alignment)
Definition scalar.h:722
__forceinline TYPE max(TYPE a, TYPE b)
Definition scalar.h:359
__forceinline void FreeVirtual(void *ptr, size_t size)
free virtual memory
Definition posixmemory.h:146
void Copy(const void *from, void *to, size_t numBytes)
Copy a chunk of memory (note the argument order is different from memcpy()!!!)
Definition osxmemory.cc:213
__forceinline void CommitVirtual(void *ptr, size_t size)
commit virtual memory
Definition posixmemory.h:135
__forceinline void * AllocVirtual(size_t size)
allocate a range of virtual memory space
Definition posixmemory.h:112
__forceinline void DecommitVirtual(void *ptr, size_t size)
decommit virtual memory
Definition posixmemory.h:123
SizeT PageSize
Definition posixsysteminfo.cc:14
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6
static const int InvalidIndex
Definition types.h:54
int SizeT
Definition types.h:49
int IndexT
Definition types.h:48