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