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#include "ContainersExport.h"
6
7namespace SC
8{
11
13template <typename T>
15{
16 VirtualArray() = default;
17 VirtualArray(size_t maxCapacity) { SC_ASSERT_RELEASE(reserve(maxCapacity)); }
18 ~VirtualArray() { clear(); }
19
22 void release()
23 {
24 virtualMemory.release();
25 capacityElements = 0;
26 sizeElements = 0;
27 }
28
31 void clear()
32 {
33 T* items = data();
34 while (sizeElements > 0)
35 {
36 sizeElements--;
37 items[sizeElements].~T();
38 }
39 }
40
42 [[nodiscard]] bool clearAndDecommit()
43 {
44 clear();
45 return decommit();
46 }
47
49 [[nodiscard]] bool decommit() { return virtualMemory.decommit(sizeElements * sizeof(T)); }
50
52 [[nodiscard]] bool resizeWithoutInitializing(size_t newSize)
53 {
54 if (not virtualMemory.commit(newSize * sizeof(T)))
55 return false;
56 sizeElements = newSize;
57 return true;
58 }
59
61 [[nodiscard]] bool resize(size_t newSize)
62 {
63 T* items = data();
64 const size_t oldSize = sizeElements;
65 if (newSize < oldSize)
66 {
67 size_t idx = oldSize;
68 do
69 {
70 items[--idx].~T();
71 } while (idx != newSize);
72 }
73 if (not resizeWithoutInitializing(newSize))
74 return false;
75 if (newSize > oldSize)
76 {
77 size_t idx = oldSize;
78 do
79 {
80 placementNew(items[idx++]);
81 } while (idx != newSize);
82 }
83 return true;
84 }
85
87 [[nodiscard]] bool reserve(size_t maxNumElements)
88 {
89 if (maxNumElements <= capacityElements)
90 {
91 return true;
92 }
93 if (virtualMemory.reserve(sizeof(T) * maxNumElements))
94 {
95 capacityElements = maxNumElements;
96 return true;
97 }
98 return false;
99 }
100
101 [[nodiscard]] size_t capacity() const { return capacityElements; }
102 [[nodiscard]] size_t size() const { return sizeElements; }
103
104 [[nodiscard]] T* data() { return static_cast<T*>(virtualMemory.data()); }
105 [[nodiscard]] const T* data() const { return static_cast<const T*>(virtualMemory.data); }
106
107 [[nodiscard]] operator Span<T>() { return {data(), sizeElements}; }
108 [[nodiscard]] operator Span<const T>() const { return {data(), sizeElements}; }
109
110 [[nodiscard]] Span<T> toSpan() { return {data(), sizeElements}; }
111 [[nodiscard]] Span<const T> toSpan() const { return {data(), sizeElements}; }
112
113 private:
114 VirtualMemory virtualMemory;
115
116 size_t sizeElements = 0;
117 size_t capacityElements = 0;
118};
120
121} // namespace SC
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition Assert.h:48
An array using a large virtual memory reservation to keep stable addresses.
Definition VirtualArray.h:15
void clear()
Clears the stable array by calling the destructor of each element.
Definition VirtualArray.h:31
bool resize(size_t newSize)
Resizes the stable array, calling constructors or destructors as needed.
Definition VirtualArray.h:61
bool reserve(size_t maxNumElements)
Reserves memory for the stable array without initializing elements.
Definition VirtualArray.h:87
bool decommit()
De-commits unused-memory, while still keeping the original virtual reservation.
Definition VirtualArray.h:49
bool resizeWithoutInitializing(size_t newSize)
Resizes the stable array without initializing or calling destructors.
Definition VirtualArray.h:52
void release()
Releases all reserved memory.
Definition VirtualArray.h:22
bool clearAndDecommit()
Clears the array calling destructors of each element and releases virtual memory.
Definition VirtualArray.h:42
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)