blob: 2e47846ee7cfc677916fc0d5a3104aa633cd033e [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the SmallVector class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_ADT_SMALLVECTOR_H
14#define LLVM_ADT_SMALLVECTOR_H
15
16#include "llvm/ADT/iterator_range.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010017#include "llvm/Support/Compiler.h"
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020018#include "llvm/Support/ErrorHandling.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010019#include "llvm/Support/MathExtras.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010020#include "llvm/Support/MemAlloc.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010021#include "llvm/Support/type_traits.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#include <algorithm>
23#include <cassert>
24#include <cstddef>
25#include <cstdlib>
26#include <cstring>
27#include <initializer_list>
28#include <iterator>
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020029#include <limits>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010030#include <memory>
31#include <new>
32#include <type_traits>
33#include <utility>
34
35namespace llvm {
36
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020037/// This is all the stuff common to all SmallVectors.
38///
39/// The template parameter specifies the type which should be used to hold the
40/// Size and Capacity of the SmallVector, so it can be adjusted.
41/// Using 32 bit size is desirable to shrink the size of the SmallVector.
42/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
43/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
44/// buffering bitcode output - which can exceed 4GB.
45template <class Size_T> class SmallVectorBase {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010046protected:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010047 void *BeginX;
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020048 Size_T Size = 0, Capacity;
49
50 /// The maximum value of the Size_T used.
51 static constexpr size_t SizeTypeMax() {
52 return std::numeric_limits<Size_T>::max();
53 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010054
Andrew Scullcdfcccc2018-10-05 20:58:37 +010055 SmallVectorBase() = delete;
Andrew Walbran3d2c1972020-04-07 12:24:26 +010056 SmallVectorBase(void *FirstEl, size_t TotalCapacity)
57 : BeginX(FirstEl), Capacity(TotalCapacity) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010058
59 /// This is an implementation of the grow() method which only works
60 /// on POD-like data types and is out of line to reduce code duplication.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020061 /// This function will report a fatal error if it cannot increase capacity.
62 void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
63
64 /// Report that MinSize doesn't fit into this vector's size type. Throws
65 /// std::length_error or calls report_fatal_error.
66 LLVM_ATTRIBUTE_NORETURN static void report_size_overflow(size_t MinSize);
67 /// Report that this vector is already at maximum capacity. Throws
68 /// std::length_error or calls report_fatal_error.
69 LLVM_ATTRIBUTE_NORETURN static void report_at_maximum_capacity();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010070
71public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010072 size_t size() const { return Size; }
73 size_t capacity() const { return Capacity; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010074
Andrew Scullcdfcccc2018-10-05 20:58:37 +010075 LLVM_NODISCARD bool empty() const { return !Size; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010076
Andrew Scullcdfcccc2018-10-05 20:58:37 +010077 /// Set the array size to \p N, which the current array must have enough
78 /// capacity for.
79 ///
80 /// This does not construct or destroy any elements in the vector.
81 ///
82 /// Clients can use this in conjunction with capacity() to write past the end
83 /// of the buffer when they know that more elements are available, and only
84 /// update the size later. This avoids the cost of value initializing elements
85 /// which will only be overwritten.
Andrew Walbran3d2c1972020-04-07 12:24:26 +010086 void set_size(size_t N) {
87 assert(N <= capacity());
88 Size = N;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010089 }
90};
91
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020092template <class T>
93using SmallVectorSizeType =
94 typename std::conditional<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
95 uint32_t>::type;
96
Andrew Scullcdfcccc2018-10-05 20:58:37 +010097/// Figure out the offset of the first element.
98template <class T, typename = void> struct SmallVectorAlignmentAndSize {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020099 alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof(
100 SmallVectorBase<SmallVectorSizeType<T>>)];
101 alignas(T) char FirstEl[sizeof(T)];
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100102};
103
104/// This is the part of SmallVectorTemplateBase which does not depend on whether
105/// the type T is a POD. The extra dummy template argument is used by ArrayRef
106/// to avoid unnecessarily requiring T to be complete.
107template <typename T, typename = void>
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200108class SmallVectorTemplateCommon
109 : public SmallVectorBase<SmallVectorSizeType<T>> {
110 using Base = SmallVectorBase<SmallVectorSizeType<T>>;
111
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100112 /// Find the address of the first element. For this pointer math to be valid
113 /// with small-size of 0 for T with lots of alignment, it's important that
114 /// SmallVectorStorage is properly-aligned even for small-size of 0.
115 void *getFirstEl() const {
116 return const_cast<void *>(reinterpret_cast<const void *>(
117 reinterpret_cast<const char *>(this) +
118 offsetof(SmallVectorAlignmentAndSize<T>, FirstEl)));
119 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100120 // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
121
122protected:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200123 SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100124
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200125 void grow_pod(size_t MinSize, size_t TSize) {
126 Base::grow_pod(getFirstEl(), MinSize, TSize);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100127 }
128
129 /// Return true if this is a smallvector which has not had dynamic
130 /// memory allocated for it.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200131 bool isSmall() const { return this->BeginX == getFirstEl(); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100132
133 /// Put this vector in a state of being small.
134 void resetToSmall() {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200135 this->BeginX = getFirstEl();
136 this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
137 }
138
139 /// Return true if V is an internal reference to the given range.
140 bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
141 // Use std::less to avoid UB.
142 std::less<> LessThan;
143 return !LessThan(V, First) && LessThan(V, Last);
144 }
145
146 /// Return true if V is an internal reference to this vector.
147 bool isReferenceToStorage(const void *V) const {
148 return isReferenceToRange(V, this->begin(), this->end());
149 }
150
151 /// Return true if First and Last form a valid (possibly empty) range in this
152 /// vector's storage.
153 bool isRangeInStorage(const void *First, const void *Last) const {
154 // Use std::less to avoid UB.
155 std::less<> LessThan;
156 return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
157 !LessThan(this->end(), Last);
158 }
159
160 /// Return true unless Elt will be invalidated by resizing the vector to
161 /// NewSize.
162 bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
163 // Past the end.
164 if (LLVM_LIKELY(!isReferenceToStorage(Elt)))
165 return true;
166
167 // Return false if Elt will be destroyed by shrinking.
168 if (NewSize <= this->size())
169 return Elt < this->begin() + NewSize;
170
171 // Return false if we need to grow.
172 return NewSize <= this->capacity();
173 }
174
175 /// Check whether Elt will be invalidated by resizing the vector to NewSize.
176 void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
177 assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
178 "Attempting to reference an element of the vector in an operation "
179 "that invalidates it");
180 }
181
182 /// Check whether Elt will be invalidated by increasing the size of the
183 /// vector by N.
184 void assertSafeToAdd(const void *Elt, size_t N = 1) {
185 this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
186 }
187
188 /// Check whether any part of the range will be invalidated by clearing.
189 void assertSafeToReferenceAfterClear(const T *From, const T *To) {
190 if (From == To)
191 return;
192 this->assertSafeToReferenceAfterResize(From, 0);
193 this->assertSafeToReferenceAfterResize(To - 1, 0);
194 }
195 template <
196 class ItTy,
197 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
198 bool> = false>
199 void assertSafeToReferenceAfterClear(ItTy, ItTy) {}
200
201 /// Check whether any part of the range will be invalidated by growing.
202 void assertSafeToAddRange(const T *From, const T *To) {
203 if (From == To)
204 return;
205 this->assertSafeToAdd(From, To - From);
206 this->assertSafeToAdd(To - 1, To - From);
207 }
208 template <
209 class ItTy,
210 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
211 bool> = false>
212 void assertSafeToAddRange(ItTy, ItTy) {}
213
214 /// Check whether any argument will be invalidated by growing for
215 /// emplace_back.
216 template <class ArgType1, class... ArgTypes>
217 void assertSafeToEmplace(ArgType1 &Arg1, ArgTypes &... Args) {
218 this->assertSafeToAdd(&Arg1);
219 this->assertSafeToEmplace(Args...);
220 }
221 void assertSafeToEmplace() {}
222
223 /// Reserve enough space to add one element, and return the updated element
224 /// pointer in case it was a reference to the storage.
225 template <class U>
226 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
227 size_t N) {
228 size_t NewSize = This->size() + N;
229 if (LLVM_LIKELY(NewSize <= This->capacity()))
230 return &Elt;
231
232 bool ReferencesStorage = false;
233 int64_t Index = -1;
234 if (!U::TakesParamByValue) {
235 if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
236 ReferencesStorage = true;
237 Index = &Elt - This->begin();
238 }
239 }
240 This->grow(NewSize);
241 return ReferencesStorage ? This->begin() + Index : &Elt;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100242 }
243
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100244public:
245 using size_type = size_t;
246 using difference_type = ptrdiff_t;
247 using value_type = T;
248 using iterator = T *;
249 using const_iterator = const T *;
250
251 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
252 using reverse_iterator = std::reverse_iterator<iterator>;
253
254 using reference = T &;
255 using const_reference = const T &;
256 using pointer = T *;
257 using const_pointer = const T *;
258
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200259 using Base::capacity;
260 using Base::empty;
261 using Base::size;
262
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100263 // forward iterator creation methods.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100264 iterator begin() { return (iterator)this->BeginX; }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100265 const_iterator begin() const { return (const_iterator)this->BeginX; }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100266 iterator end() { return begin() + size(); }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100267 const_iterator end() const { return begin() + size(); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100268
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100269 // reverse iterator creation methods.
270 reverse_iterator rbegin() { return reverse_iterator(end()); }
271 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
272 reverse_iterator rend() { return reverse_iterator(begin()); }
273 const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
274
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100275 size_type size_in_bytes() const { return size() * sizeof(T); }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200276 size_type max_size() const {
277 return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
278 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100279
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100280 size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100281
282 /// Return a pointer to the vector's buffer, even if empty().
283 pointer data() { return pointer(begin()); }
284 /// Return a pointer to the vector's buffer, even if empty().
285 const_pointer data() const { return const_pointer(begin()); }
286
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100287 reference operator[](size_type idx) {
288 assert(idx < size());
289 return begin()[idx];
290 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100291 const_reference operator[](size_type idx) const {
292 assert(idx < size());
293 return begin()[idx];
294 }
295
296 reference front() {
297 assert(!empty());
298 return begin()[0];
299 }
300 const_reference front() const {
301 assert(!empty());
302 return begin()[0];
303 }
304
305 reference back() {
306 assert(!empty());
307 return end()[-1];
308 }
309 const_reference back() const {
310 assert(!empty());
311 return end()[-1];
312 }
313};
314
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200315/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put
316/// method implementations that are designed to work with non-trivial T's.
317///
318/// We approximate is_trivially_copyable with trivial move/copy construction and
319/// trivial destruction. While the standard doesn't specify that you're allowed
320/// copy these types with memcpy, there is no way for the type to observe this.
321/// This catches the important case of std::pair<POD, POD>, which is not
322/// trivially assignable.
323template <typename T, bool = (is_trivially_copy_constructible<T>::value) &&
324 (is_trivially_move_constructible<T>::value) &&
325 std::is_trivially_destructible<T>::value>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100326class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200327 friend class SmallVectorTemplateCommon<T>;
328
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100329protected:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200330 static constexpr bool TakesParamByValue = false;
331 using ValueParamT = const T &;
332
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100333 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
334
335 static void destroy_range(T *S, T *E) {
336 while (S != E) {
337 --E;
338 E->~T();
339 }
340 }
341
342 /// Move the range [I, E) into the uninitialized memory starting with "Dest",
343 /// constructing elements as needed.
344 template<typename It1, typename It2>
345 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
346 std::uninitialized_copy(std::make_move_iterator(I),
347 std::make_move_iterator(E), Dest);
348 }
349
350 /// Copy the range [I, E) onto the uninitialized memory starting with "Dest",
351 /// constructing elements as needed.
352 template<typename It1, typename It2>
353 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
354 std::uninitialized_copy(I, E, Dest);
355 }
356
357 /// Grow the allocated memory (without initializing new elements), doubling
358 /// the size of the allocated memory. Guarantees space for at least one more
359 /// element, or MinSize more elements if specified.
360 void grow(size_t MinSize = 0);
361
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200362 /// Reserve enough space to add one element, and return the updated element
363 /// pointer in case it was a reference to the storage.
364 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
365 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
366 }
367
368 /// Reserve enough space to add one element, and return the updated element
369 /// pointer in case it was a reference to the storage.
370 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
371 return const_cast<T *>(
372 this->reserveForParamAndGetAddressImpl(this, Elt, N));
373 }
374
375 static T &&forward_value_param(T &&V) { return std::move(V); }
376 static const T &forward_value_param(const T &V) { return V; }
377
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100378public:
379 void push_back(const T &Elt) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200380 const T *EltPtr = reserveForParamAndGetAddress(Elt);
381 ::new ((void *)this->end()) T(*EltPtr);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100382 this->set_size(this->size() + 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100383 }
384
385 void push_back(T &&Elt) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200386 T *EltPtr = reserveForParamAndGetAddress(Elt);
387 ::new ((void *)this->end()) T(::std::move(*EltPtr));
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100388 this->set_size(this->size() + 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100389 }
390
391 void pop_back() {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100392 this->set_size(this->size() - 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100393 this->end()->~T();
394 }
395};
396
397// Define this out-of-line to dissuade the C++ compiler from inlining it.
Andrew Walbran16937d02019-10-22 13:54:20 +0100398template <typename T, bool TriviallyCopyable>
399void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200400 // Ensure we can fit the new capacity.
401 // This is only going to be applicable when the capacity is 32 bit.
402 if (MinSize > this->SizeTypeMax())
403 this->report_size_overflow(MinSize);
404
405 // Ensure we can meet the guarantee of space for at least one more element.
406 // The above check alone will not catch the case where grow is called with a
407 // default MinSize of 0, but the current capacity cannot be increased.
408 // This is only going to be applicable when the capacity is 32 bit.
409 if (this->capacity() == this->SizeTypeMax())
410 this->report_at_maximum_capacity();
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100411
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100412 // Always grow, even from zero.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100413 size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2));
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200414 NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100415 T *NewElts = static_cast<T*>(llvm::safe_malloc(NewCapacity*sizeof(T)));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100416
417 // Move the elements over.
418 this->uninitialized_move(this->begin(), this->end(), NewElts);
419
420 // Destroy the original elements.
421 destroy_range(this->begin(), this->end());
422
423 // If this wasn't grown from the inline copy, deallocate the old space.
424 if (!this->isSmall())
425 free(this->begin());
426
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100427 this->BeginX = NewElts;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100428 this->Capacity = NewCapacity;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100429}
430
Andrew Walbran16937d02019-10-22 13:54:20 +0100431/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200432/// method implementations that are designed to work with trivially copyable
433/// T's. This allows using memcpy in place of copy/move construction and
434/// skipping destruction.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100435template <typename T>
436class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200437 friend class SmallVectorTemplateCommon<T>;
438
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100439protected:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200440 /// True if it's cheap enough to take parameters by value. Doing so avoids
441 /// overhead related to mitigations for reference invalidation.
442 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
443
444 /// Either const T& or T, depending on whether it's cheap enough to take
445 /// parameters by value.
446 using ValueParamT =
447 typename std::conditional<TakesParamByValue, T, const T &>::type;
448
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100449 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
450
451 // No need to do a destroy loop for POD's.
452 static void destroy_range(T *, T *) {}
453
454 /// Move the range [I, E) onto the uninitialized memory
455 /// starting with "Dest", constructing elements into it as needed.
456 template<typename It1, typename It2>
457 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
458 // Just do a copy.
459 uninitialized_copy(I, E, Dest);
460 }
461
462 /// Copy the range [I, E) onto the uninitialized memory
463 /// starting with "Dest", constructing elements into it as needed.
464 template<typename It1, typename It2>
465 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
466 // Arbitrary iterator types; just use the basic implementation.
467 std::uninitialized_copy(I, E, Dest);
468 }
469
470 /// Copy the range [I, E) onto the uninitialized memory
471 /// starting with "Dest", constructing elements into it as needed.
472 template <typename T1, typename T2>
473 static void uninitialized_copy(
474 T1 *I, T1 *E, T2 *Dest,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200475 std::enable_if_t<std::is_same<typename std::remove_const<T1>::type,
476 T2>::value> * = nullptr) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100477 // Use memcpy for PODs iterated by pointers (which includes SmallVector
478 // iterators): std::uninitialized_copy optimizes to memmove, but we can
479 // use memcpy here. Note that I and E are iterators and thus might be
480 // invalid for memcpy if they are equal.
481 if (I != E)
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100482 memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100483 }
484
485 /// Double the size of the allocated memory, guaranteeing space for at
486 /// least one more element or MinSize if specified.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100487 void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100488
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200489 /// Reserve enough space to add one element, and return the updated element
490 /// pointer in case it was a reference to the storage.
491 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
492 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
493 }
494
495 /// Reserve enough space to add one element, and return the updated element
496 /// pointer in case it was a reference to the storage.
497 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
498 return const_cast<T *>(
499 this->reserveForParamAndGetAddressImpl(this, Elt, N));
500 }
501
502 /// Copy \p V or return a reference, depending on \a ValueParamT.
503 static ValueParamT forward_value_param(ValueParamT V) { return V; }
504
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100505public:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200506 void push_back(ValueParamT Elt) {
507 const T *EltPtr = reserveForParamAndGetAddress(Elt);
508 memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100509 this->set_size(this->size() + 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100510 }
511
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100512 void pop_back() { this->set_size(this->size() - 1); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100513};
514
515/// This class consists of common code factored out of the SmallVector class to
516/// reduce code duplication based on the SmallVector 'N' template parameter.
517template <typename T>
Andrew Walbran16937d02019-10-22 13:54:20 +0100518class SmallVectorImpl : public SmallVectorTemplateBase<T> {
519 using SuperClass = SmallVectorTemplateBase<T>;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100520
521public:
522 using iterator = typename SuperClass::iterator;
523 using const_iterator = typename SuperClass::const_iterator;
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100524 using reference = typename SuperClass::reference;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100525 using size_type = typename SuperClass::size_type;
526
527protected:
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200528 using SmallVectorTemplateBase<T>::TakesParamByValue;
529 using ValueParamT = typename SuperClass::ValueParamT;
530
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100531 // Default ctor - Initialize to empty.
532 explicit SmallVectorImpl(unsigned N)
Andrew Walbran16937d02019-10-22 13:54:20 +0100533 : SmallVectorTemplateBase<T>(N) {}
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100534
535public:
536 SmallVectorImpl(const SmallVectorImpl &) = delete;
537
538 ~SmallVectorImpl() {
539 // Subclass has already destructed this vector's elements.
540 // If this wasn't grown from the inline copy, deallocate the old space.
541 if (!this->isSmall())
542 free(this->begin());
543 }
544
545 void clear() {
546 this->destroy_range(this->begin(), this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100547 this->Size = 0;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100548 }
549
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200550private:
551 template <bool ForOverwrite> void resizeImpl(size_type N) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100552 if (N < this->size()) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200553 this->pop_back_n(this->size() - N);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100554 } else if (N > this->size()) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200555 this->reserve(N);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100556 for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200557 if (ForOverwrite)
558 new (&*I) T;
559 else
560 new (&*I) T();
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100561 this->set_size(N);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100562 }
563 }
564
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200565public:
566 void resize(size_type N) { resizeImpl<false>(N); }
567
568 /// Like resize, but \ref T is POD, the new values won't be initialized.
569 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
570
571 void resize(size_type N, ValueParamT NV) {
572 if (N == this->size())
573 return;
574
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100575 if (N < this->size()) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200576 this->pop_back_n(this->size() - N);
577 return;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100578 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200579
580 // N > this->size(). Defer to append.
581 this->append(N - this->size(), NV);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100582 }
583
584 void reserve(size_type N) {
585 if (this->capacity() < N)
586 this->grow(N);
587 }
588
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200589 void pop_back_n(size_type NumItems) {
590 assert(this->size() >= NumItems);
591 this->destroy_range(this->end() - NumItems, this->end());
592 this->set_size(this->size() - NumItems);
593 }
594
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100595 LLVM_NODISCARD T pop_back_val() {
596 T Result = ::std::move(this->back());
597 this->pop_back();
598 return Result;
599 }
600
601 void swap(SmallVectorImpl &RHS);
602
603 /// Add the specified range to the end of the SmallVector.
604 template <typename in_iter,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200605 typename = std::enable_if_t<std::is_convertible<
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100606 typename std::iterator_traits<in_iter>::iterator_category,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200607 std::input_iterator_tag>::value>>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100608 void append(in_iter in_start, in_iter in_end) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200609 this->assertSafeToAddRange(in_start, in_end);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100610 size_type NumInputs = std::distance(in_start, in_end);
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200611 this->reserve(this->size() + NumInputs);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100612 this->uninitialized_copy(in_start, in_end, this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100613 this->set_size(this->size() + NumInputs);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100614 }
615
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100616 /// Append \p NumInputs copies of \p Elt to the end.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200617 void append(size_type NumInputs, ValueParamT Elt) {
618 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
619 std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100620 this->set_size(this->size() + NumInputs);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100621 }
622
623 void append(std::initializer_list<T> IL) {
624 append(IL.begin(), IL.end());
625 }
626
627 // FIXME: Consider assigning over existing elements, rather than clearing &
628 // re-initializing them - for all assign(...) variants.
629
630 void assign(size_type NumElts, const T &Elt) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200631 this->assertSafeToReferenceAfterResize(&Elt, 0);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100632 clear();
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200633 this->reserve(NumElts);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100634 this->set_size(NumElts);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100635 std::uninitialized_fill(this->begin(), this->end(), Elt);
636 }
637
638 template <typename in_iter,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200639 typename = std::enable_if_t<std::is_convertible<
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100640 typename std::iterator_traits<in_iter>::iterator_category,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200641 std::input_iterator_tag>::value>>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100642 void assign(in_iter in_start, in_iter in_end) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200643 this->assertSafeToReferenceAfterClear(in_start, in_end);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100644 clear();
645 append(in_start, in_end);
646 }
647
648 void assign(std::initializer_list<T> IL) {
649 clear();
650 append(IL);
651 }
652
653 iterator erase(const_iterator CI) {
654 // Just cast away constness because this is a non-const member function.
655 iterator I = const_cast<iterator>(CI);
656
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200657 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100658
659 iterator N = I;
660 // Shift all elts down one.
661 std::move(I+1, this->end(), I);
662 // Drop the last elt.
663 this->pop_back();
664 return(N);
665 }
666
667 iterator erase(const_iterator CS, const_iterator CE) {
668 // Just cast away constness because this is a non-const member function.
669 iterator S = const_cast<iterator>(CS);
670 iterator E = const_cast<iterator>(CE);
671
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200672 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100673
674 iterator N = S;
675 // Shift all elts down.
676 iterator I = std::move(E, this->end(), S);
677 // Drop the last elts.
678 this->destroy_range(I, this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100679 this->set_size(I - this->begin());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100680 return(N);
681 }
682
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200683private:
684 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
685 // Callers ensure that ArgType is derived from T.
686 static_assert(
687 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
688 T>::value,
689 "ArgType must be derived from T!");
690
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100691 if (I == this->end()) { // Important special case for empty vector.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200692 this->push_back(::std::forward<ArgType>(Elt));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100693 return this->end()-1;
694 }
695
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200696 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100697
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200698 // Grow if necessary.
699 size_t Index = I - this->begin();
700 std::remove_reference_t<ArgType> *EltPtr =
701 this->reserveForParamAndGetAddress(Elt);
702 I = this->begin() + Index;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100703
704 ::new ((void*) this->end()) T(::std::move(this->back()));
705 // Push everything else over.
706 std::move_backward(I, this->end()-1, this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100707 this->set_size(this->size() + 1);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100708
709 // If we just moved the element we're inserting, be sure to update
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200710 // the reference (never happens if TakesParamByValue).
711 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
712 "ArgType must be 'T' when taking by value!");
713 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100714 ++EltPtr;
715
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200716 *I = ::std::forward<ArgType>(*EltPtr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100717 return I;
718 }
719
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200720public:
721 iterator insert(iterator I, T &&Elt) {
722 return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
723 }
724
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100725 iterator insert(iterator I, const T &Elt) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200726 return insert_one_impl(I, this->forward_value_param(Elt));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100727 }
728
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200729 iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100730 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
731 size_t InsertElt = I - this->begin();
732
733 if (I == this->end()) { // Important special case for empty vector.
734 append(NumToInsert, Elt);
735 return this->begin()+InsertElt;
736 }
737
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200738 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100739
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200740 // Ensure there is enough space, and get the (maybe updated) address of
741 // Elt.
742 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100743
744 // Uninvalidate the iterator.
745 I = this->begin()+InsertElt;
746
747 // If there are more elements between the insertion point and the end of the
748 // range than there are being inserted, we can use a simple approach to
749 // insertion. Since we already reserved space, we know that this won't
750 // reallocate the vector.
751 if (size_t(this->end()-I) >= NumToInsert) {
752 T *OldEnd = this->end();
753 append(std::move_iterator<iterator>(this->end() - NumToInsert),
754 std::move_iterator<iterator>(this->end()));
755
756 // Copy the existing elements that get replaced.
757 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
758
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200759 // If we just moved the element we're inserting, be sure to update
760 // the reference (never happens if TakesParamByValue).
761 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
762 EltPtr += NumToInsert;
763
764 std::fill_n(I, NumToInsert, *EltPtr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100765 return I;
766 }
767
768 // Otherwise, we're inserting more elements than exist already, and we're
769 // not inserting at the end.
770
771 // Move over the elements that we're about to overwrite.
772 T *OldEnd = this->end();
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100773 this->set_size(this->size() + NumToInsert);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100774 size_t NumOverwritten = OldEnd-I;
775 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
776
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200777 // If we just moved the element we're inserting, be sure to update
778 // the reference (never happens if TakesParamByValue).
779 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
780 EltPtr += NumToInsert;
781
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100782 // Replace the overwritten part.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200783 std::fill_n(I, NumOverwritten, *EltPtr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100784
785 // Insert the non-overwritten middle part.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200786 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100787 return I;
788 }
789
790 template <typename ItTy,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200791 typename = std::enable_if_t<std::is_convertible<
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100792 typename std::iterator_traits<ItTy>::iterator_category,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200793 std::input_iterator_tag>::value>>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100794 iterator insert(iterator I, ItTy From, ItTy To) {
795 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
796 size_t InsertElt = I - this->begin();
797
798 if (I == this->end()) { // Important special case for empty vector.
799 append(From, To);
800 return this->begin()+InsertElt;
801 }
802
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200803 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
804
805 // Check that the reserve that follows doesn't invalidate the iterators.
806 this->assertSafeToAddRange(From, To);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100807
808 size_t NumToInsert = std::distance(From, To);
809
810 // Ensure there is enough space.
811 reserve(this->size() + NumToInsert);
812
813 // Uninvalidate the iterator.
814 I = this->begin()+InsertElt;
815
816 // If there are more elements between the insertion point and the end of the
817 // range than there are being inserted, we can use a simple approach to
818 // insertion. Since we already reserved space, we know that this won't
819 // reallocate the vector.
820 if (size_t(this->end()-I) >= NumToInsert) {
821 T *OldEnd = this->end();
822 append(std::move_iterator<iterator>(this->end() - NumToInsert),
823 std::move_iterator<iterator>(this->end()));
824
825 // Copy the existing elements that get replaced.
826 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
827
828 std::copy(From, To, I);
829 return I;
830 }
831
832 // Otherwise, we're inserting more elements than exist already, and we're
833 // not inserting at the end.
834
835 // Move over the elements that we're about to overwrite.
836 T *OldEnd = this->end();
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100837 this->set_size(this->size() + NumToInsert);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100838 size_t NumOverwritten = OldEnd-I;
839 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
840
841 // Replace the overwritten part.
842 for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
843 *J = *From;
844 ++J; ++From;
845 }
846
847 // Insert the non-overwritten middle part.
848 this->uninitialized_copy(From, To, OldEnd);
849 return I;
850 }
851
852 void insert(iterator I, std::initializer_list<T> IL) {
853 insert(I, IL.begin(), IL.end());
854 }
855
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100856 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200857 this->assertSafeToEmplace(Args...);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100858 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100859 this->grow();
860 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100861 this->set_size(this->size() + 1);
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100862 return this->back();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100863 }
864
865 SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
866
867 SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
868
869 bool operator==(const SmallVectorImpl &RHS) const {
870 if (this->size() != RHS.size()) return false;
871 return std::equal(this->begin(), this->end(), RHS.begin());
872 }
873 bool operator!=(const SmallVectorImpl &RHS) const {
874 return !(*this == RHS);
875 }
876
877 bool operator<(const SmallVectorImpl &RHS) const {
878 return std::lexicographical_compare(this->begin(), this->end(),
879 RHS.begin(), RHS.end());
880 }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100881};
882
883template <typename T>
884void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
885 if (this == &RHS) return;
886
887 // We can only avoid copying elements if neither vector is small.
888 if (!this->isSmall() && !RHS.isSmall()) {
889 std::swap(this->BeginX, RHS.BeginX);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100890 std::swap(this->Size, RHS.Size);
891 std::swap(this->Capacity, RHS.Capacity);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100892 return;
893 }
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200894 this->reserve(RHS.size());
895 RHS.reserve(this->size());
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100896
897 // Swap the shared elements.
898 size_t NumShared = this->size();
899 if (NumShared > RHS.size()) NumShared = RHS.size();
900 for (size_type i = 0; i != NumShared; ++i)
901 std::swap((*this)[i], RHS[i]);
902
903 // Copy over the extra elts.
904 if (this->size() > RHS.size()) {
905 size_t EltDiff = this->size() - RHS.size();
906 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100907 RHS.set_size(RHS.size() + EltDiff);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100908 this->destroy_range(this->begin()+NumShared, this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100909 this->set_size(NumShared);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100910 } else if (RHS.size() > this->size()) {
911 size_t EltDiff = RHS.size() - this->size();
912 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100913 this->set_size(this->size() + EltDiff);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100914 this->destroy_range(RHS.begin()+NumShared, RHS.end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100915 RHS.set_size(NumShared);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100916 }
917}
918
919template <typename T>
920SmallVectorImpl<T> &SmallVectorImpl<T>::
921 operator=(const SmallVectorImpl<T> &RHS) {
922 // Avoid self-assignment.
923 if (this == &RHS) return *this;
924
925 // If we already have sufficient space, assign the common elements, then
926 // destroy any excess.
927 size_t RHSSize = RHS.size();
928 size_t CurSize = this->size();
929 if (CurSize >= RHSSize) {
930 // Assign common elements.
931 iterator NewEnd;
932 if (RHSSize)
933 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
934 else
935 NewEnd = this->begin();
936
937 // Destroy excess elements.
938 this->destroy_range(NewEnd, this->end());
939
940 // Trim.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100941 this->set_size(RHSSize);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100942 return *this;
943 }
944
945 // If we have to grow to have enough elements, destroy the current elements.
946 // This allows us to avoid copying them during the grow.
947 // FIXME: don't do this if they're efficiently moveable.
948 if (this->capacity() < RHSSize) {
949 // Destroy current elements.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +0200950 this->clear();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100951 CurSize = 0;
952 this->grow(RHSSize);
953 } else if (CurSize) {
954 // Otherwise, use assignment for the already-constructed elements.
955 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
956 }
957
958 // Copy construct the new elements in place.
959 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
960 this->begin()+CurSize);
961
962 // Set end.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100963 this->set_size(RHSSize);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100964 return *this;
965}
966
967template <typename T>
968SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
969 // Avoid self-assignment.
970 if (this == &RHS) return *this;
971
972 // If the RHS isn't small, clear this vector and then steal its buffer.
973 if (!RHS.isSmall()) {
974 this->destroy_range(this->begin(), this->end());
975 if (!this->isSmall()) free(this->begin());
976 this->BeginX = RHS.BeginX;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100977 this->Size = RHS.Size;
978 this->Capacity = RHS.Capacity;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100979 RHS.resetToSmall();
980 return *this;
981 }
982
983 // If we already have sufficient space, assign the common elements, then
984 // destroy any excess.
985 size_t RHSSize = RHS.size();
986 size_t CurSize = this->size();
987 if (CurSize >= RHSSize) {
988 // Assign common elements.
989 iterator NewEnd = this->begin();
990 if (RHSSize)
991 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
992
993 // Destroy excess elements and trim the bounds.
994 this->destroy_range(NewEnd, this->end());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100995 this->set_size(RHSSize);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100996
997 // Clear the RHS.
998 RHS.clear();
999
1000 return *this;
1001 }
1002
1003 // If we have to grow to have enough elements, destroy the current elements.
1004 // This allows us to avoid copying them during the grow.
1005 // FIXME: this may not actually make any sense if we can efficiently move
1006 // elements.
1007 if (this->capacity() < RHSSize) {
1008 // Destroy current elements.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001009 this->clear();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001010 CurSize = 0;
1011 this->grow(RHSSize);
1012 } else if (CurSize) {
1013 // Otherwise, use assignment for the already-constructed elements.
1014 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin());
1015 }
1016
1017 // Move-construct the new elements in place.
1018 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
1019 this->begin()+CurSize);
1020
1021 // Set end.
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001022 this->set_size(RHSSize);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001023
1024 RHS.clear();
1025 return *this;
1026}
1027
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001028/// Storage for the SmallVector elements. This is specialized for the N=0 case
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001029/// to avoid allocating unnecessary storage.
1030template <typename T, unsigned N>
1031struct SmallVectorStorage {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001032 alignas(T) char InlineElts[N * sizeof(T)];
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001033};
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001034
1035/// We need the storage to be properly aligned even for small-size of 0 so that
1036/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
1037/// well-defined.
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001038template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
1039
1040/// Forward declaration of SmallVector so that
1041/// calculateSmallVectorDefaultInlinedElements can reference
1042/// `sizeof(SmallVector<T, 0>)`.
1043template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
1044
1045/// Helper class for calculating the default number of inline elements for
1046/// `SmallVector<T>`.
1047///
1048/// This should be migrated to a constexpr function when our minimum
1049/// compiler support is enough for multi-statement constexpr functions.
1050template <typename T> struct CalculateSmallVectorDefaultInlinedElements {
1051 // Parameter controlling the default number of inlined elements
1052 // for `SmallVector<T>`.
1053 //
1054 // The default number of inlined elements ensures that
1055 // 1. There is at least one inlined element.
1056 // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
1057 // it contradicts 1.
1058 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1059
1060 // static_assert that sizeof(T) is not "too big".
1061 //
1062 // Because our policy guarantees at least one inlined element, it is possible
1063 // for an arbitrarily large inlined element to allocate an arbitrarily large
1064 // amount of inline storage. We generally consider it an antipattern for a
1065 // SmallVector to allocate an excessive amount of inline storage, so we want
1066 // to call attention to these cases and make sure that users are making an
1067 // intentional decision if they request a lot of inline storage.
1068 //
1069 // We want this assertion to trigger in pathological cases, but otherwise
1070 // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
1071 // larger than kPreferredSmallVectorSizeof (otherwise,
1072 // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
1073 // pattern seems useful in practice).
1074 //
1075 // One wrinkle is that this assertion is in theory non-portable, since
1076 // sizeof(T) is in general platform-dependent. However, we don't expect this
1077 // to be much of an issue, because most LLVM development happens on 64-bit
1078 // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
1079 // 32-bit hosts, dodging the issue. The reverse situation, where development
1080 // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
1081 // 64-bit host, is expected to be very rare.
1082 static_assert(
1083 sizeof(T) <= 256,
1084 "You are trying to use a default number of inlined elements for "
1085 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1086 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1087 "sure you really want that much inline storage.");
1088
1089 // Discount the size of the header itself when calculating the maximum inline
1090 // bytes.
1091 static constexpr size_t PreferredInlineBytes =
1092 kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>);
1093 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
1094 static constexpr size_t value =
1095 NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
1096};
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001097
1098/// This is a 'vector' (really, a variable-sized array), optimized
1099/// for the case when the array is small. It contains some number of elements
1100/// in-place, which allows it to avoid heap allocation when the actual number of
1101/// elements is below that threshold. This allows normal "small" cases to be
1102/// fast without losing generality for large inputs.
1103///
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001104/// \note
1105/// In the absence of a well-motivated choice for the number of inlined
1106/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
1107/// omitting the \p N). This will choose a default number of inlined elements
1108/// reasonable for allocation on the stack (for example, trying to keep \c
1109/// sizeof(SmallVector<T>) around 64 bytes).
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001110///
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001111/// \warning This does not attempt to be exception safe.
1112///
1113/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
1114template <typename T,
1115 unsigned N = CalculateSmallVectorDefaultInlinedElements<T>::value>
1116class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>,
1117 SmallVectorStorage<T, N> {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001118public:
1119 SmallVector() : SmallVectorImpl<T>(N) {}
1120
1121 ~SmallVector() {
1122 // Destroy the constructed elements in the vector.
1123 this->destroy_range(this->begin(), this->end());
1124 }
1125
1126 explicit SmallVector(size_t Size, const T &Value = T())
1127 : SmallVectorImpl<T>(N) {
1128 this->assign(Size, Value);
1129 }
1130
1131 template <typename ItTy,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001132 typename = std::enable_if_t<std::is_convertible<
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001133 typename std::iterator_traits<ItTy>::iterator_category,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001134 std::input_iterator_tag>::value>>
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001135 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
1136 this->append(S, E);
1137 }
1138
1139 template <typename RangeTy>
1140 explicit SmallVector(const iterator_range<RangeTy> &R)
1141 : SmallVectorImpl<T>(N) {
1142 this->append(R.begin(), R.end());
1143 }
1144
1145 SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
1146 this->assign(IL);
1147 }
1148
1149 SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
1150 if (!RHS.empty())
1151 SmallVectorImpl<T>::operator=(RHS);
1152 }
1153
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001154 SmallVector &operator=(const SmallVector &RHS) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001155 SmallVectorImpl<T>::operator=(RHS);
1156 return *this;
1157 }
1158
1159 SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
1160 if (!RHS.empty())
1161 SmallVectorImpl<T>::operator=(::std::move(RHS));
1162 }
1163
1164 SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) {
1165 if (!RHS.empty())
1166 SmallVectorImpl<T>::operator=(::std::move(RHS));
1167 }
1168
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001169 SmallVector &operator=(SmallVector &&RHS) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001170 SmallVectorImpl<T>::operator=(::std::move(RHS));
1171 return *this;
1172 }
1173
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001174 SmallVector &operator=(SmallVectorImpl<T> &&RHS) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001175 SmallVectorImpl<T>::operator=(::std::move(RHS));
1176 return *this;
1177 }
1178
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001179 SmallVector &operator=(std::initializer_list<T> IL) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001180 this->assign(IL);
1181 return *this;
1182 }
1183};
1184
1185template <typename T, unsigned N>
1186inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
1187 return X.capacity_in_bytes();
1188}
1189
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001190/// Given a range of type R, iterate the entire range and return a
1191/// SmallVector with elements of the vector. This is useful, for example,
1192/// when you want to iterate a range and then sort the results.
1193template <unsigned Size, typename R>
1194SmallVector<typename std::remove_const<typename std::remove_reference<
1195 decltype(*std::begin(std::declval<R &>()))>::type>::type,
1196 Size>
1197to_vector(R &&Range) {
1198 return {std::begin(Range), std::end(Range)};
1199}
1200
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001201} // end namespace llvm
1202
1203namespace std {
1204
1205 /// Implement std::swap in terms of SmallVector swap.
1206 template<typename T>
1207 inline void
1208 swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
1209 LHS.swap(RHS);
1210 }
1211
1212 /// Implement std::swap in terms of SmallVector swap.
1213 template<typename T, unsigned N>
1214 inline void
1215 swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
1216 LHS.swap(RHS);
1217 }
1218
1219} // end namespace std
1220
1221#endif // LLVM_ADT_SMALLVECTOR_H