Sane C++ Libraries: Vector.h Source File (original) (raw)
1
2
3#pragma once
4#include "../Containers/Algorithms/AlgorithmRemove.h"
5#include "../Foundation/TypeTraits.h"
6#include "../Memory/Internal/Segment.inl"
7#include "../Memory/Internal/SegmentTrivial.inl"
8
9namespace SC
10{
11namespace detail
12{
13
14template <typename T, bool isTrivial = TypeTraits::IsTriviallyCopyable::value>
15struct SegmentVTable : public SegmentTrivial
16{
17};
18
19template
20struct SegmentVTable<T, false>
21{
22 static void destruct(Span data) noexcept
23 {
24 forEach(data, [](auto, T& item) { item.~T(); });
25 }
26
27 template
28 static void copyConstructAs(Span data, Span value) noexcept
29 {
30 const U& single = value[0];
31 forEach(data, [&single](auto, T& item) { placementNew(item, single); });
32 }
33
34 template
35 static void copyConstruct(Span data, const U* src) noexcept
36 {
37 forEach(data, [src](auto idx, T& item) { placementNew(item, src[idx]); });
38 }
39
40 template
41 static void copyAssign(Span data, const U* src) noexcept
42 {
43 forEach(data, [src](auto idx, T& item) { item = src[idx]; });
44 }
45
46 template
47 static void moveConstruct(Span data, U* src) noexcept
48 {
49 forEach(data, [src](auto idx, T& item) { placementNew(item, move(src[idx])); });
50 }
51
52 template
53 static void moveAssign(Span data, U* src) noexcept
54 {
55 forEach(data, [src](auto idx, T& item) { item = move(src[idx]); });
56 }
57
58 template
59 static void copyInsert(Span headerData, Span values) noexcept
60 {
61
62 T* data = headerData.data();
63 const U* src = values.data();
64
65 const size_t numElements = headerData.sizeInElements();
66 const size_t numToInsert = values.sizeInElements();
67
68 if (numElements == 0)
69 {
70
71 for (size_t idx = 0; idx < numToInsert; ++idx)
72 {
73 placementNew(data[idx], src[idx]);
74 }
75 }
76 else
77 {
78
79 for (size_t idx = numElements; idx < numElements + numToInsert; ++idx)
80 {
81
82
83
84 if (idx >= numToInsert)
85 {
86 placementNew(data[idx], move(data[idx - numToInsert]));
87 }
88 }
89
90
91 for (size_t idx = numElements - 1; idx >= numToInsert; --idx)
92 {
93 if (idx >= numToInsert)
94 {
95 data[idx] = move(data[idx - numToInsert]);
96 }
97 }
98
99
100 for (size_t idx = 0; idx < numToInsert; ++idx)
101 {
102
103 if (idx < numElements)
104 {
105 data[idx] = src[idx];
106 }
107 else
108 {
109 placementNew(data[idx], src[idx]);
110 }
111 }
112 }
113 }
114
115 static void remove(Span headerData, size_t numToRemove) noexcept
116 {
117 T* data = headerData.data();
118
119 const size_t numElements = headerData.sizeInElements();
120
121 for (size_t idx = 0; idx < numElements - numToRemove; ++idx)
122 {
123 data[idx] = move(data[idx + numToRemove]);
124 }
125 for (size_t idx = numElements - numToRemove; idx < numElements; ++idx)
126 {
127 data[idx].~T();
128 }
129 }
130
131 private:
132 template
133 static void forEach(Span data, Lambda&& lambda) noexcept
134 {
135 const size_t numElements = data.sizeInElements();
136 T* elements = data.data();
137 for (size_t idx = 0; idx < numElements; ++idx)
138 {
139 lambda(idx, elements[idx]);
140 }
141 }
142};
143
144
145
146
147
148template
149struct ObjectVTable
150{
151 using Type = T;
152 static void destruct(Span data) noexcept { SegmentVTable::destruct(data); }
153
154 template static void copyConstructAs(Span data, Span value) noexcept { SegmentVTable::template copyConstructAs(data, value);}
155 template static void copyConstruct(Span data, const U* src) noexcept { SegmentVTable::template copyConstruct(data, src);}
156 template static void copyAssign(Span data, const U* src) noexcept { SegmentVTable::template copyAssign(data, src);}
157 template static void moveConstruct(Span data, U* src) noexcept { SegmentVTable::template moveConstruct(data, src);}
158 template static void moveAssign(Span data, U* src) noexcept { SegmentVTable::template moveAssign(data, src);}
159 template static void copyInsert(Span data, Span values) noexcept { SegmentVTable::template copyInsert(data, values);}
160
161 static void remove(Span data, size_t numElements) noexcept { SegmentVTable::remove(data, numElements); }
162};
163
164template
165struct VectorVTable : public ObjectVTable, public SegmentSelfRelativePointer
166{
167 static constexpr bool IsArray = false;
168};
169}
170
173
176
187template
189{
191
192
193 using Parent::Parent;
194
197 template
198 [[nodiscard]] bool contains(const U& value, size_t* index = nullptr) const noexcept
199 {
200 return Algorithms::contains(*this, value, index);
201 }
202
205 template
206 [[nodiscard]] bool find(Lambda&& lambda, size_t* index = nullptr) const noexcept
207 {
208 return Algorithms::findIf(Parent::begin(), Parent::end(), move(lambda), index) != Parent::end();
209 }
210
213 template
214 [[nodiscard]] bool removeAll(Lambda&& criteria) noexcept
215 {
216 T* itBeg = Parent::begin();
217 T* itEnd = Parent::end();
218 T* it = Algorithms::removeIf(itBeg, itEnd, forward(criteria));
219
220 const size_t numElements = static_cast<size_t>(itEnd - it);
221 const size_t offset = static_cast<size_t>(it - itBeg);
222 detail::VectorVTable::destruct({Parent::data() + offset, numElements});
223 Parent::header.sizeBytes -= static_cast<decltype(Parent::header.sizeBytes)>(numElements * sizeof(T));
224 return it != itEnd;
225 }
226
231 template
232 [[nodiscard]] bool remove(const U& value) noexcept
233 {
234 return removeAll([&](auto& item) { return item == value; });
235 }
236};
237
249template <typename T, int N>
251{
252
253 SmallVector(SegmentAllocator allocator = SegmentAllocator::Global) noexcept : Vector( N * sizeof(T), allocator) {}
259
263
264 protected:
265 SmallVector(int num, SegmentAllocator allocator) : Vector(N, allocator) { (void)num; }
266
267 private:
268 uint64_t inlineCapacity = N * sizeof(T);
269 union
270 {
271 T inlineData[N];
272 };
273};
274
275template
276using VectorTL = detail::SegmentCustom<Vector, Vector, 0, SegmentAllocator::ThreadLocal>;
277template <typename T, int N>
278using SmallVectorTL = detail::SegmentCustom<SmallVector<T, N>, Vector, N, SegmentAllocator::ThreadLocal>;
279
281
282}
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition Assert.h:46
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition Compiler.h:264
constexpr T && forward(typename TypeTraits::RemoveReference< T >::type &value)
Forwards an lvalue or an rvalue as an rvalue reference.
Definition Compiler.h:267
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
A slice of contiguous memory, prefixed by and header containing size and capacity.
Definition Segment.h:113
A Vector that can hold up to N elements inline and > N on heap.
Definition Vector.h:251
A contiguous sequence of heap allocated elements.
Definition Vector.h:189
bool remove(const U &value) noexcept
Removes all values equal to value
Definition Vector.h:232
bool find(Lambda &&lambda, size_t *index=nullptr) const noexcept
Finds the first item in array matching criteria given by the lambda.
Definition Vector.h:206
bool contains(const U &value, size_t *index=nullptr) const noexcept
Check if the current array contains a given value.
Definition Vector.h:198
bool removeAll(Lambda &&criteria) noexcept
Removes all items matching criteria given by Lambda.
Definition Vector.h:214