Nebula
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
34#include "core/types.h"
35#include "system/systeminfo.h"
36#include "math/scalar.h"
37#include <type_traits>
38
39
40
41//------------------------------------------------------------------------------
42namespace Util
43{
44
45template<class TYPE, int STACK_SIZE>
47{
48 TYPE* data() { return stackElements; }
49private:
50 TYPE stackElements[STACK_SIZE];
51};
52
53template<class TYPE>
54struct _smallvector<TYPE, 0>
55{
56 TYPE* data() { return nullptr; }
57};
58
59template<class TYPE, int SMALL_VECTOR_SIZE = 0> class Array
60{
61public:
63 typedef TYPE* Iterator;
64 typedef const TYPE* ConstIterator;
65
67
71 Array(SizeT initialCapacity, SizeT initialGrow);
73 Array(SizeT initialSize, SizeT initialGrow, const TYPE& initialValue);
75 Array(const ArrayT& rhs);
77 Array(ArrayT&& rhs) noexcept;
79 Array(std::initializer_list<TYPE> list);
81 Array(std::nullptr_t);
83 Array(const TYPE* const buf, SizeT num);
86
92 TYPE& operator[](IndexT index) const;
94 TYPE& operator[](IndexT index);
100 template<typename T> T As() const;
101
103 TYPE& Get(IndexT index) const;
104
106 template <typename ...ELEM_TYPE>
107 void Append(const TYPE& first, const ELEM_TYPE&... elements);
109 void Append(const TYPE& elm);
111 void Append(TYPE&& elm);
115 void AppendArray(const TYPE* arr, const SizeT count);
117 TYPE& Emplace();
121 void Reserve(SizeT num);
122
124 const SizeT Size() const;
126 const SizeT ByteSize() const;
128 const SizeT Capacity() const;
130 TYPE& Front() const;
132 TYPE& Back() const;
134 bool IsEmpty() const;
136 bool IsValidIndex(IndexT index) const;
138 void EraseIndex(IndexT index);
148 void EraseBack();
152 TYPE PopFront();
154 TYPE PopBack();
156 void Insert(IndexT index, const TYPE& elm);
158 IndexT InsertSorted(const TYPE& elm);
160 IndexT InsertAtEndOfIdenticalRange(IndexT startIndex, const TYPE& elm);
162 bool IsSorted() const;
164 void Clear();
166 void Reset();
168 void Free();
174 Iterator End() const;
178 Iterator Find(const TYPE& elm, const IndexT start = 0) const;
180 IndexT FindIndex(const TYPE& elm, const IndexT start = 0) const;
182 template <typename KEYTYPE> IndexT FindIndex(typename std::enable_if<true, const KEYTYPE&>::type elm, const IndexT start = 0) const;
184 void Fill(IndexT first, SizeT num, const TYPE& elm);
190 void Sort();
192 void QuickSort();
194 void SortWithFunc(bool (*func)(const TYPE& lhs, const TYPE& rhs));
196 void QuickSortWithFunc(int (*func)(const void* lhs, const void* rhs));
198 IndexT BinarySearchIndex(const TYPE& elm) const;
200 template <typename KEYTYPE> IndexT BinarySearchIndex(typename std::enable_if<true, const KEYTYPE&>::type elm) const;
201
203 void Resize(SizeT num);
205 template <typename ...ARGS> void Resize(SizeT num, ARGS... args);
207 void Extend(SizeT num);
209 void Fit();
210
212 constexpr SizeT TypeSize() const;
213
216 Iterator end() const;
217 size_t size() const;
218 void resize(size_t size);
219 void clear() noexcept;
220 void push_back(const TYPE& item);
221
223 void Grow();
224protected:
225
227 void Destroy(TYPE* elm);
229 void Copy(const Array<TYPE, SMALL_VECTOR_SIZE>& src);
231 void Delete();
233 void GrowTo(SizeT newCapacity);
235 void Move(IndexT fromIndex, IndexT toIndex);
237 void DestroyRange(IndexT fromIndex, IndexT toIndex);
239 void CopyRange(TYPE* to, TYPE* from, SizeT num);
241 void MoveRange(TYPE* to, TYPE* from, SizeT num);
242
243 static const SizeT MinGrowSize = 16;
244 static const SizeT MaxGrowSize = 65536; // FIXME: big grow size needed for mesh tools
245 SizeT grow; // grow by this number of elements if array exhausted
246 SizeT capacity; // number of elements allocated
247 SizeT count; // number of elements in array
248 TYPE* elements; // pointer to element array
249
250 _smallvector<TYPE, SMALL_VECTOR_SIZE> stackElements;
251};
252
253//------------------------------------------------------------------------------
256template<class TYPE, int SMALL_VECTOR_SIZE>
257Array<TYPE, SMALL_VECTOR_SIZE>::Array() :
258 grow(16),
259 capacity(SMALL_VECTOR_SIZE),
260 count(0),
261 elements(this->stackElements.data())
262{
263}
264
265//------------------------------------------------------------------------------
268template<class TYPE, int SMALL_VECTOR_SIZE>
270 grow(_grow),
271 capacity(SMALL_VECTOR_SIZE),
272 count(0),
273 elements(this->stackElements.data())
274{
275 if (0 == this->grow)
276 {
277 this->grow = 16;
278 }
279 this->GrowTo(_capacity);
280}
281
282//------------------------------------------------------------------------------
285template<class TYPE, int SMALL_VECTOR_SIZE>
286Array<TYPE, SMALL_VECTOR_SIZE>::Array(SizeT initialSize, SizeT _grow, const TYPE& initialValue) :
287 grow(_grow),
288 capacity(SMALL_VECTOR_SIZE),
289 count(0),
290 elements(stackElements.data())
291{
292 if (0 == this->grow)
293 {
294 this->grow = 16;
295 }
296
297 this->GrowTo(initialSize);
298 this->count = initialSize;
299 IndexT i;
300 for (i = 0; i < initialSize; i++)
301 {
302 this->elements[i] = initialValue;
303 }
304}
305
306//------------------------------------------------------------------------------
309template<class TYPE, int SMALL_VECTOR_SIZE>
310Array<TYPE, SMALL_VECTOR_SIZE>::Array(const TYPE* const buf, SizeT num) :
311 grow(16),
312 capacity(SMALL_VECTOR_SIZE),
313 count(0),
314 elements(stackElements.data())
315{
316 static_assert(std::is_trivially_copyable<TYPE>::value, "TYPE is not trivially copyable; Util::Array cannot be constructed from pointer of TYPE.");
317 this->GrowTo(num);
318 this->count = num;
319 const SizeT bytes = num * sizeof(TYPE);
320 Memory::Copy(buf, this->elements, bytes);
321}
322
323//------------------------------------------------------------------------------
326template<class TYPE, int SMALL_VECTOR_SIZE>
327Array<TYPE, SMALL_VECTOR_SIZE>::Array(std::initializer_list<TYPE> list) :
328 grow(16),
329 capacity(SMALL_VECTOR_SIZE),
330 count(0),
331 elements(stackElements.data())
332{
333 this->GrowTo((SizeT)list.size());
334 this->count = (SizeT)list.size();
335 IndexT i;
336 for (i = 0; i < this->count; i++)
337 {
338 this->elements[i] = list.begin()[i];
339 }
340}
341
342//------------------------------------------------------------------------------
345template<class TYPE, int SMALL_VECTOR_SIZE>
347 grow(16),
348 capacity(SMALL_VECTOR_SIZE),
349 count(0),
350 elements(stackElements.data())
351{
352}
353
354//------------------------------------------------------------------------------
357template<class TYPE, int SMALL_VECTOR_SIZE>
359 grow(16),
360 capacity(SMALL_VECTOR_SIZE),
361 count(0),
362 elements(this->stackElements.data())
363{
364 this->Copy(rhs);
365}
366
367//------------------------------------------------------------------------------
370template<class TYPE, int SMALL_VECTOR_SIZE>
372 grow(rhs.grow),
373 capacity(rhs.capacity),
374 count(rhs.count),
375 elements(this->stackElements.data())
376{
377 // If data is on the stack, copy data over
378 if (rhs.capacity <= SMALL_VECTOR_SIZE)
379 {
380 for (IndexT i = 0; i < rhs.capacity; i++)
381 this->elements[i] = rhs.elements[i];
382 }
383 else
384 {
385 // Otherwise, exchange pointers and invalidate
386 this->elements = rhs.elements;
387 rhs.elements = rhs.stackElements.data();
388 }
389 rhs.count = 0;
390 rhs.capacity = SMALL_VECTOR_SIZE;
391}
392
393//------------------------------------------------------------------------------
396template<class TYPE, int SMALL_VECTOR_SIZE>
397void
399{
400 #if NEBULA_BOUNDSCHECKS
401 // Make sure array is either empty, or stack array before copy
402 n_assert(this->stackElements.data() == this->elements);
403 #endif
404
405 this->GrowTo(src.capacity);
406 this->grow = src.grow;
407 this->count = src.count;
408 IndexT i;
409 for (i = 0; i < this->count; i++)
410 {
411 this->elements[i] = src.elements[i];
412 }
413}
414
415//------------------------------------------------------------------------------
418template<class TYPE, int SMALL_VECTOR_SIZE>
419void
421{
422 this->grow = 16;
423
424 if (this->capacity > 0)
425 {
426 if (this->elements != this->stackElements.data())
427 {
428 ArrayFree(this->capacity, this->elements);
429 }
430 else
431 {
432 // If in small vector, run destructor
433 this->DestroyRange(0, this->count);
434 }
435 }
436 this->elements = this->stackElements.data();
437 this->count = 0;
438 this->capacity = SMALL_VECTOR_SIZE;
439}
440
441//------------------------------------------------------------------------------
444template<class TYPE, int SMALL_VECTOR_SIZE> void
446{
447 elm->~TYPE();
448}
449
450//------------------------------------------------------------------------------
453template<class TYPE, int SMALL_VECTOR_SIZE>
455{
456 this->Delete();
457}
458
459//------------------------------------------------------------------------------
462template<class TYPE, int SMALL_VECTOR_SIZE> void
464{
465 this->Delete();
466 this->grow = _grow;
467 this->capacity = _capacity;
468 this->count = _capacity;
469 if (this->capacity > 0)
470 {
471 this->GrowTo(this->capacity);
472 }
473 else
474 {
475 this->elements = 0;
476 }
477}
478
479//------------------------------------------------------------------------------
482template<class TYPE, int SMALL_VECTOR_SIZE> void
484{
485 if (this != &rhs)
486 {
487 if ((this->capacity > 0) && (rhs.count <= this->capacity))
488 {
489 // source array fits into our capacity, copy in place
490 n_assert(0 != this->elements);
491
492 this->CopyRange(this->elements, rhs.elements, rhs.count);
493 if (rhs.count < this->count)
494 {
495 this->DestroyRange(rhs.count, this->count);
496 }
497 this->grow = rhs.grow;
498 this->count = rhs.count;
499 }
500 else
501 {
502 // source array doesn't fit into our capacity, need to reallocate
503 this->Delete();
504 this->Copy(rhs);
505 }
506 }
507}
508
509//------------------------------------------------------------------------------
512template<class TYPE, int SMALL_VECTOR_SIZE> void
514{
515 if (this != &rhs)
516 {
517 this->Delete();
518
519 // If rhs is not using stack, simply reassign pointers
520 if (rhs.elements != rhs.stackElements.data())
521 {
522 this->elements = rhs.elements;
523 rhs.elements = nullptr;
524 }
525 else
526 {
527 // Otherwise, move every element over to the stack of this array
528 this->MoveRange(this->elements, rhs.elements, rhs.count);
529 }
530
531 this->grow = rhs.grow;
532 this->count = rhs.count;
533 this->capacity = rhs.capacity;
534 rhs.count = 0;
535 rhs.capacity = 0;
536 }
537}
538
539//------------------------------------------------------------------------------
542template<class TYPE, int SMALL_VECTOR_SIZE> void
544{
545 if (newCapacity > SMALL_VECTOR_SIZE)
546 {
547 TYPE* newArray = ArrayAlloc<TYPE>(newCapacity);
548 if (this->elements)
549 {
550 this->MoveRange(newArray, this->elements, this->count);
551
552 // discard old array if not the stack array
553 if (this->elements != this->stackElements.data())
554 ArrayFree(this->capacity, this->elements);
555 }
556 this->elements = newArray;
557 this->capacity = newCapacity;
558 }
559}
560
561//------------------------------------------------------------------------------
564template<class TYPE, int SMALL_VECTOR_SIZE>
565void
567{
568 #if NEBULA_BOUNDSCHECKS
569 n_assert(this->grow > 0);
570 #endif
571
572 SizeT growToSize;
573 if (0 == this->capacity)
574 {
575 growToSize = this->grow;
576 }
577 else
578 {
579 // grow by half of the current capacity, but never more then MaxGrowSize
580 SizeT growBy = this->capacity >> 1;
581 if (growBy == 0)
582 {
583 growBy = MinGrowSize;
584 }
585 else if (growBy > MaxGrowSize)
586 {
587 growBy = MaxGrowSize;
588 }
589 growToSize = this->capacity + growBy;
590 }
591 this->GrowTo(growToSize);
592}
593
594//------------------------------------------------------------------------------
599template<class TYPE, int SMALL_VECTOR_SIZE>
600void
602{
603 #if NEBULA_BOUNDSCHECKS
604 n_assert(this->elements);
605 n_assert(fromIndex < this->count);
606 #endif
607
608 // nothing to move?
609 if (fromIndex == toIndex)
610 {
611 return;
612 }
613
614 // compute number of elements to move
615 SizeT num = this->count - fromIndex;
616
617 // check if array needs to grow
618 SizeT neededSize = toIndex + num;
619 while (neededSize > this->capacity)
620 {
621 this->Grow();
622 }
623
624 if (fromIndex > toIndex)
625 {
626 // this is a backward move
627 this->MoveRange(&this->elements[toIndex], &this->elements[fromIndex], num);
628 this->DestroyRange(fromIndex + num - 1, this->count);
629 }
630 else
631 {
632 // this is a forward move
633 int i; // NOTE: this must remain signed for the following loop to work!!!
634 for (i = num - 1; i >= 0; --i)
635 {
636 this->elements[toIndex + i] = this->elements[fromIndex + i];
637 }
638
639 // destroy freed elements
640 this->DestroyRange(fromIndex, toIndex);
641 }
642
643 // adjust array size
644 this->count = toIndex + num;
645}
646
647//------------------------------------------------------------------------------
650template<class TYPE, int SMALL_VECTOR_SIZE>
651inline void
653{
654 if constexpr (!std::is_trivially_destructible<TYPE>::value)
655 {
656 for (IndexT i = fromIndex; i < toIndex; i++)
657 {
658 this->Destroy(&(this->elements[i]));
659 }
660 }
661 else
662 {
663 Memory::Clear((void*)&this->elements[fromIndex], sizeof(TYPE) * (toIndex - fromIndex));
664 }
665}
666
667//------------------------------------------------------------------------------
670template<class TYPE, int SMALL_VECTOR_SIZE>
671inline void
673{
674 // this is a backward move
675 if constexpr (!std::is_trivially_copyable<TYPE>::value)
676 {
677 IndexT i;
678 for (i = 0; i < num; i++)
679 {
680 to[i] = from[i];
681 }
682 }
683 else
684 {
685 Memory::CopyElements(from, to, num);
686 }
687}
688
689//------------------------------------------------------------------------------
692template<class TYPE, int SMALL_VECTOR_SIZE>
693inline void
695{
696 // copy over contents
697 if constexpr (!std::is_trivially_move_assignable<TYPE>::value && std::is_move_assignable<TYPE>::value)
698 {
699 IndexT i;
700 for (i = 0; i < num; i++)
701 {
702 to[i] = std::move(from[i]);
703 }
704 }
705 else
706 {
707 Memory::MoveElements(from, to, num);
708 }
709}
710
711//------------------------------------------------------------------------------
714template<class TYPE, int SMALL_VECTOR_SIZE>
715inline TYPE&
717{
718#if NEBULA_BOUNDSCHECKS
719 n_assert(this->elements != nullptr);
720 n_assert(this->capacity > index);
721#endif
722 return this->elements[index];
723}
724
725//------------------------------------------------------------------------------
728template<class TYPE, int SMALL_VECTOR_SIZE>
729void
731{
732 // grow allocated space if exhausted
733 if (this->count == this->capacity)
734 {
735 this->Grow();
736 }
737 #if NEBULA_BOUNDSCHECKS
738 n_assert(this->elements);
739 #endif
740 this->elements[this->count++] = elm;
741}
742
743//------------------------------------------------------------------------------
746template<class TYPE, int SMALL_VECTOR_SIZE>
747void
749{
750 // grow allocated space if exhausted
751 if (this->count == this->capacity)
752 {
753 this->Grow();
754 }
755#if NEBULA_BOUNDSCHECKS
756 n_assert(this->elements);
757#endif
758 this->elements[this->count++] = std::move(elm);
759}
760
761//------------------------------------------------------------------------------
764template<class TYPE, int SMALL_VECTOR_SIZE>
765void
767{
768 SizeT neededCapacity = this->count + rhs.count;
769 if (neededCapacity > this->capacity)
770 {
771 this->GrowTo(neededCapacity);
772 }
773
774 // forward elements from array
775 IndexT i;
776 for (i = 0; i < rhs.count; i++)
777 {
778 this->elements[this->count + i] = rhs.elements[i];
779 }
780 this->count += rhs.count;
781}
782
783//------------------------------------------------------------------------------
786template<class TYPE, int SMALL_VECTOR_SIZE>
787void
789{
790 SizeT neededCapacity = this->count + count;
791 if (neededCapacity > this->capacity)
792 {
793 this->GrowTo(neededCapacity);
794 }
795
796 // forward elements from array
797 IndexT i;
798 for (i = 0; i < count; i++)
799 {
800 this->elements[this->count + i] = arr[i];
801 }
802 this->count += count;
803}
804
805//------------------------------------------------------------------------------
808template<class TYPE, int SMALL_VECTOR_SIZE>
809TYPE&
811{
812 // grow allocated space if exhausted
813 if (this->count == this->capacity)
814 {
815 this->Grow();
816 }
817#if NEBULA_BOUNDSCHECKS
818 n_assert(this->elements);
819#endif
820 this->elements[this->count] = TYPE();
821 return this->elements[this->count++];
822}
823
824//------------------------------------------------------------------------------
827template<class TYPE, int SMALL_VECTOR_SIZE>
828TYPE*
830{
831 SizeT neededCapacity = this->count + count;
832 if (neededCapacity > this->capacity)
833 {
834 this->GrowTo(neededCapacity);
835 }
836
837 // forward elements from array
838 IndexT i;
839 for (i = 0; i < count; i++)
840 {
841 this->elements[this->count + i] = TYPE();
842 }
843 TYPE* first = this->elements[this->count];
844 this->count += count;
845 return first;
846}
847
848//------------------------------------------------------------------------------
858template<class TYPE, int SMALL_VECTOR_SIZE>
859void
861{
862#if NEBULA_BOUNDSCHECKS
863 n_assert(num >= 0);
864#endif
865
866 SizeT neededCapacity = this->count + num;
867 if (neededCapacity > this->capacity)
868 {
869 this->GrowTo(neededCapacity);
870 }
871}
872
873//------------------------------------------------------------------------------
876template<class TYPE, int SMALL_VECTOR_SIZE>
877const SizeT
879{
880 return this->count;
881}
882
883//------------------------------------------------------------------------------
886template<class TYPE, int SMALL_VECTOR_SIZE>
887const SizeT
889{
890 return this->count * sizeof(TYPE);
891}
892
893//------------------------------------------------------------------------------
896template<class TYPE, int SMALL_VECTOR_SIZE>
897const SizeT
899{
900 return this->capacity;
901}
902
903//------------------------------------------------------------------------------
908template<class TYPE, int SMALL_VECTOR_SIZE>
909TYPE&
911{
912 #if NEBULA_BOUNDSCHECKS
913 n_assert(this->elements && (index < this->count) && (index >= 0));
914 #endif
915 return this->elements[index];
916}
917
918//------------------------------------------------------------------------------
923template<class TYPE, int SMALL_VECTOR_SIZE>
924TYPE&
926{
927#if NEBULA_BOUNDSCHECKS
928 n_assert(this->elements && (index < this->count) && (index >= 0));
929#endif
930 return this->elements[index];
931}
932
933//------------------------------------------------------------------------------
938template<class TYPE, int SMALL_VECTOR_SIZE>
939bool
941{
942 if (rhs.Size() == this->Size())
943 {
944 IndexT i;
945 SizeT num = this->Size();
946 for (i = 0; i < num; i++)
947 {
948 if (!(this->elements[i] == rhs.elements[i]))
949 {
950 return false;
951 }
952 }
953 return true;
954 }
955 else
956 {
957 return false;
958 }
959}
960
961//------------------------------------------------------------------------------
966template<class TYPE, int SMALL_VECTOR_SIZE>
967bool
969{
970 return !(*this == rhs);
971}
972
973//------------------------------------------------------------------------------
976template<class TYPE, int SMALL_VECTOR_SIZE>
977TYPE&
979{
980 #if NEBULA_BOUNDSCHECKS
981 n_assert(this->elements && (this->count > 0));
982 #endif
983 return this->elements[0];
984}
985
986//------------------------------------------------------------------------------
989template<class TYPE, int SMALL_VECTOR_SIZE>
990TYPE&
992{
993 #if NEBULA_BOUNDSCHECKS
994 n_assert(this->elements && (this->count > 0));
995 #endif
996 return this->elements[this->count - 1];
997}
998
999//------------------------------------------------------------------------------
1002template<class TYPE, int SMALL_VECTOR_SIZE>
1003void
1005{
1006 this->Append(item);
1007}
1008
1009//------------------------------------------------------------------------------
1012template<class TYPE, int SMALL_VECTOR_SIZE>
1013bool
1015{
1016 return (this->count == 0);
1017}
1018
1019//------------------------------------------------------------------------------
1022template<class TYPE, int SMALL_VECTOR_SIZE>
1023bool
1025{
1026 return this->elements && (index < this->count) && (index >= 0);
1027}
1028
1029//------------------------------------------------------------------------------
1032template<class TYPE, int SMALL_VECTOR_SIZE>
1033void
1035{
1036 #if NEBULA_BOUNDSCHECKS
1037 n_assert(this->elements && (index < this->count) && (index >= 0));
1038 #endif
1039 if (index == (this->count - 1))
1040 {
1041 // special case: last element
1042 this->EraseBack();
1043 }
1044 else
1045 {
1046 this->Move(index + 1, index);
1047 }
1048}
1049
1050//------------------------------------------------------------------------------
1054template<class TYPE, int SMALL_VECTOR_SIZE>
1055void
1057{
1058 #if NEBULA_BOUNDSCHECKS
1059 n_assert(this->elements && (index < this->count) && (index >= 0));
1060 #endif
1061
1062 // swap with last element, and destroy last element
1063 IndexT lastElementIndex = this->count - 1;
1064 if (index < lastElementIndex)
1065 {
1066 if constexpr (!std::is_trivially_move_assignable<TYPE>::value)
1067 this->elements[index] = std::move(this->elements[lastElementIndex]);
1068 else
1069 this->elements[index] = this->elements[lastElementIndex];
1070 }
1071 this->count--;
1072}
1073
1074//------------------------------------------------------------------------------
1077template<class TYPE, int SMALL_VECTOR_SIZE>
1080{
1081 #if NEBULA_BOUNDSCHECKS
1082 n_assert(this->elements && (iter >= this->elements) && (iter < (this->elements + this->count)));
1083 #endif
1084 this->EraseIndex(IndexT(iter - this->elements));
1085 return iter;
1086}
1087
1088//------------------------------------------------------------------------------
1092template<class TYPE, int SMALL_VECTOR_SIZE>
1095{
1096 #if NEBULA_BOUNDSCHECKS
1097 n_assert(this->elements && (iter >= this->elements) && (iter < (this->elements + this->count)));
1098 #endif
1099 this->EraseIndexSwap(IndexT(iter - this->elements));
1100 return iter;
1101}
1102
1103//------------------------------------------------------------------------------
1106template<class TYPE, int SMALL_VECTOR_SIZE>
1107void
1109{
1110 n_assert(end >= start);
1111 n_assert(end <= this->count);
1112 if (start == end)
1113 this->EraseIndex(start);
1114 else
1115 {
1116 // add 1 to end to remove and move including that element
1117 this->DestroyRange(start, end);
1118 SizeT numMove = this->count - end;
1119 this->MoveRange(&this->elements[start], &this->elements[end], numMove);
1120 this->count -= end - start;
1121 }
1122}
1123
1124//------------------------------------------------------------------------------
1127template<class TYPE, int SMALL_VECTOR_SIZE>
1128void
1130{
1131 n_assert(this->count > 0);
1132 if constexpr (!std::is_trivially_destructible<TYPE>::value)
1133 this->Destroy(&(this->elements[this->count - 1]));
1134 this->count--;
1135}
1136
1137//------------------------------------------------------------------------------
1140template<class TYPE, int SMALL_VECTOR_SIZE>
1141void
1143{
1144 this->EraseIndex(0);
1145}
1146
1147//------------------------------------------------------------------------------
1150template<class TYPE, int SMALL_VECTOR_SIZE>
1151inline TYPE
1153{
1154#if NEBULA_BOUNDSCHECKS
1155 n_assert(this->count > 0);
1156#endif
1157 TYPE ret = std::move(this->elements[0]);
1158 this->EraseIndex(0);
1159 return ret;
1160}
1161
1162//------------------------------------------------------------------------------
1165template<class TYPE, int SMALL_VECTOR_SIZE>
1166inline TYPE
1168{
1169#if NEBULA_BOUNDSCHECKS
1170 n_assert(this->count > 0);
1171#endif
1172 this->count--;
1173 return std::move(this->elements[this->count]);
1174}
1175
1176//------------------------------------------------------------------------------
1179template<class TYPE, int SMALL_VECTOR_SIZE>
1180void
1182{
1183 #if NEBULA_BOUNDSCHECKS
1184 n_assert(index <= this->count && (index >= 0));
1185 #endif
1186 if (index == this->count)
1187 {
1188 // special case: append element to back
1189 this->Append(elm);
1190 }
1191 else
1192 {
1193 this->Move(index, index + 1);
1194 this->elements[index] = elm;
1195 }
1196}
1197
1198//------------------------------------------------------------------------------
1203template<class TYPE, int SMALL_VECTOR_SIZE>
1204void
1206{
1207 if (this->count > 0)
1208 {
1209 this->DestroyRange(0, this->count);
1210 this->count = 0;
1211 }
1212}
1213
1214//------------------------------------------------------------------------------
1219template<class TYPE, int SMALL_VECTOR_SIZE>
1220void
1222{
1223 this->count = 0;
1224}
1225
1226//------------------------------------------------------------------------------
1230template<class TYPE, int SMALL_VECTOR_SIZE>
1231void
1233{
1234 this->Delete();
1235 this->grow = 16;
1236}
1237
1238//------------------------------------------------------------------------------
1241template<class TYPE, int SMALL_VECTOR_SIZE>
1244{
1245 return this->elements;
1246}
1247
1248//------------------------------------------------------------------------------
1251template<class TYPE, int SMALL_VECTOR_SIZE>
1254{
1255 return static_cast<Array<TYPE, SMALL_VECTOR_SIZE>::ConstIterator>(this->elements);
1256}
1257
1258//------------------------------------------------------------------------------
1261template<class TYPE, int SMALL_VECTOR_SIZE>
1264{
1265 return this->elements + this->count;
1266}
1267
1268//------------------------------------------------------------------------------
1271template<class TYPE, int SMALL_VECTOR_SIZE>
1274{
1275 return static_cast<Array<TYPE, SMALL_VECTOR_SIZE>::ConstIterator>(this->elements + this->count);
1276}
1277
1278//------------------------------------------------------------------------------
1286template<class TYPE, int SMALL_VECTOR_SIZE>
1288Array<TYPE, SMALL_VECTOR_SIZE>::Find(const TYPE& elm, const IndexT start) const
1289{
1290 n_assert(start <= this->count);
1291 IndexT index;
1292 for (index = start; index < this->count; index++)
1293 {
1294 if (this->elements[index] == elm)
1295 {
1296 return &(this->elements[index]);
1297 }
1298 }
1299 return 0;
1300}
1301
1302//------------------------------------------------------------------------------
1310template<class TYPE, int SMALL_VECTOR_SIZE>
1311IndexT
1312Array<TYPE, SMALL_VECTOR_SIZE>::FindIndex(const TYPE& elm, const IndexT start) const
1313{
1314 n_assert(start <= this->count);
1315 IndexT index;
1316 for (index = start; index < this->count; index++)
1317 {
1318 if (this->elements[index] == elm)
1319 {
1320 return index;
1321 }
1322 }
1323 return InvalidIndex;
1324}
1325
1326//------------------------------------------------------------------------------
1329template<class TYPE, int SMALL_VECTOR_SIZE>
1330template<typename ...ELEM_TYPE>
1331inline void
1332Array<TYPE, SMALL_VECTOR_SIZE>::Append(const TYPE& first, const ELEM_TYPE&... elements)
1333{
1334 // The plus one is for the first element
1335 const int size = sizeof...(elements) + 1;
1336 this->Reserve(size);
1337 TYPE res[size] = { first, elements... };
1338 for (IndexT i = 0; i < size; i++)
1339 {
1340 this->elements[this->count++] = res[i];
1341 }
1342}
1343
1344//------------------------------------------------------------------------------
1359template<class TYPE, int SMALL_VECTOR_SIZE>
1360template<typename KEYTYPE>
1361inline IndexT
1362Array<TYPE, SMALL_VECTOR_SIZE>::FindIndex(typename std::enable_if<true, const KEYTYPE&>::type elm, const IndexT start) const
1363{
1364 n_assert(start <= this->count);
1365 IndexT index;
1366 for (index = start; index < this->count; index++)
1367 {
1368 if (this->elements[index] == elm)
1369 {
1370 return index;
1371 }
1372 }
1373 return InvalidIndex;
1374}
1375
1376//------------------------------------------------------------------------------
1385template<class TYPE, int SMALL_VECTOR_SIZE>
1386void
1388{
1389 if ((first + num) > this->count)
1390 {
1391 this->GrowTo(first + num);
1392 this->count = first + num;
1393 }
1394
1395 IndexT i;
1396 for (i = first; i < (first + num); i++)
1397 {
1398 this->elements[i] = elm;
1399 }
1400}
1401
1402//------------------------------------------------------------------------------
1409template<class TYPE, int SMALL_VECTOR_SIZE>
1412{
1414 IndexT i;
1415 SizeT num = rhs.Size();
1416 for (i = 0; i < num; i++)
1417 {
1418 if (0 == this->Find(rhs[i]))
1419 {
1420 diff.Append(rhs[i]);
1421 }
1422 }
1423 return diff;
1424}
1425
1426//------------------------------------------------------------------------------
1430template<class TYPE, int SMALL_VECTOR_SIZE>
1431void
1433{
1434 std::sort(this->Begin(), this->End());
1435}
1436
1437//------------------------------------------------------------------------------
1441template <class TYPE, int SMALL_VECTOR_SIZE>
1442void
1444{
1445 std::qsort(
1446 this->Begin(),
1447 this->Size(),
1448 sizeof(TYPE),
1449 [](const void* a, const void* b)
1450 {
1451 TYPE arg1 = *static_cast<const TYPE*>(a);
1452 TYPE arg2 = *static_cast<const TYPE*>(b);
1453 return (arg1 > arg2) - (arg1 < arg2);
1454 }
1455 );
1456}
1457
1458//------------------------------------------------------------------------------
1461template<class TYPE, int SMALL_VECTOR_SIZE>
1462void
1463Util::Array<TYPE, SMALL_VECTOR_SIZE>::SortWithFunc(bool (*func)(const TYPE& lhs, const TYPE& rhs))
1464{
1465 std::sort(this->Begin(), this->End(), func);
1466}
1467
1468//------------------------------------------------------------------------------
1471template <class TYPE, int SMALL_VECTOR_SIZE>
1472void
1473Array<TYPE, SMALL_VECTOR_SIZE>::QuickSortWithFunc(int (*func)(const void* lhs, const void* rhs))
1474{
1475 std::qsort(
1476 this->Begin(),
1477 this->Size(),
1478 sizeof(TYPE),
1479 func
1480 );
1481}
1482
1483//------------------------------------------------------------------------------
1488template<class TYPE, int SMALL_VECTOR_SIZE>
1489IndexT
1491{
1492 SizeT num = this->Size();
1493 if (num > 0)
1494 {
1495 IndexT half;
1496 IndexT lo = 0;
1497 IndexT hi = num - 1;
1498 IndexT mid;
1499 while (lo <= hi)
1500 {
1501 if (0 != (half = num/2))
1502 {
1503 mid = lo + ((num & 1) ? half : (half - 1));
1504 if (elm < this->elements[mid])
1505 {
1506 hi = mid - 1;
1507 num = num & 1 ? half : half - 1;
1508 }
1509 else if (elm > this->elements[mid])
1510 {
1511 lo = mid + 1;
1512 num = half;
1513 }
1514 else
1515 {
1516 return mid;
1517 }
1518 }
1519 else if (0 != num)
1520 {
1521 if (elm != this->elements[lo])
1522 {
1523 return InvalidIndex;
1524 }
1525 else
1526 {
1527 return lo;
1528 }
1529 }
1530 else
1531 {
1532 break;
1533 }
1534 }
1535 }
1536 return InvalidIndex;
1537}
1538
1539//------------------------------------------------------------------------------
1548template<class TYPE, int SMALL_VECTOR_SIZE>
1549template<typename KEYTYPE> inline IndexT
1550Array<TYPE, SMALL_VECTOR_SIZE>::BinarySearchIndex(typename std::enable_if<true, const KEYTYPE&>::type elm) const
1551{
1552 SizeT num = this->Size();
1553 if (num > 0)
1554 {
1555 IndexT half;
1556 IndexT lo = 0;
1557 IndexT hi = num - 1;
1558 IndexT mid;
1559 while (lo <= hi)
1560 {
1561 if (0 != (half = num / 2))
1562 {
1563 mid = lo + ((num & 1) ? half : (half - 1));
1564 if (this->elements[mid] > elm)
1565 {
1566 hi = mid - 1;
1567 num = num & 1 ? half : half - 1;
1568 }
1569 else if (this->elements[mid] < elm)
1570 {
1571 lo = mid + 1;
1572 num = half;
1573 }
1574 else
1575 {
1576 return mid;
1577 }
1578 }
1579 else if (0 != num)
1580 {
1581 if (this->elements[lo] != elm)
1582 {
1583 return InvalidIndex;
1584 }
1585 else
1586 {
1587 return lo;
1588 }
1589 }
1590 else
1591 {
1592 break;
1593 }
1594 }
1595 }
1596 return InvalidIndex;
1597}
1598
1599//------------------------------------------------------------------------------
1602template<class TYPE, int SMALL_VECTOR_SIZE>
1603void
1605{
1606 if (num < this->count)
1607 {
1608 this->DestroyRange(num, this->count);
1609 }
1610 else if (num > this->capacity)
1611 {
1612 this->GrowTo(num);
1613 }
1614
1615 this->count = num;
1616}
1617
1618//------------------------------------------------------------------------------
1621template<class TYPE, int SMALL_VECTOR_SIZE>
1622template<typename ...ARGS>
1624{
1625 if (num < this->count)
1626 {
1627 this->DestroyRange(num, this->count);
1628 }
1629 else if (num > this->capacity)
1630 {
1631 SizeT oldCapacity = this->capacity;
1632 this->GrowTo(num);
1633 for (IndexT i = oldCapacity; i < this->capacity; i++)
1634 this->elements[i] = TYPE(args...);
1635 }
1636
1637 this->count = num;
1638}
1639
1640//------------------------------------------------------------------------------
1643template<class TYPE, int SMALL_VECTOR_SIZE>
1645{
1646 if (num > this->capacity)
1647 {
1648 this->GrowTo(num);
1649 this->count = num;
1650 }
1651}
1652
1653//------------------------------------------------------------------------------
1656template<class TYPE, int SMALL_VECTOR_SIZE>
1657void
1659{
1660 this->Clear();
1661}
1662
1663//------------------------------------------------------------------------------
1666template<class TYPE, int SMALL_VECTOR_SIZE>
1667inline void
1669{
1670 TYPE* newArray = ArrayAlloc<TYPE>(this->count);
1671 if (this->elements)
1672 {
1673 this->MoveRange(newArray, this->elements, this->count);
1674 if (this->elements != this->stackElements.data())
1675 ArrayFree(this->capacity, this->elements);
1676 }
1677 this->elements = newArray;
1678
1679 this->capacity = this->count;
1680}
1681
1682//------------------------------------------------------------------------------
1685template<class TYPE, int SMALL_VECTOR_SIZE>
1686inline constexpr SizeT
1688{
1689 return sizeof(TYPE);
1690}
1691
1692//------------------------------------------------------------------------------
1695template<class TYPE, int SMALL_VECTOR_SIZE>
1696size_t
1698{
1699 return this->count;
1700}
1701
1702
1703//------------------------------------------------------------------------------
1706template<class TYPE, int SMALL_VECTOR_SIZE>
1709{
1710 return this->elements;
1711}
1712
1713//------------------------------------------------------------------------------
1716template<class TYPE, int SMALL_VECTOR_SIZE>
1719{
1720 return this->elements + this->count;
1721}
1722
1723//------------------------------------------------------------------------------
1726template<class TYPE, int SMALL_VECTOR_SIZE>
1727void
1729{
1730 if (static_cast<SizeT>(s) > this->capacity)
1731 {
1732 this->GrowTo(static_cast<SizeT>(s));
1733 }
1734 this->count = static_cast<SizeT>(s);
1735}
1736
1737
1738//------------------------------------------------------------------------------
1743template<class TYPE, int SMALL_VECTOR_SIZE>
1744bool
1746{
1747 if (this->count > 1)
1748 {
1749 IndexT i;
1750 for (i = 0; i < this->count - 1; i++)
1751 {
1752 if (this->elements[i] > this->elements[i + 1])
1753 {
1754 return false;
1755 }
1756 }
1757 }
1758 return true;
1759}
1760
1761//------------------------------------------------------------------------------
1767template<class TYPE, int SMALL_VECTOR_SIZE>
1768IndexT
1770{
1771 IndexT i = startIndex + 1;
1772 for (; i < this->count; i++)
1773 {
1774 if (this->elements[i] != elm)
1775 {
1776 this->Insert(i, elm);
1777 return i;
1778 }
1779 }
1780
1781 // fallthrough: new element needs to be appended to end
1782 this->Append(elm);
1783 return (this->Size() - 1);
1784}
1785
1786//------------------------------------------------------------------------------
1791template<class TYPE, int SMALL_VECTOR_SIZE>
1792IndexT
1794{
1795 SizeT num = this->Size();
1796 if (num == 0)
1797 {
1798 // array is currently empty
1799 this->Append(elm);
1800 return this->Size() - 1;
1801 }
1802 else
1803 {
1804 IndexT half;
1805 IndexT lo = 0;
1806 IndexT hi = num - 1;
1807 IndexT mid;
1808 while (lo <= hi)
1809 {
1810 if (0 != (half = num/2))
1811 {
1812 mid = lo + ((num & 1) ? half : (half - 1));
1813 if (elm < this->elements[mid])
1814 {
1815 hi = mid - 1;
1816 num = num & 1 ? half : half - 1;
1817 }
1818 else if (elm > this->elements[mid])
1819 {
1820 lo = mid + 1;
1821 num = half;
1822 }
1823 else
1824 {
1825 // element already exists at [mid], append the
1826 // new element to the end of the range
1827 return this->InsertAtEndOfIdenticalRange(mid, elm);
1828 }
1829 }
1830 else if (0 != num)
1831 {
1832 if (elm < this->elements[lo])
1833 {
1834 this->Insert(lo, elm);
1835 return lo;
1836 }
1837 else if (elm > this->elements[lo])
1838 {
1839 this->Insert(lo + 1, elm);
1840 return lo + 1;
1841 }
1842 else
1843 {
1844 // element already exists at [low], append
1845 // the new element to the end of the range
1846 return this->InsertAtEndOfIdenticalRange(lo, elm);
1847 }
1848 }
1849 else
1850 {
1851 #if NEBULA_BOUNDSCHECKS
1852 n_assert(0 == lo);
1853 #endif
1854 this->Insert(lo, elm);
1855 return lo;
1856 }
1857 }
1858 if (elm < this->elements[lo])
1859 {
1860 this->Insert(lo, elm);
1861 return lo;
1862 }
1863 else if (elm > this->elements[lo])
1864 {
1865 this->Insert(lo + 1, elm);
1866 return lo + 1;
1867 }
1868 else
1869 {
1870 // can't happen(?)
1871 }
1872 }
1873 // can't happen
1874 n_error("Array::InsertSorted: Can't happen!");
1875 return InvalidIndex;
1876}
1877
1878template<class TYPE, int STACK_SIZE>
1880
1881} // namespace Util
1882//------------------------------------------------------------------------------
Definition half.h:20
Nebula's dynamic array class.
Definition array.h:60
Array(std::nullptr_t)
construct an empty fixed array
Definition array.h:346
void Move(IndexT fromIndex, IndexT toIndex)
move elements, grows array if needed
Definition array.h:601
const TYPE * ConstIterator
Definition array.h:64
void Extend(SizeT num)
Resize to fit the provided value, but don't shrink if the new size is smaller.
Definition array.h:1644
Array(SizeT initialCapacity, SizeT initialGrow)
constuctor with initial size and grow size
Definition array.h:269
void Reserve(SizeT num)
increase capacity to fit N more elements into the array.
Definition array.h:860
void Fill(IndexT first, SizeT num, const TYPE &elm)
fill array range with element
Definition array.h:1387
IndexT FindIndex(const TYPE &elm, const IndexT start=0) const
find identical element in array, return index, InvalidIndex if not found
Definition array.h:1312
void Destroy(TYPE *elm)
destroy an element (call destructor without freeing memory)
Definition array.h:445
Iterator End() const
return iterator to end of array
Definition array.h:1263
SizeT capacity
Definition array.h:246
SizeT count
Definition array.h:247
TYPE * EmplaceArray(const SizeT count)
Emplace range of items and return pointer to first.
Definition array.h:829
~Array()
destructor
Definition array.h:454
Iterator Find(const TYPE &elm, const IndexT start=0) const
find identical element in array, return iterator
Definition array.h:1288
IndexT FindIndex(typename std::enable_if< true, const KEYTYPE & >::type elm, const IndexT start=0) const
find identical element using a specific key type
Definition array.h:1362
bool operator!=(const Array< TYPE, SMALL_VECTOR_SIZE > &rhs) const
inequality operator
Definition array.h:968
TYPE * Iterator
define iterator
Definition array.h:63
void EraseFront()
erase front
Definition array.h:1142
TYPE & Back() const
return reference to last element
Definition array.h:991
void Copy(const Array< TYPE, SMALL_VECTOR_SIZE > &src)
copy content
Definition array.h:398
const SizeT Capacity() const
get overall allocated size of array in number of elements
Definition array.h:898
void Clear()
clear array (calls destructors)
Definition array.h:1205
TYPE * elements
Definition array.h:248
IndexT InsertAtEndOfIdenticalRange(IndexT startIndex, const TYPE &elm)
insert element at the first non-identical position, return index of inclusion position
Definition array.h:1769
ConstIterator ConstEnd() const
return const iterator to end of array
Definition array.h:1273
constexpr SizeT TypeSize() const
Returns sizeof(TYPE)
Definition array.h:1687
Array(std::initializer_list< TYPE > list)
constructor from initializer list
Definition array.h:327
void EraseRange(IndexT start, IndexT end)
erase range, excluding the element at end
Definition array.h:1108
IndexT BinarySearchIndex(typename std::enable_if< true, const KEYTYPE & >::type elm) const
do a binary search using a specific key type
Definition array.h:1550
void Sort()
sort the array
Definition array.h:1432
SizeT grow
Definition array.h:245
void operator=(Array< TYPE, SMALL_VECTOR_SIZE > &&rhs) noexcept
move operator
Definition array.h:513
void QuickSort()
quick sort the array
Definition array.h:1443
void Delete()
delete content
Definition array.h:420
void Append(TYPE &&elm)
append an element which is being forwarded
Definition array.h:748
void DestroyRange(IndexT fromIndex, IndexT toIndex)
destroy range of elements
Definition array.h:652
Iterator end() const
Definition array.h:1718
TYPE & operator[](IndexT index) const
[] operator
Definition array.h:910
static const SizeT MinGrowSize
Definition array.h:243
Array(ArrayT &&rhs) noexcept
move constructor
Definition array.h:371
void SortWithFunc(bool(*func)(const TYPE &lhs, const TYPE &rhs))
sort with custom function
Definition array.h:1463
void Append(const TYPE &first, const ELEM_TYPE &... elements)
Append multiple elements to the end of the array.
Definition array.h:1332
TYPE & operator[](IndexT index)
[] operator
Definition array.h:925
Iterator begin() const
for range-based iteration
Definition array.h:1708
Iterator EraseSwap(Iterator iter)
erase element at iterator, fill gap by swapping in last element, destroys sorting!
Definition array.h:1094
TYPE & Emplace()
Emplace item (create new item and return reference)
Definition array.h:810
Array(const TYPE *const buf, SizeT num)
constructor from TYPE pointer and size.
Definition array.h:310
void Reset()
reset array (does NOT call destructors)
Definition array.h:1221
void Realloc(SizeT capacity, SizeT grow)
clear contents and preallocate with new attributes
Definition array.h:463
T As() const
convert to "anything"
bool IsEmpty() const
return true if array empty
Definition array.h:1014
IndexT InsertSorted(const TYPE &elm)
insert element into sorted array, return index where element was included
Definition array.h:1793
void AppendArray(const Array< TYPE, SMALL_VECTOR_SIZE > &rhs)
append the contents of an array to this array
Definition array.h:766
void Grow()
grow array with grow value
Definition array.h:566
void EraseIndex(IndexT index)
erase element at index, keep sorting intact
Definition array.h:1034
static const SizeT MaxGrowSize
Definition array.h:244
const SizeT ByteSize() const
return the byte size of the array.
Definition array.h:888
void EraseIndexSwap(IndexT index)
erase element at index, fill gap by swapping in last element, destroys sorting!
Definition array.h:1056
TYPE PopFront()
Pop front.
Definition array.h:1152
ConstIterator ConstBegin() const
return const iterator to beginning of array
Definition array.h:1253
_smallvector< TYPE, SMALL_VECTOR_SIZE > stackElements
Definition array.h:250
void resize(size_t size)
Definition array.h:1728
Array(SizeT initialSize, SizeT initialGrow, const TYPE &initialValue)
constructor with initial size, grow size and initial values
Definition array.h:286
void operator=(const Array< TYPE, SMALL_VECTOR_SIZE > &rhs)
assignment operator
Definition array.h:483
void Append(const TYPE &elm)
append element to end of array
Definition array.h:730
void GrowTo(SizeT newCapacity)
grow array to target size
Definition array.h:543
TYPE & Get(IndexT index) const
Get element (same as operator[] but as a function)
Definition array.h:716
void Insert(IndexT index, const TYPE &elm)
insert element before element at index
Definition array.h:1181
void push_back(const TYPE &item)
Definition array.h:1004
size_t size() const
Definition array.h:1697
void CopyRange(TYPE *to, TYPE *from, SizeT num)
copy range
Definition array.h:672
void Resize(SizeT num, ARGS... args)
Resize and fill new elements with arguments.
Definition array.h:1623
bool operator==(const Array< TYPE, SMALL_VECTOR_SIZE > &rhs) const
equality operator
Definition array.h:940
ArrayT Difference(const Array< TYPE, SMALL_VECTOR_SIZE > &rhs)
returns new array with elements which are not in rhs (slow!)
Definition array.h:1411
void EraseBack()
erase back
Definition array.h:1129
bool IsValidIndex(IndexT index) const
check if index is valid
Definition array.h:1024
Iterator Begin() const
return iterator to beginning of array
Definition array.h:1243
bool IsSorted() const
test if the array is sorted, this is a slow operation!
Definition array.h:1745
IndexT BinarySearchIndex(const TYPE &elm) const
do a binary search, requires a sorted array
Definition array.h:1490
void MoveRange(TYPE *to, TYPE *from, SizeT num)
move range
Definition array.h:694
void Resize(SizeT num)
Set size. Grows array if num is greater than capacity. Calls destroy on all objects at index > num!
Definition array.h:1604
void QuickSortWithFunc(int(*func)(const void *lhs, const void *rhs))
quick sort the array
Definition array.h:1473
Array()
constructor with default parameters
Definition array.h:257
void Free()
free memory and reset size
Definition array.h:1232
const SizeT Size() const
get number of elements in array
Definition array.h:878
void AppendArray(const TYPE *arr, const SizeT count)
append from C array
Definition array.h:788
void clear() noexcept
Definition array.h:1658
TYPE & Front() const
return reference to first element
Definition array.h:978
TYPE PopBack()
Pop back.
Definition array.h:1167
Iterator Erase(Iterator iter)
erase element pointed to by iterator, keep sorting intact
Definition array.h:1079
void Fit()
Fit the size of the array to the amount of elements.
Definition array.h:1668
Array(const ArrayT &rhs)
copy constructor
Definition array.h:358
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
#define n_assert(exp)
Definition debug.h:50
void ArrayFree(size_t size, TYPE *buffer)
Definition memory.h:45
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 CopyElements(const T *from, T *to, size_t numElements)
Copy a chunk of memory (note the argument order is different from memcpy()!!!)
Definition posixmemory.h:208
__forceinline void MoveElements(const T *from, T *to, size_t numElements)
Move a chunk of memory, can handle overlapping regions.
Definition posixmemory.h:191
void Clear(void *ptr, size_t numBytes)
Overwrite a chunk of memory with 0's.
Definition osxmemory.cc:229
A pinned array is an array which manages its own virtual memory.
Definition String.cs:6
Nebula's scalar datatype.
TYPE * data()
Definition array.h:56
Definition array.h:47
TYPE stackElements[STACK_SIZE]
Definition array.h:50
TYPE * data()
Definition array.h:48
static const int InvalidIndex
Definition types.h:54
int SizeT
Definition types.h:49
int IndexT
Definition types.h:48