Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
VirtualArray.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#include "../Foundation/Span.h"
4#include "../Memory/VirtualMemory.h"
5
6namespace SC
7{
10
12template <typename T>
14{
15 VirtualArray() = default;
16 VirtualArray(size_t maxCapacity) { SC_ASSERT_RELEASE(reserve(maxCapacity)); }
17 ~VirtualArray() { clear(); }
18
21 void release()
22 {
23 virtualMemory.release();
24 capacityElements = 0;
25 sizeElements = 0;
26 }
27
30 void clear()
31 {
32 T* items = data();
33 while (sizeElements > 0)
34 {
35 sizeElements--;
36 items[sizeElements].~T();
37 }
38 }
39
41 [[nodiscard]] bool clearAndDecommit()
42 {
43 clear();
44 return decommit();
45 }
46
48 [[nodiscard]] bool decommit() { return virtualMemory.decommit(sizeElements * sizeof(T)); }
49
51 [[nodiscard]] bool resizeWithoutInitializing(size_t newSize)
52 {
53 if (not virtualMemory.commit(newSize * sizeof(T)))
54 return false;
55 sizeElements = newSize;
56 return true;
57 }
58
60 [[nodiscard]] bool resize(size_t newSize)
61 {
62 T* items = data();
63 const size_t oldSize = sizeElements;
64 if (newSize < oldSize)
65 {
66 size_t idx = oldSize;
67 do
68 {
69 items[--idx].~T();
70 } while (idx != newSize);
71 }
72 if (not resizeWithoutInitializing(newSize))
73 return false;
74 if (newSize > oldSize)
75 {
76 size_t idx = oldSize;
77 do
78 {
79 placementNew(items[idx++]);
80 } while (idx != newSize);
81 }
82 return true;
83 }
84
86 [[nodiscard]] bool reserve(size_t maxNumElements)
87 {
88 if (maxNumElements <= capacityElements)
89 {
90 return true;
91 }
92 if (virtualMemory.reserve(sizeof(T) * maxNumElements))
93 {
94 capacityElements = maxNumElements;
95 return true;
96 }
97 return false;
98 }
99
100 [[nodiscard]] size_t capacity() const { return capacityElements; }
101 [[nodiscard]] size_t size() const { return sizeElements; }
102
103 [[nodiscard]] T* data() { return static_cast<T*>(virtualMemory.data()); }
104 [[nodiscard]] const T* data() const { return static_cast<const T*>(virtualMemory.data); }
105
106 [[nodiscard]] operator Span<T>() { return {data(), sizeElements}; }
107 [[nodiscard]] operator Span<const T>() const { return {data(), sizeElements}; }
108
109 [[nodiscard]] Span<T> toSpan() { return {data(), sizeElements}; }
110 [[nodiscard]] Span<const T> toSpan() const { return {data(), sizeElements}; }
111
112 private:
113 VirtualMemory virtualMemory;
114
115 size_t sizeElements = 0;
116 size_t capacityElements = 0;
117};
119
120} // namespace SC
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition Assert.h:46
An array using a large virtual memory reservation to keep stable addresses.
Definition VirtualArray.h:14
void clear()
Clears the stable array by calling the destructor of each element.
Definition VirtualArray.h:30
bool resize(size_t newSize)
Resizes the stable array, calling constructors or destructors as needed.
Definition VirtualArray.h:60
bool reserve(size_t maxNumElements)
Reserves memory for the stable array without initializing elements.
Definition VirtualArray.h:86
bool decommit()
De-commits unused-memory, while still keeping the original virtual reservation.
Definition VirtualArray.h:48
bool resizeWithoutInitializing(size_t newSize)
Resizes the stable array without initializing or calling destructors.
Definition VirtualArray.h:51
void release()
Releases all reserved memory.
Definition VirtualArray.h:21
bool clearAndDecommit()
Clears the array calling destructors of each element and releases virtual memory.
Definition VirtualArray.h:41
void * data()
Returns a pointer to the start of the reserved virtual memory.
Definition VirtualMemory.h:62
bool reserve(size_t maxCapacityInBytes)
Reserves a large block of virtual memory of size maxCapacityInBytes.
bool commit(size_t sizeInBytes)
Ensures at least sizeInBytes to be committed / accessible from the large maxCapacityInBytes block.
void release()
Reclaims the entire virtual memory block (reserved with VirtualMemory::reserve)
bool decommit(size_t sizeInBytes)
Reclaims all unused pages past sizeInBytes (previously committed with VirtualMemory::commit)