LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/ADT - SmallVector.h (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 0.0 % 182 0
Test Date: 2026-07-03 19:57:34 Functions: 0.0 % 137 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 72 0

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

Generated by: LCOV version 2.0-1