1f22ef01cSRoman Divacky //===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements the SmallVector class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "llvm/ADT/SmallVector.h"
15f22ef01cSRoman Divacky using namespace llvm;
16f22ef01cSRoman Divacky 
17*4ba319b5SDimitry Andric // Check that no bytes are wasted and everything is well-aligned.
18*4ba319b5SDimitry Andric namespace {
19*4ba319b5SDimitry Andric struct Struct16B {
20*4ba319b5SDimitry Andric   alignas(16) void *X;
21*4ba319b5SDimitry Andric };
22*4ba319b5SDimitry Andric struct Struct32B {
23*4ba319b5SDimitry Andric   alignas(32) void *X;
24*4ba319b5SDimitry Andric };
25*4ba319b5SDimitry Andric }
26*4ba319b5SDimitry Andric static_assert(sizeof(SmallVector<void *, 0>) ==
27*4ba319b5SDimitry Andric                   sizeof(unsigned) * 2 + sizeof(void *),
28*4ba319b5SDimitry Andric               "wasted space in SmallVector size 0");
29*4ba319b5SDimitry Andric static_assert(alignof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
30*4ba319b5SDimitry Andric               "wrong alignment for 16-byte aligned T");
31*4ba319b5SDimitry Andric static_assert(alignof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
32*4ba319b5SDimitry Andric               "wrong alignment for 32-byte aligned T");
33*4ba319b5SDimitry Andric static_assert(sizeof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
34*4ba319b5SDimitry Andric               "missing padding for 16-byte aligned T");
35*4ba319b5SDimitry Andric static_assert(sizeof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
36*4ba319b5SDimitry Andric               "missing padding for 32-byte aligned T");
37*4ba319b5SDimitry Andric static_assert(sizeof(SmallVector<void *, 1>) ==
38*4ba319b5SDimitry Andric                   sizeof(unsigned) * 2 + sizeof(void *) * 2,
39*4ba319b5SDimitry Andric               "wasted space in SmallVector size 1");
40*4ba319b5SDimitry Andric 
41f22ef01cSRoman Divacky /// grow_pod - This is an implementation of the grow() method which only works
42f22ef01cSRoman Divacky /// on POD-like datatypes and is out of line to reduce code duplication.
grow_pod(void * FirstEl,size_t MinCapacity,size_t TSize)43*4ba319b5SDimitry Andric void SmallVectorBase::grow_pod(void *FirstEl, size_t MinCapacity,
443861d79fSDimitry Andric                                size_t TSize) {
45*4ba319b5SDimitry Andric   // Ensure we can fit the new capacity in 32 bits.
46*4ba319b5SDimitry Andric   if (MinCapacity > UINT32_MAX)
47*4ba319b5SDimitry Andric     report_bad_alloc_error("SmallVector capacity overflow during allocation");
48*4ba319b5SDimitry Andric 
49*4ba319b5SDimitry Andric   size_t NewCapacity = 2 * capacity() + 1; // Always grow.
50*4ba319b5SDimitry Andric   NewCapacity =
51*4ba319b5SDimitry Andric       std::min(std::max(NewCapacity, MinCapacity), size_t(UINT32_MAX));
52ffd1746dSEd Schouten 
53ffd1746dSEd Schouten   void *NewElts;
543861d79fSDimitry Andric   if (BeginX == FirstEl) {
55*4ba319b5SDimitry Andric     NewElts = safe_malloc(NewCapacity * TSize);
56f22ef01cSRoman Divacky 
57f22ef01cSRoman Divacky     // Copy the elements over.  No need to run dtors on PODs.
58*4ba319b5SDimitry Andric     memcpy(NewElts, this->BeginX, size() * TSize);
59ffd1746dSEd Schouten   } else {
60ffd1746dSEd Schouten     // If this wasn't grown from the inline copy, grow the allocated space.
61*4ba319b5SDimitry Andric     NewElts = safe_realloc(this->BeginX, NewCapacity * TSize);
62ffd1746dSEd Schouten   }
63f22ef01cSRoman Divacky 
64f22ef01cSRoman Divacky   this->BeginX = NewElts;
65*4ba319b5SDimitry Andric   this->Capacity = NewCapacity;
66f22ef01cSRoman Divacky }
67