SmallVector.h (47703B)
1 //===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===// 2 // 3 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file defines the SmallVector class. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_ADT_SMALLVECTOR_H 15 #define LLVM_ADT_SMALLVECTOR_H 16 17 #ifdef _MSC_VER 18 #pragma warning(push) 19 #pragma warning(disable: 4267) // warning C4267: '=': conversion from 'size_t' to 'Size_T', possible loss of data 20 #pragma warning(disable: 4324) // warning C4324: 'llvm::SmallVectorStorage<T,0>': structure was padded due to alignment specifier 21 #pragma warning(disable: 4100) // warning C4100: 'TSize': unreferenced formal parameter 22 #endif 23 24 //#include "llvm/Support/Compiler.h" 25 //#include "llvm/Support/type_traits.h" 26 #include <algorithm> 27 #include <cassert> 28 #include <cstddef> 29 #include <cstdlib> 30 #include <cstring> 31 #include <functional> 32 #include <initializer_list> 33 #include <iterator> 34 #include <limits> 35 #include <memory> 36 #include <new> 37 #include <type_traits> 38 #include <utility> 39 40 namespace llvm { 41 42 template <typename T> class ArrayRef; 43 44 template <typename IteratorT> class iterator_range; 45 46 template <class Iterator> 47 using EnableIfConvertibleToInputIterator = std::enable_if_t<std::is_convertible< 48 typename std::iterator_traits<Iterator>::iterator_category, 49 std::input_iterator_tag>::value>; 50 51 /// This is all the stuff common to all SmallVectors. 52 /// 53 /// The template parameter specifies the type which should be used to hold the 54 /// Size and Capacity of the SmallVector, so it can be adjusted. 55 /// Using 32 bit size is desirable to shrink the size of the SmallVector. 56 /// Using 64 bit size is desirable for cases like SmallVector<char>, where a 57 /// 32 bit size would limit the vector to ~4GB. SmallVectors are used for 58 /// buffering bitcode output - which can exceed 4GB. 59 template <class Size_T> class SmallVectorBase { 60 protected: 61 void *BeginX; 62 Size_T Size = 0, Capacity; 63 64 /// The maximum value of the Size_T used. 65 static constexpr size_t SizeTypeMax() { 66 return std::numeric_limits<Size_T>::max(); 67 } 68 69 SmallVectorBase() = delete; 70 SmallVectorBase(void *FirstEl, size_t TotalCapacity) 71 : BeginX(FirstEl), Capacity(TotalCapacity) {} 72 73 /// This is a helper for \a grow() that's out of line to reduce code 74 /// duplication. This function will report a fatal error if it can't grow at 75 /// least to \p MinSize. 76 void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize, 77 size_t &NewCapacity); 78 79 /// This is an implementation of the grow() method which only works 80 /// on POD-like data types and is out of line to reduce code duplication. 81 /// This function will report a fatal error if it cannot increase capacity. 82 void grow_pod(void *FirstEl, size_t MinSize, size_t TSize); 83 84 /// If vector was first created with capacity 0, getFirstEl() points to the 85 /// memory right after, an area unallocated. If a subsequent allocation, 86 /// that grows the vector, happens to return the same pointer as getFirstEl(), 87 /// get a new allocation, otherwise isSmall() will falsely return that no 88 /// allocation was done (true) and the memory will not be freed in the 89 /// destructor. If a VSize is given (vector size), also copy that many 90 /// elements to the new allocation - used if realloca fails to increase 91 /// space, and happens to allocate precisely at BeginX. 92 /// This is unlikely to be called often, but resolves a memory leak when the 93 /// situation does occur. 94 void *replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity, 95 size_t VSize = 0); 96 97 public: 98 size_t size() const { return Size; } 99 size_t capacity() const { return Capacity; } 100 101 [[nodiscard]] bool empty() const { return !Size; } 102 103 protected: 104 /// Set the array size to \p N, which the current array must have enough 105 /// capacity for. 106 /// 107 /// This does not construct or destroy any elements in the vector. 108 void set_size(size_t N) { 109 assert(N <= capacity()); 110 Size = N; 111 } 112 }; 113 114 template <class T> 115 using SmallVectorSizeType = 116 std::conditional_t<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t, 117 uint32_t>; 118 119 /// Figure out the offset of the first element. 120 template <class T, typename = void> struct SmallVectorAlignmentAndSize { 121 alignas(SmallVectorBase<SmallVectorSizeType<T>>) char Base[sizeof( 122 SmallVectorBase<SmallVectorSizeType<T>>)]; 123 alignas(T) char FirstEl[sizeof(T)]; 124 }; 125 126 /// This is the part of SmallVectorTemplateBase which does not depend on whether 127 /// the type T is a POD. The extra dummy template argument is used by ArrayRef 128 /// to avoid unnecessarily requiring T to be complete. 129 template <typename T, typename = void> 130 class SmallVectorTemplateCommon 131 : public SmallVectorBase<SmallVectorSizeType<T>> { 132 using Base = SmallVectorBase<SmallVectorSizeType<T>>; 133 134 protected: 135 /// Find the address of the first element. For this pointer math to be valid 136 /// with small-size of 0 for T with lots of alignment, it's important that 137 /// SmallVectorStorage is properly-aligned even for small-size of 0. 138 void *getFirstEl() const { 139 return const_cast<void *>(reinterpret_cast<const void *>( 140 reinterpret_cast<const char *>(this) + 141 offsetof(SmallVectorAlignmentAndSize<T>, FirstEl))); 142 } 143 // Space after 'FirstEl' is clobbered, do not add any instance vars after it. 144 145 SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {} 146 147 void grow_pod(size_t MinSize, size_t TSize) { 148 Base::grow_pod(getFirstEl(), MinSize, TSize); 149 } 150 151 /// Return true if this is a smallvector which has not had dynamic 152 /// memory allocated for it. 153 bool isSmall() const { return this->BeginX == getFirstEl(); } 154 155 /// Put this vector in a state of being small. 156 void resetToSmall() { 157 this->BeginX = getFirstEl(); 158 this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect. 159 } 160 161 /// Return true if V is an internal reference to the given range. 162 bool isReferenceToRange(const void *V, const void *First, const void *Last) const { 163 // Use std::less to avoid UB. 164 std::less<> LessThan; 165 return !LessThan(V, First) && LessThan(V, Last); 166 } 167 168 /// Return true if V is an internal reference to this vector. 169 bool isReferenceToStorage(const void *V) const { 170 return isReferenceToRange(V, this->begin(), this->end()); 171 } 172 173 /// Return true if First and Last form a valid (possibly empty) range in this 174 /// vector's storage. 175 bool isRangeInStorage(const void *First, const void *Last) const { 176 // Use std::less to avoid UB. 177 std::less<> LessThan; 178 return !LessThan(First, this->begin()) && !LessThan(Last, First) && 179 !LessThan(this->end(), Last); 180 } 181 182 /// Return true unless Elt will be invalidated by resizing the vector to 183 /// NewSize. 184 bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) { 185 // Past the end. 186 if (LLVM_LIKELY(!isReferenceToStorage(Elt))) 187 return true; 188 189 // Return false if Elt will be destroyed by shrinking. 190 if (NewSize <= this->size()) 191 return Elt < this->begin() + NewSize; 192 193 // Return false if we need to grow. 194 return NewSize <= this->capacity(); 195 } 196 197 /// Check whether Elt will be invalidated by resizing the vector to NewSize. 198 void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) { 199 assert(isSafeToReferenceAfterResize(Elt, NewSize) && 200 "Attempting to reference an element of the vector in an operation " 201 "that invalidates it"); 202 } 203 204 /// Check whether Elt will be invalidated by increasing the size of the 205 /// vector by N. 206 void assertSafeToAdd(const void *Elt, size_t N = 1) { 207 this->assertSafeToReferenceAfterResize(Elt, this->size() + N); 208 } 209 210 /// Check whether any part of the range will be invalidated by clearing. 211 void assertSafeToReferenceAfterClear(const T *From, const T *To) { 212 if (From == To) 213 return; 214 this->assertSafeToReferenceAfterResize(From, 0); 215 this->assertSafeToReferenceAfterResize(To - 1, 0); 216 } 217 template < 218 class ItTy, 219 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value, 220 bool> = false> 221 void assertSafeToReferenceAfterClear(ItTy, ItTy) {} 222 223 /// Check whether any part of the range will be invalidated by growing. 224 void assertSafeToAddRange(const T *From, const T *To) { 225 if (From == To) 226 return; 227 this->assertSafeToAdd(From, To - From); 228 this->assertSafeToAdd(To - 1, To - From); 229 } 230 template < 231 class ItTy, 232 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value, 233 bool> = false> 234 void assertSafeToAddRange(ItTy, ItTy) {} 235 236 /// Reserve enough space to add one element, and return the updated element 237 /// pointer in case it was a reference to the storage. 238 template <class U> 239 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt, 240 size_t N) { 241 size_t NewSize = This->size() + N; 242 if (/*LLVM_LIKELY*/(NewSize <= This->capacity())) [[likely]] 243 return &Elt; 244 245 bool ReferencesStorage = false; 246 int64_t Index = -1; 247 if (!U::TakesParamByValue) { 248 if (/*LLVM_UNLIKELY*/(This->isReferenceToStorage(&Elt))) [[unlikely]] { 249 ReferencesStorage = true; 250 Index = &Elt - This->begin(); 251 } 252 } 253 This->grow(NewSize); 254 return ReferencesStorage ? This->begin() + Index : &Elt; 255 } 256 257 public: 258 using size_type = size_t; 259 using difference_type = ptrdiff_t; 260 using value_type = T; 261 using iterator = T *; 262 using const_iterator = const T *; 263 264 using const_reverse_iterator = std::reverse_iterator<const_iterator>; 265 using reverse_iterator = std::reverse_iterator<iterator>; 266 267 using reference = T &; 268 using const_reference = const T &; 269 using pointer = T *; 270 using const_pointer = const T *; 271 272 using Base::capacity; 273 using Base::empty; 274 using Base::size; 275 276 // forward iterator creation methods. 277 iterator begin() { return (iterator)this->BeginX; } 278 const_iterator begin() const { return (const_iterator)this->BeginX; } 279 iterator end() { return begin() + size(); } 280 const_iterator end() const { return begin() + size(); } 281 282 // reverse iterator creation methods. 283 reverse_iterator rbegin() { return reverse_iterator(end()); } 284 const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } 285 reverse_iterator rend() { return reverse_iterator(begin()); } 286 const_reverse_iterator rend() const { return const_reverse_iterator(begin());} 287 288 size_type size_in_bytes() const { return size() * sizeof(T); } 289 size_type max_size() const { 290 return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T)); 291 } 292 293 size_t capacity_in_bytes() const { return capacity() * sizeof(T); } 294 295 /// Return a pointer to the vector's buffer, even if empty(). 296 pointer data() { return pointer(begin()); } 297 /// Return a pointer to the vector's buffer, even if empty(). 298 const_pointer data() const { return const_pointer(begin()); } 299 300 reference operator[](size_type idx) { 301 assert(idx < size()); 302 return begin()[idx]; 303 } 304 const_reference operator[](size_type idx) const { 305 assert(idx < size()); 306 return begin()[idx]; 307 } 308 309 reference front() { 310 assert(!empty()); 311 return begin()[0]; 312 } 313 const_reference front() const { 314 assert(!empty()); 315 return begin()[0]; 316 } 317 318 reference back() { 319 assert(!empty()); 320 return end()[-1]; 321 } 322 const_reference back() const { 323 assert(!empty()); 324 return end()[-1]; 325 } 326 }; 327 328 /// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put 329 /// method implementations that are designed to work with non-trivial T's. 330 /// 331 /// We approximate is_trivially_copyable with trivial move/copy construction and 332 /// trivial destruction. While the standard doesn't specify that you're allowed 333 /// copy these types with memcpy, there is no way for the type to observe this. 334 /// This catches the important case of std::pair<POD, POD>, which is not 335 /// trivially assignable. 336 template <typename T, bool = (std::is_trivially_copy_constructible<T>::value) && 337 (std::is_trivially_move_constructible<T>::value) && 338 std::is_trivially_destructible<T>::value> 339 class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> { 340 friend class SmallVectorTemplateCommon<T>; 341 342 protected: 343 static constexpr bool TakesParamByValue = false; 344 using ValueParamT = const T &; 345 346 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} 347 348 static void destroy_range(T *S, T *E) { 349 while (S != E) { 350 --E; 351 E->~T(); 352 } 353 } 354 355 /// Move the range [I, E) into the uninitialized memory starting with "Dest", 356 /// constructing elements as needed. 357 template<typename It1, typename It2> 358 static void uninitialized_move(It1 I, It1 E, It2 Dest) { 359 std::uninitialized_move(I, E, Dest); 360 } 361 362 /// Copy the range [I, E) onto the uninitialized memory starting with "Dest", 363 /// constructing elements as needed. 364 template<typename It1, typename It2> 365 static void uninitialized_copy(It1 I, It1 E, It2 Dest) { 366 std::uninitialized_copy(I, E, Dest); 367 } 368 369 /// Grow the allocated memory (without initializing new elements), doubling 370 /// the size of the allocated memory. Guarantees space for at least one more 371 /// element, or MinSize more elements if specified. 372 void grow(size_t MinSize = 0); 373 374 /// Create a new allocation big enough for \p MinSize and pass back its size 375 /// in \p NewCapacity. This is the first section of \a grow(). 376 T *mallocForGrow(size_t MinSize, size_t &NewCapacity); 377 378 /// Move existing elements over to the new allocation \p NewElts, the middle 379 /// section of \a grow(). 380 void moveElementsForGrow(T *NewElts); 381 382 /// Transfer ownership of the allocation, finishing up \a grow(). 383 void takeAllocationForGrow(T *NewElts, size_t NewCapacity); 384 385 /// Reserve enough space to add one element, and return the updated element 386 /// pointer in case it was a reference to the storage. 387 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) { 388 return this->reserveForParamAndGetAddressImpl(this, Elt, N); 389 } 390 391 /// Reserve enough space to add one element, and return the updated element 392 /// pointer in case it was a reference to the storage. 393 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) { 394 return const_cast<T *>( 395 this->reserveForParamAndGetAddressImpl(this, Elt, N)); 396 } 397 398 static T &&forward_value_param(T &&V) { return std::move(V); } 399 static const T &forward_value_param(const T &V) { return V; } 400 401 void growAndAssign(size_t NumElts, const T &Elt) { 402 // Grow manually in case Elt is an internal reference. 403 size_t NewCapacity; 404 T *NewElts = mallocForGrow(NumElts, NewCapacity); 405 std::uninitialized_fill_n(NewElts, NumElts, Elt); 406 this->destroy_range(this->begin(), this->end()); 407 takeAllocationForGrow(NewElts, NewCapacity); 408 this->set_size(NumElts); 409 } 410 411 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) { 412 // Grow manually in case one of Args is an internal reference. 413 size_t NewCapacity; 414 T *NewElts = mallocForGrow(0, NewCapacity); 415 ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...); 416 moveElementsForGrow(NewElts); 417 takeAllocationForGrow(NewElts, NewCapacity); 418 this->set_size(this->size() + 1); 419 return this->back(); 420 } 421 422 public: 423 void push_back(const T &Elt) { 424 const T *EltPtr = reserveForParamAndGetAddress(Elt); 425 ::new ((void *)this->end()) T(*EltPtr); 426 this->set_size(this->size() + 1); 427 } 428 429 void push_back(T &&Elt) { 430 T *EltPtr = reserveForParamAndGetAddress(Elt); 431 ::new ((void *)this->end()) T(::std::move(*EltPtr)); 432 this->set_size(this->size() + 1); 433 } 434 435 void pop_back() { 436 this->set_size(this->size() - 1); 437 this->end()->~T(); 438 } 439 }; 440 441 // Define this out-of-line to dissuade the C++ compiler from inlining it. 442 template <typename T, bool TriviallyCopyable> 443 void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) { 444 size_t NewCapacity; 445 T *NewElts = mallocForGrow(MinSize, NewCapacity); 446 moveElementsForGrow(NewElts); 447 takeAllocationForGrow(NewElts, NewCapacity); 448 } 449 450 template <typename T, bool TriviallyCopyable> 451 T *SmallVectorTemplateBase<T, TriviallyCopyable>::mallocForGrow( 452 size_t MinSize, size_t &NewCapacity) { 453 return static_cast<T *>( 454 SmallVectorBase<SmallVectorSizeType<T>>::mallocForGrow( 455 this->getFirstEl(), MinSize, sizeof(T), NewCapacity)); 456 } 457 458 // Define this out-of-line to dissuade the C++ compiler from inlining it. 459 template <typename T, bool TriviallyCopyable> 460 void SmallVectorTemplateBase<T, TriviallyCopyable>::moveElementsForGrow( 461 T *NewElts) { 462 // Move the elements over. 463 this->uninitialized_move(this->begin(), this->end(), NewElts); 464 465 // Destroy the original elements. 466 destroy_range(this->begin(), this->end()); 467 } 468 469 // Define this out-of-line to dissuade the C++ compiler from inlining it. 470 template <typename T, bool TriviallyCopyable> 471 void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow( 472 T *NewElts, size_t NewCapacity) { 473 // If this wasn't grown from the inline copy, deallocate the old space. 474 if (!this->isSmall()) 475 free(this->begin()); 476 477 this->BeginX = NewElts; 478 this->Capacity = NewCapacity; 479 } 480 481 /// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put 482 /// method implementations that are designed to work with trivially copyable 483 /// T's. This allows using memcpy in place of copy/move construction and 484 /// skipping destruction. 485 template <typename T> 486 class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> { 487 friend class SmallVectorTemplateCommon<T>; 488 489 protected: 490 /// True if it's cheap enough to take parameters by value. Doing so avoids 491 /// overhead related to mitigations for reference invalidation. 492 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *); 493 494 /// Either const T& or T, depending on whether it's cheap enough to take 495 /// parameters by value. 496 using ValueParamT = std::conditional_t<TakesParamByValue, T, const T &>; 497 498 SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} 499 500 // No need to do a destroy loop for POD's. 501 static void destroy_range(T *, T *) {} 502 503 /// Move the range [I, E) onto the uninitialized memory 504 /// starting with "Dest", constructing elements into it as needed. 505 template<typename It1, typename It2> 506 static void uninitialized_move(It1 I, It1 E, It2 Dest) { 507 // Just do a copy. 508 uninitialized_copy(I, E, Dest); 509 } 510 511 /// Copy the range [I, E) onto the uninitialized memory 512 /// starting with "Dest", constructing elements into it as needed. 513 template<typename It1, typename It2> 514 static void uninitialized_copy(It1 I, It1 E, It2 Dest) { 515 // Arbitrary iterator types; just use the basic implementation. 516 std::uninitialized_copy(I, E, Dest); 517 } 518 519 /// Copy the range [I, E) onto the uninitialized memory 520 /// starting with "Dest", constructing elements into it as needed. 521 template <typename T1, typename T2> 522 static void uninitialized_copy( 523 T1 *I, T1 *E, T2 *Dest, 524 std::enable_if_t<std::is_same<std::remove_const_t<T1>, T2>::value> * = 525 nullptr) { 526 // Use memcpy for PODs iterated by pointers (which includes SmallVector 527 // iterators): std::uninitialized_copy optimizes to memmove, but we can 528 // use memcpy here. Note that I and E are iterators and thus might be 529 // invalid for memcpy if they are equal. 530 if (I != E) 531 memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T)); 532 } 533 534 /// Double the size of the allocated memory, guaranteeing space for at 535 /// least one more element or MinSize if specified. 536 void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); } 537 538 /// Reserve enough space to add one element, and return the updated element 539 /// pointer in case it was a reference to the storage. 540 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) { 541 return this->reserveForParamAndGetAddressImpl(this, Elt, N); 542 } 543 544 /// Reserve enough space to add one element, and return the updated element 545 /// pointer in case it was a reference to the storage. 546 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) { 547 return const_cast<T *>( 548 this->reserveForParamAndGetAddressImpl(this, Elt, N)); 549 } 550 551 /// Copy \p V or return a reference, depending on \a ValueParamT. 552 static ValueParamT forward_value_param(ValueParamT V) { return V; } 553 554 void growAndAssign(size_t NumElts, T Elt) { 555 // Elt has been copied in case it's an internal reference, side-stepping 556 // reference invalidation problems without losing the realloc optimization. 557 this->set_size(0); 558 this->grow(NumElts); 559 std::uninitialized_fill_n(this->begin(), NumElts, Elt); 560 this->set_size(NumElts); 561 } 562 563 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) { 564 // Use push_back with a copy in case Args has an internal reference, 565 // side-stepping reference invalidation problems without losing the realloc 566 // optimization. 567 push_back(T(std::forward<ArgTypes>(Args)...)); 568 return this->back(); 569 } 570 571 public: 572 void push_back(ValueParamT Elt) { 573 const T *EltPtr = reserveForParamAndGetAddress(Elt); 574 memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T)); 575 this->set_size(this->size() + 1); 576 } 577 578 void pop_back() { this->set_size(this->size() - 1); } 579 }; 580 581 /// This class consists of common code factored out of the SmallVector class to 582 /// reduce code duplication based on the SmallVector 'N' template parameter. 583 template <typename T> 584 class SmallVectorImpl : public SmallVectorTemplateBase<T> { 585 using SuperClass = SmallVectorTemplateBase<T>; 586 587 public: 588 using iterator = typename SuperClass::iterator; 589 using const_iterator = typename SuperClass::const_iterator; 590 using reference = typename SuperClass::reference; 591 using size_type = typename SuperClass::size_type; 592 593 protected: 594 using SmallVectorTemplateBase<T>::TakesParamByValue; 595 using ValueParamT = typename SuperClass::ValueParamT; 596 597 // Default ctor - Initialize to empty. 598 explicit SmallVectorImpl(unsigned N) 599 : SmallVectorTemplateBase<T>(N) {} 600 601 void assignRemote(SmallVectorImpl &&RHS) { 602 this->destroy_range(this->begin(), this->end()); 603 if (!this->isSmall()) 604 free(this->begin()); 605 this->BeginX = RHS.BeginX; 606 this->Size = RHS.Size; 607 this->Capacity = RHS.Capacity; 608 RHS.resetToSmall(); 609 } 610 611 ~SmallVectorImpl() { 612 // Subclass has already destructed this vector's elements. 613 // If this wasn't grown from the inline copy, deallocate the old space. 614 if (!this->isSmall()) 615 free(this->begin()); 616 } 617 618 public: 619 SmallVectorImpl(const SmallVectorImpl &) = delete; 620 621 void clear() { 622 this->destroy_range(this->begin(), this->end()); 623 this->Size = 0; 624 } 625 626 private: 627 // Make set_size() private to avoid misuse in subclasses. 628 using SuperClass::set_size; 629 630 template <bool ForOverwrite> void resizeImpl(size_type N) { 631 if (N == this->size()) 632 return; 633 634 if (N < this->size()) { 635 this->truncate(N); 636 return; 637 } 638 639 this->reserve(N); 640 for (auto I = this->end(), E = this->begin() + N; I != E; ++I) 641 if (ForOverwrite) 642 new (&*I) T; 643 else 644 new (&*I) T(); 645 this->set_size(N); 646 } 647 648 public: 649 void resize(size_type N) { resizeImpl<false>(N); } 650 651 /// Like resize, but \ref T is POD, the new values won't be initialized. 652 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); } 653 654 /// Like resize, but requires that \p N is less than \a size(). 655 void truncate(size_type N) { 656 assert(this->size() >= N && "Cannot increase size with truncate"); 657 this->destroy_range(this->begin() + N, this->end()); 658 this->set_size(N); 659 } 660 661 void resize(size_type N, ValueParamT NV) { 662 if (N == this->size()) 663 return; 664 665 if (N < this->size()) { 666 this->truncate(N); 667 return; 668 } 669 670 // N > this->size(). Defer to append. 671 this->append(N - this->size(), NV); 672 } 673 674 void reserve(size_type N) { 675 if (this->capacity() < N) 676 this->grow(N); 677 } 678 679 void pop_back_n(size_type NumItems) { 680 assert(this->size() >= NumItems); 681 truncate(this->size() - NumItems); 682 } 683 684 [[nodiscard]] T pop_back_val() { 685 T Result = ::std::move(this->back()); 686 this->pop_back(); 687 return Result; 688 } 689 690 void swap(SmallVectorImpl &RHS); 691 692 /// Add the specified range to the end of the SmallVector. 693 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> 694 void append(ItTy in_start, ItTy in_end) { 695 this->assertSafeToAddRange(in_start, in_end); 696 size_type NumInputs = std::distance(in_start, in_end); 697 this->reserve(this->size() + NumInputs); 698 this->uninitialized_copy(in_start, in_end, this->end()); 699 this->set_size(this->size() + NumInputs); 700 } 701 702 /// Append \p NumInputs copies of \p Elt to the end. 703 void append(size_type NumInputs, ValueParamT Elt) { 704 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs); 705 std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr); 706 this->set_size(this->size() + NumInputs); 707 } 708 709 void append(std::initializer_list<T> IL) { 710 append(IL.begin(), IL.end()); 711 } 712 713 void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); } 714 715 void assign(size_type NumElts, ValueParamT Elt) { 716 // Note that Elt could be an internal reference. 717 if (NumElts > this->capacity()) { 718 this->growAndAssign(NumElts, Elt); 719 return; 720 } 721 722 // Assign over existing elements. 723 std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt); 724 if (NumElts > this->size()) 725 std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt); 726 else if (NumElts < this->size()) 727 this->destroy_range(this->begin() + NumElts, this->end()); 728 this->set_size(NumElts); 729 } 730 731 // FIXME: Consider assigning over existing elements, rather than clearing & 732 // re-initializing them - for all assign(...) variants. 733 734 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> 735 void assign(ItTy in_start, ItTy in_end) { 736 this->assertSafeToReferenceAfterClear(in_start, in_end); 737 clear(); 738 append(in_start, in_end); 739 } 740 741 void assign(std::initializer_list<T> IL) { 742 clear(); 743 append(IL); 744 } 745 746 void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); } 747 748 iterator erase(const_iterator CI) { 749 // Just cast away constness because this is a non-const member function. 750 iterator I = const_cast<iterator>(CI); 751 752 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds."); 753 754 iterator N = I; 755 // Shift all elts down one. 756 std::move(I+1, this->end(), I); 757 // Drop the last elt. 758 this->pop_back(); 759 return(N); 760 } 761 762 iterator erase(const_iterator CS, const_iterator CE) { 763 // Just cast away constness because this is a non-const member function. 764 iterator S = const_cast<iterator>(CS); 765 iterator E = const_cast<iterator>(CE); 766 767 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds."); 768 769 iterator N = S; 770 // Shift all elts down. 771 iterator I = std::move(E, this->end(), S); 772 // Drop the last elts. 773 this->destroy_range(I, this->end()); 774 this->set_size(I - this->begin()); 775 return(N); 776 } 777 778 private: 779 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) { 780 // Callers ensure that ArgType is derived from T. 781 static_assert( 782 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>, 783 T>::value, 784 "ArgType must be derived from T!"); 785 786 if (I == this->end()) { // Important special case for empty vector. 787 this->push_back(::std::forward<ArgType>(Elt)); 788 return this->end()-1; 789 } 790 791 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds."); 792 793 // Grow if necessary. 794 size_t Index = I - this->begin(); 795 std::remove_reference_t<ArgType> *EltPtr = 796 this->reserveForParamAndGetAddress(Elt); 797 I = this->begin() + Index; 798 799 ::new ((void*) this->end()) T(::std::move(this->back())); 800 // Push everything else over. 801 std::move_backward(I, this->end()-1, this->end()); 802 this->set_size(this->size() + 1); 803 804 // If we just moved the element we're inserting, be sure to update 805 // the reference (never happens if TakesParamByValue). 806 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value, 807 "ArgType must be 'T' when taking by value!"); 808 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end())) 809 ++EltPtr; 810 811 *I = ::std::forward<ArgType>(*EltPtr); 812 return I; 813 } 814 815 public: 816 iterator insert(iterator I, T &&Elt) { 817 return insert_one_impl(I, this->forward_value_param(std::move(Elt))); 818 } 819 820 iterator insert(iterator I, const T &Elt) { 821 return insert_one_impl(I, this->forward_value_param(Elt)); 822 } 823 824 iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt) { 825 // Convert iterator to elt# to avoid invalidating iterator when we reserve() 826 size_t InsertElt = I - this->begin(); 827 828 if (I == this->end()) { // Important special case for empty vector. 829 append(NumToInsert, Elt); 830 return this->begin()+InsertElt; 831 } 832 833 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds."); 834 835 // Ensure there is enough space, and get the (maybe updated) address of 836 // Elt. 837 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert); 838 839 // Uninvalidate the iterator. 840 I = this->begin()+InsertElt; 841 842 // If there are more elements between the insertion point and the end of the 843 // range than there are being inserted, we can use a simple approach to 844 // insertion. Since we already reserved space, we know that this won't 845 // reallocate the vector. 846 if (size_t(this->end()-I) >= NumToInsert) { 847 T *OldEnd = this->end(); 848 append(std::move_iterator<iterator>(this->end() - NumToInsert), 849 std::move_iterator<iterator>(this->end())); 850 851 // Copy the existing elements that get replaced. 852 std::move_backward(I, OldEnd-NumToInsert, OldEnd); 853 854 // If we just moved the element we're inserting, be sure to update 855 // the reference (never happens if TakesParamByValue). 856 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end()) 857 EltPtr += NumToInsert; 858 859 std::fill_n(I, NumToInsert, *EltPtr); 860 return I; 861 } 862 863 // Otherwise, we're inserting more elements than exist already, and we're 864 // not inserting at the end. 865 866 // Move over the elements that we're about to overwrite. 867 T *OldEnd = this->end(); 868 this->set_size(this->size() + NumToInsert); 869 size_t NumOverwritten = OldEnd-I; 870 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten); 871 872 // If we just moved the element we're inserting, be sure to update 873 // the reference (never happens if TakesParamByValue). 874 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end()) 875 EltPtr += NumToInsert; 876 877 // Replace the overwritten part. 878 std::fill_n(I, NumOverwritten, *EltPtr); 879 880 // Insert the non-overwritten middle part. 881 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr); 882 return I; 883 } 884 885 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> 886 iterator insert(iterator I, ItTy From, ItTy To) { 887 // Convert iterator to elt# to avoid invalidating iterator when we reserve() 888 size_t InsertElt = I - this->begin(); 889 890 if (I == this->end()) { // Important special case for empty vector. 891 append(From, To); 892 return this->begin()+InsertElt; 893 } 894 895 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds."); 896 897 // Check that the reserve that follows doesn't invalidate the iterators. 898 this->assertSafeToAddRange(From, To); 899 900 size_t NumToInsert = std::distance(From, To); 901 902 // Ensure there is enough space. 903 reserve(this->size() + NumToInsert); 904 905 // Uninvalidate the iterator. 906 I = this->begin()+InsertElt; 907 908 // If there are more elements between the insertion point and the end of the 909 // range than there are being inserted, we can use a simple approach to 910 // insertion. Since we already reserved space, we know that this won't 911 // reallocate the vector. 912 if (size_t(this->end()-I) >= NumToInsert) { 913 T *OldEnd = this->end(); 914 append(std::move_iterator<iterator>(this->end() - NumToInsert), 915 std::move_iterator<iterator>(this->end())); 916 917 // Copy the existing elements that get replaced. 918 std::move_backward(I, OldEnd-NumToInsert, OldEnd); 919 920 std::copy(From, To, I); 921 return I; 922 } 923 924 // Otherwise, we're inserting more elements than exist already, and we're 925 // not inserting at the end. 926 927 // Move over the elements that we're about to overwrite. 928 T *OldEnd = this->end(); 929 this->set_size(this->size() + NumToInsert); 930 size_t NumOverwritten = OldEnd-I; 931 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten); 932 933 // Replace the overwritten part. 934 for (T *J = I; NumOverwritten > 0; --NumOverwritten) { 935 *J = *From; 936 ++J; ++From; 937 } 938 939 // Insert the non-overwritten middle part. 940 this->uninitialized_copy(From, To, OldEnd); 941 return I; 942 } 943 944 void insert(iterator I, std::initializer_list<T> IL) { 945 insert(I, IL.begin(), IL.end()); 946 } 947 948 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) { 949 if (LLVM_UNLIKELY(this->size() >= this->capacity())) 950 return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...); 951 952 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...); 953 this->set_size(this->size() + 1); 954 return this->back(); 955 } 956 957 SmallVectorImpl &operator=(const SmallVectorImpl &RHS); 958 959 SmallVectorImpl &operator=(SmallVectorImpl &&RHS); 960 961 bool operator==(const SmallVectorImpl &RHS) const { 962 if (this->size() != RHS.size()) return false; 963 return std::equal(this->begin(), this->end(), RHS.begin()); 964 } 965 bool operator!=(const SmallVectorImpl &RHS) const { 966 return !(*this == RHS); 967 } 968 969 bool operator<(const SmallVectorImpl &RHS) const { 970 return std::lexicographical_compare(this->begin(), this->end(), 971 RHS.begin(), RHS.end()); 972 } 973 bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; } 974 bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); } 975 bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); } 976 }; 977 978 template <typename T> 979 void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) { 980 if (this == &RHS) return; 981 982 // We can only avoid copying elements if neither vector is small. 983 if (!this->isSmall() && !RHS.isSmall()) { 984 std::swap(this->BeginX, RHS.BeginX); 985 std::swap(this->Size, RHS.Size); 986 std::swap(this->Capacity, RHS.Capacity); 987 return; 988 } 989 this->reserve(RHS.size()); 990 RHS.reserve(this->size()); 991 992 // Swap the shared elements. 993 size_t NumShared = this->size(); 994 if (NumShared > RHS.size()) NumShared = RHS.size(); 995 for (size_type i = 0; i != NumShared; ++i) 996 std::swap((*this)[i], RHS[i]); 997 998 // Copy over the extra elts. 999 if (this->size() > RHS.size()) { 1000 size_t EltDiff = this->size() - RHS.size(); 1001 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end()); 1002 RHS.set_size(RHS.size() + EltDiff); 1003 this->destroy_range(this->begin()+NumShared, this->end()); 1004 this->set_size(NumShared); 1005 } else if (RHS.size() > this->size()) { 1006 size_t EltDiff = RHS.size() - this->size(); 1007 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end()); 1008 this->set_size(this->size() + EltDiff); 1009 this->destroy_range(RHS.begin()+NumShared, RHS.end()); 1010 RHS.set_size(NumShared); 1011 } 1012 } 1013 1014 template <typename T> 1015 SmallVectorImpl<T> &SmallVectorImpl<T>:: 1016 operator=(const SmallVectorImpl<T> &RHS) { 1017 // Avoid self-assignment. 1018 if (this == &RHS) return *this; 1019 1020 // If we already have sufficient space, assign the common elements, then 1021 // destroy any excess. 1022 size_t RHSSize = RHS.size(); 1023 size_t CurSize = this->size(); 1024 if (CurSize >= RHSSize) { 1025 // Assign common elements. 1026 iterator NewEnd; 1027 if (RHSSize) 1028 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin()); 1029 else 1030 NewEnd = this->begin(); 1031 1032 // Destroy excess elements. 1033 this->destroy_range(NewEnd, this->end()); 1034 1035 // Trim. 1036 this->set_size(RHSSize); 1037 return *this; 1038 } 1039 1040 // If we have to grow to have enough elements, destroy the current elements. 1041 // This allows us to avoid copying them during the grow. 1042 // FIXME: don't do this if they're efficiently moveable. 1043 if (this->capacity() < RHSSize) { 1044 // Destroy current elements. 1045 this->clear(); 1046 CurSize = 0; 1047 this->grow(RHSSize); 1048 } else if (CurSize) { 1049 // Otherwise, use assignment for the already-constructed elements. 1050 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin()); 1051 } 1052 1053 // Copy construct the new elements in place. 1054 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(), 1055 this->begin()+CurSize); 1056 1057 // Set end. 1058 this->set_size(RHSSize); 1059 return *this; 1060 } 1061 1062 template <typename T> 1063 SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) { 1064 // Avoid self-assignment. 1065 if (this == &RHS) return *this; 1066 1067 // If the RHS isn't small, clear this vector and then steal its buffer. 1068 if (!RHS.isSmall()) { 1069 this->assignRemote(std::move(RHS)); 1070 return *this; 1071 } 1072 1073 // If we already have sufficient space, assign the common elements, then 1074 // destroy any excess. 1075 size_t RHSSize = RHS.size(); 1076 size_t CurSize = this->size(); 1077 if (CurSize >= RHSSize) { 1078 // Assign common elements. 1079 iterator NewEnd = this->begin(); 1080 if (RHSSize) 1081 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd); 1082 1083 // Destroy excess elements and trim the bounds. 1084 this->destroy_range(NewEnd, this->end()); 1085 this->set_size(RHSSize); 1086 1087 // Clear the RHS. 1088 RHS.clear(); 1089 1090 return *this; 1091 } 1092 1093 // If we have to grow to have enough elements, destroy the current elements. 1094 // This allows us to avoid copying them during the grow. 1095 // FIXME: this may not actually make any sense if we can efficiently move 1096 // elements. 1097 if (this->capacity() < RHSSize) { 1098 // Destroy current elements. 1099 this->clear(); 1100 CurSize = 0; 1101 this->grow(RHSSize); 1102 } else if (CurSize) { 1103 // Otherwise, use assignment for the already-constructed elements. 1104 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin()); 1105 } 1106 1107 // Move-construct the new elements in place. 1108 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(), 1109 this->begin()+CurSize); 1110 1111 // Set end. 1112 this->set_size(RHSSize); 1113 1114 RHS.clear(); 1115 return *this; 1116 } 1117 1118 /// Storage for the SmallVector elements. This is specialized for the N=0 case 1119 /// to avoid allocating unnecessary storage. 1120 template <typename T, unsigned N> 1121 struct SmallVectorStorage { 1122 alignas(T) char InlineElts[N * sizeof(T)]; 1123 }; 1124 1125 /// We need the storage to be properly aligned even for small-size of 0 so that 1126 /// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is 1127 /// well-defined. 1128 template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {}; 1129 1130 /// Forward declaration of SmallVector so that 1131 /// calculateSmallVectorDefaultInlinedElements can reference 1132 /// `sizeof(SmallVector<T, 0>)`. 1133 template <typename T, unsigned N> class /*LLVM_GSL_OWNER*/ SmallVector; 1134 1135 /// Helper class for calculating the default number of inline elements for 1136 /// `SmallVector<T>`. 1137 /// 1138 /// This should be migrated to a constexpr function when our minimum 1139 /// compiler support is enough for multi-statement constexpr functions. 1140 template <typename T> struct CalculateSmallVectorDefaultInlinedElements { 1141 // Parameter controlling the default number of inlined elements 1142 // for `SmallVector<T>`. 1143 // 1144 // The default number of inlined elements ensures that 1145 // 1. There is at least one inlined element. 1146 // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless 1147 // it contradicts 1. 1148 static constexpr size_t kPreferredSmallVectorSizeof = 64; 1149 1150 // static_assert that sizeof(T) is not "too big". 1151 // 1152 // Because our policy guarantees at least one inlined element, it is possible 1153 // for an arbitrarily large inlined element to allocate an arbitrarily large 1154 // amount of inline storage. We generally consider it an antipattern for a 1155 // SmallVector to allocate an excessive amount of inline storage, so we want 1156 // to call attention to these cases and make sure that users are making an 1157 // intentional decision if they request a lot of inline storage. 1158 // 1159 // We want this assertion to trigger in pathological cases, but otherwise 1160 // not be too easy to hit. To accomplish that, the cutoff is actually somewhat 1161 // larger than kPreferredSmallVectorSizeof (otherwise, 1162 // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that 1163 // pattern seems useful in practice). 1164 // 1165 // One wrinkle is that this assertion is in theory non-portable, since 1166 // sizeof(T) is in general platform-dependent. However, we don't expect this 1167 // to be much of an issue, because most LLVM development happens on 64-bit 1168 // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for 1169 // 32-bit hosts, dodging the issue. The reverse situation, where development 1170 // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a 1171 // 64-bit host, is expected to be very rare. 1172 static_assert( 1173 sizeof(T) <= 256, 1174 "You are trying to use a default number of inlined elements for " 1175 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an " 1176 "explicit number of inlined elements with `SmallVector<T, N>` to make " 1177 "sure you really want that much inline storage."); 1178 1179 // Discount the size of the header itself when calculating the maximum inline 1180 // bytes. 1181 static constexpr size_t PreferredInlineBytes = 1182 kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>); 1183 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T); 1184 static constexpr size_t value = 1185 NumElementsThatFit == 0 ? 1 : NumElementsThatFit; 1186 }; 1187 1188 /// This is a 'vector' (really, a variable-sized array), optimized 1189 /// for the case when the array is small. It contains some number of elements 1190 /// in-place, which allows it to avoid heap allocation when the actual number of 1191 /// elements is below that threshold. This allows normal "small" cases to be 1192 /// fast without losing generality for large inputs. 1193 /// 1194 /// \note 1195 /// In the absence of a well-motivated choice for the number of inlined 1196 /// elements \p N, it is recommended to use \c SmallVector<T> (that is, 1197 /// omitting the \p N). This will choose a default number of inlined elements 1198 /// reasonable for allocation on the stack (for example, trying to keep \c 1199 /// sizeof(SmallVector<T>) around 64 bytes). 1200 /// 1201 /// \warning This does not attempt to be exception safe. 1202 /// 1203 /// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h 1204 template <typename T, 1205 unsigned N = CalculateSmallVectorDefaultInlinedElements<T>::value> 1206 class /*LLVM_GSL_OWNER*/ SmallVector : public SmallVectorImpl<T>, 1207 SmallVectorStorage<T, N> { 1208 public: 1209 SmallVector() : SmallVectorImpl<T>(N) {} 1210 1211 ~SmallVector() { 1212 // Destroy the constructed elements in the vector. 1213 this->destroy_range(this->begin(), this->end()); 1214 } 1215 1216 explicit SmallVector(size_t Size) 1217 : SmallVectorImpl<T>(N) { 1218 this->resize(Size); 1219 } 1220 1221 SmallVector(size_t Size, const T &Value) 1222 : SmallVectorImpl<T>(N) { 1223 this->assign(Size, Value); 1224 } 1225 1226 template <typename ItTy, typename = EnableIfConvertibleToInputIterator<ItTy>> 1227 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) { 1228 this->append(S, E); 1229 } 1230 1231 template <typename RangeTy> 1232 explicit SmallVector(const iterator_range<RangeTy> &R) 1233 : SmallVectorImpl<T>(N) { 1234 this->append(R.begin(), R.end()); 1235 } 1236 1237 SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) { 1238 this->append(IL); 1239 } 1240 1241 template <typename U, 1242 typename = std::enable_if_t<std::is_convertible<U, T>::value>> 1243 explicit SmallVector(ArrayRef<U> A) : SmallVectorImpl<T>(N) { 1244 this->append(A.begin(), A.end()); 1245 } 1246 1247 SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) { 1248 if (!RHS.empty()) 1249 SmallVectorImpl<T>::operator=(RHS); 1250 } 1251 1252 SmallVector &operator=(const SmallVector &RHS) { 1253 SmallVectorImpl<T>::operator=(RHS); 1254 return *this; 1255 } 1256 1257 SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) { 1258 if (!RHS.empty()) 1259 SmallVectorImpl<T>::operator=(::std::move(RHS)); 1260 } 1261 1262 SmallVector(SmallVectorImpl<T> &&RHS) : SmallVectorImpl<T>(N) { 1263 if (!RHS.empty()) 1264 SmallVectorImpl<T>::operator=(::std::move(RHS)); 1265 } 1266 1267 SmallVector &operator=(SmallVector &&RHS) { 1268 if (N) { 1269 SmallVectorImpl<T>::operator=(::std::move(RHS)); 1270 return *this; 1271 } 1272 // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the 1273 // case. 1274 if (this == &RHS) 1275 return *this; 1276 if (RHS.empty()) { 1277 this->destroy_range(this->begin(), this->end()); 1278 this->Size = 0; 1279 } else { 1280 this->assignRemote(std::move(RHS)); 1281 } 1282 return *this; 1283 } 1284 1285 SmallVector &operator=(SmallVectorImpl<T> &&RHS) { 1286 SmallVectorImpl<T>::operator=(::std::move(RHS)); 1287 return *this; 1288 } 1289 1290 SmallVector &operator=(std::initializer_list<T> IL) { 1291 this->assign(IL); 1292 return *this; 1293 } 1294 }; 1295 1296 template <typename T, unsigned N> 1297 inline size_t capacity_in_bytes(const SmallVector<T, N> &X) { 1298 return X.capacity_in_bytes(); 1299 } 1300 1301 template <typename RangeType> 1302 using ValueTypeFromRangeType = 1303 std::remove_const_t<std::remove_reference_t<decltype(*std::begin( 1304 std::declval<RangeType &>()))>>; 1305 1306 /// Given a range of type R, iterate the entire range and return a 1307 /// SmallVector with elements of the vector. This is useful, for example, 1308 /// when you want to iterate a range and then sort the results. 1309 template <unsigned Size, typename R> 1310 SmallVector<ValueTypeFromRangeType<R>, Size> to_vector(R &&Range) { 1311 return {std::begin(Range), std::end(Range)}; 1312 } 1313 template <typename R> 1314 SmallVector<ValueTypeFromRangeType<R>> to_vector(R &&Range) { 1315 return {std::begin(Range), std::end(Range)}; 1316 } 1317 1318 template <typename Out, unsigned Size, typename R> 1319 SmallVector<Out, Size> to_vector_of(R &&Range) { 1320 return {std::begin(Range), std::end(Range)}; 1321 } 1322 1323 template <typename Out, typename R> SmallVector<Out> to_vector_of(R &&Range) { 1324 return {std::begin(Range), std::end(Range)}; 1325 } 1326 1327 // Explicit instantiations 1328 extern template class llvm::SmallVectorBase<uint32_t>; 1329 #if SIZE_MAX > UINT32_MAX 1330 extern template class llvm::SmallVectorBase<uint64_t>; 1331 #endif 1332 1333 } // end namespace llvm 1334 1335 namespace std { 1336 1337 /// Implement std::swap in terms of SmallVector swap. 1338 template<typename T> 1339 inline void 1340 swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) { 1341 LHS.swap(RHS); 1342 } 1343 1344 /// Implement std::swap in terms of SmallVector swap. 1345 template<typename T, unsigned N> 1346 inline void 1347 swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) { 1348 LHS.swap(RHS); 1349 } 1350 1351 } // end namespace std 1352 1353 #ifdef _MSC_VER 1354 #pragma warning(pop) 1355 #endif 1356 1357 #endif // LLVM_ADT_SMALLVECTOR_H