Repository navigation
Expand file tree
/
Copy pathSparseArray.cpp
More file actions
68 lines (57 loc) · 1.67 KB
/
Copy pathSparseArray.cpp
File metadata and controls
68 lines (57 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/** The result of a sparse array allocation. */
struct FSparseArrayAllocationInfo
{
int32 Index;
void* Pointer;
};
/** Allocated elements are overlapped with free element info in the element list. */
template<typename ElementType>
union TSparseArrayElementOrFreeListLink
{
ElementType ElementData;
struct {
int32 PrevFreeIndex;
int32 NextFreeIndex;
};
};
template<typename ElementType,typename Allocator /*= FDefaultSparseArrayAllocator */>
class TSparseArray
{
typedef TSparseArrayElementOrFreeListLink<TAlignedBytes<sizeof(ElementType), alignof(ElementType)>> FElementOrFreeListLink;
typedef TArray<FElementOrFreeListLink, Allocator::ElementAllocator> DataType;
DataType Data;
typedef TBitArray<Allocator::BitArrayAllocator> AllocationBitArrayType;
AllocationBitArrayType AllocationFlags;
/** The index of an unallocated element in the array that currently contains the head of the linked list of free elements. */
int32 FirstFreeIndex = -1;
/** The number of elements in the free list. */
int32 NumFreeIndices = 0;
int32 Add(const ElementType& Element)
{
FSparseArrayAllocationInfo Allocation = AddUninitialized();
new(Allocation) ElementType(Element);
return Allocation.Index;
}
FSparseArrayAllocationInfo AddUninitialized()
{
int32 Index;
if(NumFreeIndices)
{
// Remove and use the first index from the list of free elements.
Index = FirstFreeIndex;
FirstFreeIndex = GetData(FirstFreeIndex).NextFreeIndex;
--NumFreeIndices;
if(NumFreeIndices)
{
GetData(FirstFreeIndex).PrevFreeIndex = -1;
}
}
else
{
// Add a new element.
Index = Data.AddUninitialized(1);
AllocationFlags.Add(false);
}
return AllocateIndex(Index);
}
}