| 1 | #include <basis/seadNew.h> |
| 2 | #include <basis/seadRawPrint.h> |
| 3 | #include <container/seadPtrArray.h> |
| 4 | |
| 5 | namespace sead |
| 6 | { |
| 7 | void PtrArrayImpl::setBuffer(s32 ptrNumMax, void* buf) |
| 8 | { |
| 9 | if (ptrNumMax < 1) |
| 10 | { |
| 11 | SEAD_ASSERT_MSG(false, "ptrNumMax[%d] must be larger than zero" , ptrNumMax); |
| 12 | return; |
| 13 | } |
| 14 | |
| 15 | if (buf == NULL) |
| 16 | { |
| 17 | SEAD_ASSERT_MSG(false, "buf is null" ); |
| 18 | return; |
| 19 | } |
| 20 | |
| 21 | mPtrs = static_cast<void**>(buf); |
| 22 | mPtrNum = 0; |
| 23 | mPtrNumMax = ptrNumMax; |
| 24 | } |
| 25 | |
| 26 | void PtrArrayImpl::allocBuffer(s32 ptrNumMax, Heap* heap, s32 alignment) |
| 27 | { |
| 28 | SEAD_ASSERT(mPtrs == nullptr); |
| 29 | |
| 30 | if (ptrNumMax < 1) |
| 31 | { |
| 32 | SEAD_ASSERT_MSG(false, "ptrNumMax[%d] must be larger than zero" , ptrNumMax); |
| 33 | return; |
| 34 | } |
| 35 | |
| 36 | setBuffer(ptrNumMax, buf: new (heap, alignment, std::nothrow) u8[s32(sizeof(void*)) * ptrNumMax]); |
| 37 | } |
| 38 | |
| 39 | bool PtrArrayImpl::tryAllocBuffer(s32 ptrNumMax, Heap* heap, s32 alignment) |
| 40 | { |
| 41 | SEAD_ASSERT(mPtrs == nullptr); |
| 42 | |
| 43 | if (ptrNumMax < 1) |
| 44 | { |
| 45 | SEAD_ASSERT_MSG(false, "ptrNumMax[%d] must be larger than zero" , ptrNumMax); |
| 46 | return false; |
| 47 | } |
| 48 | |
| 49 | auto* buf = new (heap, alignment, std::nothrow) u8[s32(sizeof(void*)) * ptrNumMax]; |
| 50 | if (!buf) |
| 51 | return false; |
| 52 | |
| 53 | setBuffer(ptrNumMax, buf); |
| 54 | return true; |
| 55 | } |
| 56 | |
| 57 | void PtrArrayImpl::freeBuffer() |
| 58 | { |
| 59 | if (isBufferReady()) |
| 60 | { |
| 61 | delete[] mPtrs; |
| 62 | mPtrs = nullptr; |
| 63 | mPtrNum = 0; |
| 64 | mPtrNumMax = 0; |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | void PtrArrayImpl::erase(s32 pos, s32 count) |
| 69 | { |
| 70 | if (pos < 0) |
| 71 | { |
| 72 | SEAD_ASSERT_MSG(false, "illegal position[%d]" , pos); |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | if (count < 0) |
| 77 | { |
| 78 | SEAD_ASSERT_MSG(false, "illegal number[%d]" , count); |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | if (pos + count > mPtrNum) |
| 83 | { |
| 84 | SEAD_ASSERT_MSG(false, "pos[%d] + num[%d] exceed size[%d]" , pos, count, mPtrNum); |
| 85 | return; |
| 86 | } |
| 87 | |
| 88 | const s32 endPos = pos + count; |
| 89 | if (mPtrNum > endPos) |
| 90 | MemUtil::copyOverlap(dest: mPtrs + pos, src: mPtrs + endPos, size: sizeof(void*) * (mPtrNum - endPos)); |
| 91 | |
| 92 | mPtrNum -= count; |
| 93 | } |
| 94 | |
| 95 | // NON_MATCHING: semantically equivalent |
| 96 | void PtrArrayImpl::reverse() |
| 97 | { |
| 98 | for (s32 i = 0; i < mPtrNum / 2; ++i) |
| 99 | swap(pos1: mPtrNum - i - 1, pos2: i); |
| 100 | } |
| 101 | |
| 102 | // Fisher–Yates shuffle. |
| 103 | void PtrArrayImpl::shuffle(Random* random) |
| 104 | { |
| 105 | SEAD_ASSERT(random); |
| 106 | for (s32 i = mPtrNum - 1; i > 0; --i) |
| 107 | swap(pos1: i, pos2: random->getS32Range(a: 0, b: i + 1)); |
| 108 | } |
| 109 | |
| 110 | void PtrArrayImpl::insert(s32 pos, void* ptr) |
| 111 | { |
| 112 | if (!checkInsert(idx: pos, num: 1)) |
| 113 | return; |
| 114 | |
| 115 | createVacancy(pos, count: 1); |
| 116 | mPtrs[pos] = ptr; |
| 117 | ++mPtrNum; |
| 118 | } |
| 119 | |
| 120 | bool PtrArrayImpl::checkInsert(s32 pos, s32 num) |
| 121 | { |
| 122 | if (pos < 0) |
| 123 | { |
| 124 | SEAD_ASSERT_MSG(false, "illegal position[%d]" , pos); |
| 125 | return false; |
| 126 | } |
| 127 | |
| 128 | if (mPtrNum + num > mPtrNumMax) |
| 129 | { |
| 130 | SEAD_ASSERT_MSG(false, "list is full." ); |
| 131 | return false; |
| 132 | } |
| 133 | |
| 134 | if (mPtrNum < pos) |
| 135 | { |
| 136 | SEAD_ASSERT_MSG(false, "pos[%d] exceed size[%d]" , pos, mPtrNum); |
| 137 | return false; |
| 138 | } |
| 139 | |
| 140 | return true; |
| 141 | } |
| 142 | |
| 143 | // TODO: PtrArrayImpl::insertArray |
| 144 | |
| 145 | // TODO: PtrArrayImpl::sort |
| 146 | |
| 147 | // TODO: PtrArrayImpl::heapSort |
| 148 | |
| 149 | // TODO: PtrArrayImpl::compare |
| 150 | |
| 151 | // TODO: PtrArrayImpl::uniq |
| 152 | |
| 153 | // TODO: PtrArrayImpl::binarySearch |
| 154 | |
| 155 | } // namespace sead |
| 156 | |