Deluge Firmware 1.3.0
Build date: 2026.11.13
Loading...
Searching...
No Matches
resizeable_array.h
1/*
2 * Copyright © 2017-2023 Synthstrom Audible Limited
3 *
4 * This file is part of The Synthstrom Audible Deluge Firmware.
5 *
6 * The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software Foundation,
8 * either version 3 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with this program.
15 * If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#include "definitions_cxx.hpp"
21#include <cstdint>
22
23#define GREATER_OR_EQUAL 0
24#define LESS (-1)
25
26// Re-entrancy means concurrent mutation (heap corruption), so this is on in all builds
27#define RESIZEABLE_ARRAY_DO_LOCKS 1
28
29class ResizeableArray {
30public:
31 ResizeableArray(int32_t newElementSize, int32_t newMaxNumEmptySpacesToKeep = 16,
32 int32_t newNumExtrarSpacesToAllocate = 15);
33 ~ResizeableArray();
34 void init();
35 bool cloneFrom(ResizeableArray const* other);
36 void empty();
37 void swapStateWith(ResizeableArray* other);
38 void deleteAtIndex(int32_t i, int32_t numToDelete = 1, bool mayShortenMemoryAfter = true);
39 bool ensureEnoughSpaceAllocated(int32_t numAdditionalElementsNeeded);
40 Error insertAtIndex(int32_t i, int32_t numToInsert = 1, void* thingNotToStealFrom = nullptr);
41 void swapElements(int32_t i1, int32_t i2);
42 void repositionElement(int32_t iFrom, int32_t iTo);
43 Error beenCloned();
44 void setMemory(void* newMemory, int32_t newMemorySize);
45 void setStaticMemory(void* newMemory, int32_t newMemorySize);
46
47 void moveElementsLeft(int32_t oldStartIndex, int32_t oldStopIndex, int32_t distance);
48 void moveElementsRight(int32_t oldStartIndex, int32_t oldStopIndex, int32_t distance);
49
50 [[gnu::always_inline]] inline void* getElementAddress(int32_t index) {
51 int32_t absoluteIndex = index + memoryStart;
52 if (absoluteIndex >= memorySize)
53 absoluteIndex -= memorySize;
54 return (char* __restrict__)memory + (absoluteIndex * elementSize);
55 }
56
57 [[gnu::always_inline]] inline int32_t getNumElements() { return numElements; }
58
59 uint32_t elementSize;
60 bool emptyingShouldFreeMemory;
61 uint32_t staticMemoryAllocationSize;
62
63protected:
64 void* memory;
65 int32_t numElements;
66 int32_t memorySize; // In elements, not bytes
67 int32_t memoryStart;
68#if TEST_VECTOR
69 int32_t moveCount;
70#endif
71
72#if RESIZEABLE_ARRAY_DO_LOCKS
73 bool lock;
74 void freezeOnLock();
75 void exitLock();
76#endif
77
78private:
79 void attemptMemoryShorten();
80 bool attemptMemoryExpansion(int32_t minNumToExtend, int32_t idealNumToExtend, bool mayExtendAllocation,
81 void* thingNotToStealFrom);
82 void copyToNewMemory(void* newMemory, uint32_t destinationIndex, void* source, uint32_t numElementsToCopy,
83 uint32_t newMemorySize, uint32_t newMemoryStartIndex);
84 Error copyElementsFromOldMemory(void* otherMemory, int32_t otherMemorySize, int32_t otherMemoryStart);
85
86 void moveElementsRightNoWrap(int32_t oldStartIndex, int32_t oldStopIndex, int32_t distance);
87 void moveElementsLeftNoWrap(int32_t oldStartIndex, int32_t oldStopIndex, int32_t distance);
88
89 void* memoryAllocationStart; // This might be slightly to the left of "memory"
90
91 const int32_t maxNumEmptySpacesToKeep; // Can go down to 0
92 const int32_t numExtraSpacesToAllocate; // Can go down to 0
93};