Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

944 lines
29 KiB

  1. //===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the SmallVector class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_SMALLVECTOR_H
  14. #define LLVM_ADT_SMALLVECTOR_H
  15. #include "llvm/Support/AlignOf.h"
  16. #include "llvm/Support/Compiler.h"
  17. #include "llvm/Support/MathExtras.h"
  18. #include "llvm/Support/type_traits.h"
  19. #include <algorithm>
  20. #include <cassert>
  21. #include <cstddef>
  22. #include <cstdlib>
  23. #include <cstring>
  24. #include <iterator>
  25. #include <memory>
  26. namespace llvm {
  27. /// SmallVectorBase - This is all the non-templated stuff common to all
  28. /// SmallVectors.
  29. class SmallVectorBase {
  30. protected:
  31. void *BeginX, *EndX, *CapacityX;
  32. protected:
  33. SmallVectorBase(void *FirstEl, size_t Size)
  34. : BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {}
  35. /// grow_pod - This is an implementation of the grow() method which only works
  36. /// on POD-like data types and is out of line to reduce code duplication.
  37. void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize);
  38. public:
  39. /// size_in_bytes - This returns size()*sizeof(T).
  40. size_t size_in_bytes() const {
  41. return size_t((char*)EndX - (char*)BeginX);
  42. }
  43. /// capacity_in_bytes - This returns capacity()*sizeof(T).
  44. size_t capacity_in_bytes() const {
  45. return size_t((char*)CapacityX - (char*)BeginX);
  46. }
  47. bool empty() const { return BeginX == EndX; }
  48. };
  49. template <typename T, unsigned N> struct SmallVectorStorage;
  50. /// SmallVectorTemplateCommon - This is the part of SmallVectorTemplateBase
  51. /// which does not depend on whether the type T is a POD. The extra dummy
  52. /// template argument is used by ArrayRef to avoid unnecessarily requiring T
  53. /// to be complete.
  54. template <typename T, typename = void>
  55. class SmallVectorTemplateCommon : public SmallVectorBase {
  56. private:
  57. template <typename, unsigned> friend struct SmallVectorStorage;
  58. // Allocate raw space for N elements of type T. If T has a ctor or dtor, we
  59. // don't want it to be automatically run, so we need to represent the space as
  60. // something else. Use an array of char of sufficient alignment.
  61. typedef llvm::AlignedCharArrayUnion<T> U;
  62. U FirstEl;
  63. // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
  64. protected:
  65. SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {}
  66. void grow_pod(size_t MinSizeInBytes, size_t TSize) {
  67. SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize);
  68. }
  69. /// isSmall - Return true if this is a smallvector which has not had dynamic
  70. /// memory allocated for it.
  71. bool isSmall() const {
  72. return BeginX == static_cast<const void*>(&FirstEl);
  73. }
  74. /// resetToSmall - Put this vector in a state of being small.
  75. void resetToSmall() {
  76. BeginX = EndX = CapacityX = &FirstEl;
  77. }
  78. void setEnd(T *P) { this->EndX = P; }
  79. public:
  80. typedef size_t size_type;
  81. typedef ptrdiff_t difference_type;
  82. typedef T value_type;
  83. typedef T *iterator;
  84. typedef const T *const_iterator;
  85. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  86. typedef std::reverse_iterator<iterator> reverse_iterator;
  87. typedef T &reference;
  88. typedef const T &const_reference;
  89. typedef T *pointer;
  90. typedef const T *const_pointer;
  91. // forward iterator creation methods.
  92. iterator begin() { return (iterator)this->BeginX; }
  93. const_iterator begin() const { return (const_iterator)this->BeginX; }
  94. iterator end() { return (iterator)this->EndX; }
  95. const_iterator end() const { return (const_iterator)this->EndX; }
  96. protected:
  97. iterator capacity_ptr() { return (iterator)this->CapacityX; }
  98. const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
  99. public:
  100. // reverse iterator creation methods.
  101. reverse_iterator rbegin() { return reverse_iterator(end()); }
  102. const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
  103. reverse_iterator rend() { return reverse_iterator(begin()); }
  104. const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
  105. size_type size() const { return end()-begin(); }
  106. size_type max_size() const { return size_type(-1) / sizeof(T); }
  107. /// capacity - Return the total number of elements in the currently allocated
  108. /// buffer.
  109. size_t capacity() const { return capacity_ptr() - begin(); }
  110. /// data - Return a pointer to the vector's buffer, even if empty().
  111. pointer data() { return pointer(begin()); }
  112. /// data - Return a pointer to the vector's buffer, even if empty().
  113. const_pointer data() const { return const_pointer(begin()); }
  114. reference operator[](unsigned idx) {
  115. assert(begin() + idx < end());
  116. return begin()[idx];
  117. }
  118. const_reference operator[](unsigned idx) const {
  119. assert(begin() + idx < end());
  120. return begin()[idx];
  121. }
  122. reference front() {
  123. assert(!empty());
  124. return begin()[0];
  125. }
  126. const_reference front() const {
  127. assert(!empty());
  128. return begin()[0];
  129. }
  130. reference back() {
  131. assert(!empty());
  132. return end()[-1];
  133. }
  134. const_reference back() const {
  135. assert(!empty());
  136. return end()[-1];
  137. }
  138. };
  139. /// SmallVectorTemplateBase<isPodLike = false> - This is where we put method
  140. /// implementations that are designed to work with non-POD-like T's.
  141. template <typename T, bool isPodLike>
  142. class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
  143. protected:
  144. SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
  145. static void destroy_range(T *S, T *E) {
  146. while (S != E) {
  147. --E;
  148. E->~T();
  149. }
  150. }
  151. /// move - Use move-assignment to move the range [I, E) onto the
  152. /// objects starting with "Dest". This is just <memory>'s
  153. /// std::move, but not all stdlibs actually provide that.
  154. template<typename It1, typename It2>
  155. static It2 move(It1 I, It1 E, It2 Dest) {
  156. #if LLVM_HAS_RVALUE_REFERENCES
  157. for (; I != E; ++I, ++Dest)
  158. *Dest = ::std::move(*I);
  159. return Dest;
  160. #else
  161. return ::std::copy(I, E, Dest);
  162. #endif
  163. }
  164. /// move_backward - Use move-assignment to move the range
  165. /// [I, E) onto the objects ending at "Dest", moving objects
  166. /// in reverse order. This is just <algorithm>'s
  167. /// std::move_backward, but not all stdlibs actually provide that.
  168. template<typename It1, typename It2>
  169. static It2 move_backward(It1 I, It1 E, It2 Dest) {
  170. #if LLVM_HAS_RVALUE_REFERENCES
  171. while (I != E)
  172. *--Dest = ::std::move(*--E);
  173. return Dest;
  174. #else
  175. return ::std::copy_backward(I, E, Dest);
  176. #endif
  177. }
  178. /// uninitialized_move - Move the range [I, E) into the uninitialized
  179. /// memory starting with "Dest", constructing elements as needed.
  180. template<typename It1, typename It2>
  181. static void uninitialized_move(It1 I, It1 E, It2 Dest) {
  182. #if LLVM_HAS_RVALUE_REFERENCES
  183. for (; I != E; ++I, ++Dest)
  184. ::new ((void*) &*Dest) T(::std::move(*I));
  185. #else
  186. ::std::uninitialized_copy(I, E, Dest);
  187. #endif
  188. }
  189. /// uninitialized_copy - Copy the range [I, E) onto the uninitialized
  190. /// memory starting with "Dest", constructing elements as needed.
  191. template<typename It1, typename It2>
  192. static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
  193. std::uninitialized_copy(I, E, Dest);
  194. }
  195. /// grow - Grow the allocated memory (without initializing new
  196. /// elements), doubling the size of the allocated memory.
  197. /// Guarantees space for at least one more element, or MinSize more
  198. /// elements if specified.
  199. void grow(size_t MinSize = 0);
  200. public:
  201. void push_back(const T &Elt) {
  202. if (this->EndX < this->CapacityX) {
  203. Retry:
  204. ::new ((void*) this->end()) T(Elt);
  205. this->setEnd(this->end()+1);
  206. return;
  207. }
  208. this->grow();
  209. goto Retry;
  210. }
  211. #if LLVM_HAS_RVALUE_REFERENCES
  212. void push_back(T &&Elt) {
  213. if (this->EndX < this->CapacityX) {
  214. Retry:
  215. ::new ((void*) this->end()) T(::std::move(Elt));
  216. this->setEnd(this->end()+1);
  217. return;
  218. }
  219. this->grow();
  220. goto Retry;
  221. }
  222. #endif
  223. void pop_back() {
  224. this->setEnd(this->end()-1);
  225. this->end()->~T();
  226. }
  227. };
  228. // Define this out-of-line to dissuade the C++ compiler from inlining it.
  229. template <typename T, bool isPodLike>
  230. void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
  231. size_t CurCapacity = this->capacity();
  232. size_t CurSize = this->size();
  233. // Always grow, even from zero.
  234. size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
  235. if (NewCapacity < MinSize)
  236. NewCapacity = MinSize;
  237. T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T)));
  238. // Move the elements over.
  239. this->uninitialized_move(this->begin(), this->end(), NewElts);
  240. // Destroy the original elements.
  241. destroy_range(this->begin(), this->end());
  242. // If this wasn't grown from the inline copy, deallocate the old space.
  243. if (!this->isSmall())
  244. free(this->begin());
  245. this->setEnd(NewElts+CurSize);
  246. this->BeginX = NewElts;
  247. this->CapacityX = this->begin()+NewCapacity;
  248. }
  249. /// SmallVectorTemplateBase<isPodLike = true> - This is where we put method
  250. /// implementations that are designed to work with POD-like T's.
  251. template <typename T>
  252. class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
  253. protected:
  254. SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
  255. // No need to do a destroy loop for POD's.
  256. static void destroy_range(T *, T *) {}
  257. /// move - Use move-assignment to move the range [I, E) onto the
  258. /// objects starting with "Dest". For PODs, this is just memcpy.
  259. template<typename It1, typename It2>
  260. static It2 move(It1 I, It1 E, It2 Dest) {
  261. return ::std::copy(I, E, Dest);
  262. }
  263. /// move_backward - Use move-assignment to move the range
  264. /// [I, E) onto the objects ending at "Dest", moving objects
  265. /// in reverse order.
  266. template<typename It1, typename It2>
  267. static It2 move_backward(It1 I, It1 E, It2 Dest) {
  268. return ::std::copy_backward(I, E, Dest);
  269. }
  270. /// uninitialized_move - Move the range [I, E) onto the uninitialized memory
  271. /// starting with "Dest", constructing elements into it as needed.
  272. template<typename It1, typename It2>
  273. static void uninitialized_move(It1 I, It1 E, It2 Dest) {
  274. // Just do a copy.
  275. uninitialized_copy(I, E, Dest);
  276. }
  277. /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
  278. /// starting with "Dest", constructing elements into it as needed.
  279. template<typename It1, typename It2>
  280. static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
  281. // Arbitrary iterator types; just use the basic implementation.
  282. std::uninitialized_copy(I, E, Dest);
  283. }
  284. /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
  285. /// starting with "Dest", constructing elements into it as needed.
  286. template<typename T1, typename T2>
  287. static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest) {
  288. // Use memcpy for PODs iterated by pointers (which includes SmallVector
  289. // iterators): std::uninitialized_copy optimizes to memmove, but we can
  290. // use memcpy here.
  291. memcpy(Dest, I, (E-I)*sizeof(T));
  292. }
  293. /// grow - double the size of the allocated memory, guaranteeing space for at
  294. /// least one more element or MinSize if specified.
  295. void grow(size_t MinSize = 0) {
  296. this->grow_pod(MinSize*sizeof(T), sizeof(T));
  297. }
  298. public:
  299. void push_back(const T &Elt) {
  300. if (this->EndX < this->CapacityX) {
  301. Retry:
  302. memcpy(this->end(), &Elt, sizeof(T));
  303. this->setEnd(this->end()+1);
  304. return;
  305. }
  306. this->grow();
  307. goto Retry;
  308. }
  309. void pop_back() {
  310. this->setEnd(this->end()-1);
  311. }
  312. };
  313. /// SmallVectorImpl - This class consists of common code factored out of the
  314. /// SmallVector class to reduce code duplication based on the SmallVector 'N'
  315. /// template parameter.
  316. template <typename T>
  317. class SmallVectorImpl : public SmallVectorTemplateBase<T, isPodLike<T>::value> {
  318. typedef SmallVectorTemplateBase<T, isPodLike<T>::value > SuperClass;
  319. SmallVectorImpl(const SmallVectorImpl&) LLVM_DELETED_FUNCTION;
  320. public:
  321. typedef typename SuperClass::iterator iterator;
  322. typedef typename SuperClass::size_type size_type;
  323. protected:
  324. // Default ctor - Initialize to empty.
  325. explicit SmallVectorImpl(unsigned N)
  326. : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
  327. }
  328. public:
  329. ~SmallVectorImpl() {
  330. // Destroy the constructed elements in the vector.
  331. this->destroy_range(this->begin(), this->end());
  332. // If this wasn't grown from the inline copy, deallocate the old space.
  333. if (!this->isSmall())
  334. free(this->begin());
  335. }
  336. void clear() {
  337. this->destroy_range(this->begin(), this->end());
  338. this->EndX = this->BeginX;
  339. }
  340. void resize(unsigned N) {
  341. if (N < this->size()) {
  342. this->destroy_range(this->begin()+N, this->end());
  343. this->setEnd(this->begin()+N);
  344. } else if (N > this->size()) {
  345. if (this->capacity() < N)
  346. this->grow(N);
  347. std::uninitialized_fill(this->end(), this->begin()+N, T());
  348. this->setEnd(this->begin()+N);
  349. }
  350. }
  351. void resize(unsigned N, const T &NV) {
  352. if (N < this->size()) {
  353. this->destroy_range(this->begin()+N, this->end());
  354. this->setEnd(this->begin()+N);
  355. } else if (N > this->size()) {
  356. if (this->capacity() < N)
  357. this->grow(N);
  358. std::uninitialized_fill(this->end(), this->begin()+N, NV);
  359. this->setEnd(this->begin()+N);
  360. }
  361. }
  362. void reserve(unsigned N) {
  363. if (this->capacity() < N)
  364. this->grow(N);
  365. }
  366. T pop_back_val() {
  367. #if LLVM_HAS_RVALUE_REFERENCES
  368. T Result = ::std::move(this->back());
  369. #else
  370. T Result = this->back();
  371. #endif
  372. this->pop_back();
  373. return Result;
  374. }
  375. void swap(SmallVectorImpl &RHS);
  376. /// append - Add the specified range to the end of the SmallVector.
  377. ///
  378. template<typename in_iter>
  379. void append(in_iter in_start, in_iter in_end) {
  380. size_type NumInputs = std::distance(in_start, in_end);
  381. // Grow allocated space if needed.
  382. if (NumInputs > size_type(this->capacity_ptr()-this->end()))
  383. this->grow(this->size()+NumInputs);
  384. // Copy the new elements over.
  385. // TODO: NEED To compile time dispatch on whether in_iter is a random access
  386. // iterator to use the fast uninitialized_copy.
  387. std::uninitialized_copy(in_start, in_end, this->end());
  388. this->setEnd(this->end() + NumInputs);
  389. }
  390. /// append - Add the specified range to the end of the SmallVector.
  391. ///
  392. void append(size_type NumInputs, const T &Elt) {
  393. // Grow allocated space if needed.
  394. if (NumInputs > size_type(this->capacity_ptr()-this->end()))
  395. this->grow(this->size()+NumInputs);
  396. // Copy the new elements over.
  397. std::uninitialized_fill_n(this->end(), NumInputs, Elt);
  398. this->setEnd(this->end() + NumInputs);
  399. }
  400. void assign(unsigned NumElts, const T &Elt) {
  401. clear();
  402. if (this->capacity() < NumElts)
  403. this->grow(NumElts);
  404. this->setEnd(this->begin()+NumElts);
  405. std::uninitialized_fill(this->begin(), this->end(), Elt);
  406. }
  407. iterator erase(iterator I) {
  408. assert(I >= this->begin() && "Iterator to erase is out of bounds.");
  409. assert(I < this->end() && "Erasing at past-the-end iterator.");
  410. iterator N = I;
  411. // Shift all elts down one.
  412. this->move(I+1, this->end(), I);
  413. // Drop the last elt.
  414. this->pop_back();
  415. return(N);
  416. }
  417. iterator erase(iterator S, iterator E) {
  418. assert(S >= this->begin() && "Range to erase is out of bounds.");
  419. assert(S <= E && "Trying to erase invalid range.");
  420. assert(E <= this->end() && "Trying to erase past the end.");
  421. iterator N = S;
  422. // Shift all elts down.
  423. iterator I = this->move(E, this->end(), S);
  424. // Drop the last elts.
  425. this->destroy_range(I, this->end());
  426. this->setEnd(I);
  427. return(N);
  428. }
  429. #if LLVM_HAS_RVALUE_REFERENCES
  430. iterator insert(iterator I, T &&Elt) {
  431. if (I == this->end()) { // Important special case for empty vector.
  432. this->push_back(::std::move(Elt));
  433. return this->end()-1;
  434. }
  435. assert(I >= this->begin() && "Insertion iterator is out of bounds.");
  436. assert(I <= this->end() && "Inserting past the end of the vector.");
  437. if (this->EndX < this->CapacityX) {
  438. Retry:
  439. ::new ((void*) this->end()) T(::std::move(this->back()));
  440. this->setEnd(this->end()+1);
  441. // Push everything else over.
  442. this->move_backward(I, this->end()-1, this->end());
  443. // If we just moved the element we're inserting, be sure to update
  444. // the reference.
  445. T *EltPtr = &Elt;
  446. if (I <= EltPtr && EltPtr < this->EndX)
  447. ++EltPtr;
  448. *I = ::std::move(*EltPtr);
  449. return I;
  450. }
  451. size_t EltNo = I-this->begin();
  452. this->grow();
  453. I = this->begin()+EltNo;
  454. goto Retry;
  455. }
  456. #endif
  457. iterator insert(iterator I, const T &Elt) {
  458. if (I == this->end()) { // Important special case for empty vector.
  459. this->push_back(Elt);
  460. return this->end()-1;
  461. }
  462. assert(I >= this->begin() && "Insertion iterator is out of bounds.");
  463. assert(I <= this->end() && "Inserting past the end of the vector.");
  464. if (this->EndX < this->CapacityX) {
  465. Retry:
  466. ::new ((void*) this->end()) T(this->back());
  467. this->setEnd(this->end()+1);
  468. // Push everything else over.
  469. this->move_backward(I, this->end()-1, this->end());
  470. // If we just moved the element we're inserting, be sure to update
  471. // the reference.
  472. const T *EltPtr = &Elt;
  473. if (I <= EltPtr && EltPtr < this->EndX)
  474. ++EltPtr;
  475. *I = *EltPtr;
  476. return I;
  477. }
  478. size_t EltNo = I-this->begin();
  479. this->grow();
  480. I = this->begin()+EltNo;
  481. goto Retry;
  482. }
  483. iterator insert(iterator I, size_type NumToInsert, const T &Elt) {
  484. // Convert iterator to elt# to avoid invalidating iterator when we reserve()
  485. size_t InsertElt = I - this->begin();
  486. if (I == this->end()) { // Important special case for empty vector.
  487. append(NumToInsert, Elt);
  488. return this->begin()+InsertElt;
  489. }
  490. assert(I >= this->begin() && "Insertion iterator is out of bounds.");
  491. assert(I <= this->end() && "Inserting past the end of the vector.");
  492. // Ensure there is enough space.
  493. reserve(static_cast<unsigned>(this->size() + NumToInsert));
  494. // Uninvalidate the iterator.
  495. I = this->begin()+InsertElt;
  496. // If there are more elements between the insertion point and the end of the
  497. // range than there are being inserted, we can use a simple approach to
  498. // insertion. Since we already reserved space, we know that this won't
  499. // reallocate the vector.
  500. if (size_t(this->end()-I) >= NumToInsert) {
  501. T *OldEnd = this->end();
  502. append(this->end()-NumToInsert, this->end());
  503. // Copy the existing elements that get replaced.
  504. this->move_backward(I, OldEnd-NumToInsert, OldEnd);
  505. std::fill_n(I, NumToInsert, Elt);
  506. return I;
  507. }
  508. // Otherwise, we're inserting more elements than exist already, and we're
  509. // not inserting at the end.
  510. // Move over the elements that we're about to overwrite.
  511. T *OldEnd = this->end();
  512. this->setEnd(this->end() + NumToInsert);
  513. size_t NumOverwritten = OldEnd-I;
  514. this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
  515. // Replace the overwritten part.
  516. std::fill_n(I, NumOverwritten, Elt);
  517. // Insert the non-overwritten middle part.
  518. std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
  519. return I;
  520. }
  521. template<typename ItTy>
  522. iterator insert(iterator I, ItTy From, ItTy To) {
  523. // Convert iterator to elt# to avoid invalidating iterator when we reserve()
  524. size_t InsertElt = I - this->begin();
  525. if (I == this->end()) { // Important special case for empty vector.
  526. append(From, To);
  527. return this->begin()+InsertElt;
  528. }
  529. assert(I >= this->begin() && "Insertion iterator is out of bounds.");
  530. assert(I <= this->end() && "Inserting past the end of the vector.");
  531. size_t NumToInsert = std::distance(From, To);
  532. // Ensure there is enough space.
  533. reserve(static_cast<unsigned>(this->size() + NumToInsert));
  534. // Uninvalidate the iterator.
  535. I = this->begin()+InsertElt;
  536. // If there are more elements between the insertion point and the end of the
  537. // range than there are being inserted, we can use a simple approach to
  538. // insertion. Since we already reserved space, we know that this won't
  539. // reallocate the vector.
  540. if (size_t(this->end()-I) >= NumToInsert) {
  541. T *OldEnd = this->end();
  542. append(this->end()-NumToInsert, this->end());
  543. // Copy the existing elements that get replaced.
  544. this->move_backward(I, OldEnd-NumToInsert, OldEnd);
  545. std::copy(From, To, I);
  546. return I;
  547. }
  548. // Otherwise, we're inserting more elements than exist already, and we're
  549. // not inserting at the end.
  550. // Move over the elements that we're about to overwrite.
  551. T *OldEnd = this->end();
  552. this->setEnd(this->end() + NumToInsert);
  553. size_t NumOverwritten = OldEnd-I;
  554. this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
  555. // Replace the overwritten part.
  556. for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
  557. *J = *From;
  558. ++J; ++From;
  559. }
  560. // Insert the non-overwritten middle part.
  561. this->uninitialized_copy(From, To, OldEnd);
  562. return I;
  563. }
  564. SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
  565. #if LLVM_HAS_RVALUE_REFERENCES
  566. SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
  567. #endif
  568. bool operator==(const SmallVectorImpl &RHS) const {
  569. if (this->size() != RHS.size()) return false;
  570. return std::equal(this->begin(), this->end(), RHS.begin());
  571. }
  572. bool operator!=(const SmallVectorImpl &RHS) const {
  573. return !(*this == RHS);
  574. }
  575. bool operator<(const SmallVectorImpl &RHS) const {
  576. return std::lexicographical_compare(this->begin(), this->end(),
  577. RHS.begin(), RHS.end());
  578. }
  579. /// Set the array size to \p N, which the current array must have enough
  580. /// capacity for.
  581. ///
  582. /// This does not construct or destroy any elements in the vector.
  583. ///
  584. /// Clients can use this in conjunction with capacity() to write past the end
  585. /// of the buffer when they know that more elements are available, and only
  586. /// update the size later. This avoids the cost of value initializing elements
  587. /// which will only be overwritten.
  588. void set_size(unsigned N) {
  589. assert(N <= this->capacity());
  590. this->setEnd(this->begin() + N);
  591. }
  592. };
  593. template <typename T>
  594. void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
  595. if (this == &RHS) return;
  596. // We can only avoid copying elements if neither vector is small.
  597. if (!this->isSmall() && !RHS.isSmall()) {
  598. std::swap(this->BeginX, RHS.BeginX);
  599. std::swap(this->EndX, RHS.EndX);
  600. std::swap(this->CapacityX, RHS.CapacityX);
  601. return;
  602. }
  603. if (RHS.size() > this->capacity())
  604. this->grow(RHS.size());
  605. if (this->size() > RHS.capacity())
  606. RHS.grow(this->size());
  607. // Swap the shared elements.
  608. size_t NumShared = this->size();
  609. if (NumShared > RHS.size()) NumShared = RHS.size();
  610. for (unsigned i = 0; i != static_cast<unsigned>(NumShared); ++i)
  611. std::swap((*this)[i], RHS[i]);
  612. // Copy over the extra elts.
  613. if (this->size() > RHS.size()) {
  614. size_t EltDiff = this->size() - RHS.size();
  615. this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
  616. RHS.setEnd(RHS.end()+EltDiff);
  617. this->destroy_range(this->begin()+NumShared, this->end());
  618. this->setEnd(this->begin()+NumShared);
  619. } else if (RHS.size() > this->size()) {
  620. size_t EltDiff = RHS.size() - this->size();
  621. this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
  622. this->setEnd(this->end() + EltDiff);
  623. this->destroy_range(RHS.begin()+NumShared, RHS.end());
  624. RHS.setEnd(RHS.begin()+NumShared);
  625. }
  626. }
  627. template <typename T>
  628. SmallVectorImpl<T> &SmallVectorImpl<T>::
  629. operator=(const SmallVectorImpl<T> &RHS) {
  630. // Avoid self-assignment.
  631. if (this == &RHS) return *this;
  632. // If we already have sufficient space, assign the common elements, then
  633. // destroy any excess.
  634. size_t RHSSize = RHS.size();
  635. size_t CurSize = this->size();
  636. if (CurSize >= RHSSize) {
  637. // Assign common elements.
  638. iterator NewEnd;
  639. if (RHSSize)
  640. NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
  641. else
  642. NewEnd = this->begin();
  643. // Destroy excess elements.
  644. this->destroy_range(NewEnd, this->end());
  645. // Trim.
  646. this->setEnd(NewEnd);
  647. return *this;
  648. }
  649. // If we have to grow to have enough elements, destroy the current elements.
  650. // This allows us to avoid copying them during the grow.
  651. // FIXME: don't do this if they're efficiently moveable.
  652. if (this->capacity() < RHSSize) {
  653. // Destroy current elements.
  654. this->destroy_range(this->begin(), this->end());
  655. this->setEnd(this->begin());
  656. CurSize = 0;
  657. this->grow(RHSSize);
  658. } else if (CurSize) {
  659. // Otherwise, use assignment for the already-constructed elements.
  660. std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
  661. }
  662. // Copy construct the new elements in place.
  663. this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
  664. this->begin()+CurSize);
  665. // Set end.
  666. this->setEnd(this->begin()+RHSSize);
  667. return *this;
  668. }
  669. #if LLVM_HAS_RVALUE_REFERENCES
  670. template <typename T>
  671. SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
  672. // Avoid self-assignment.
  673. if (this == &RHS) return *this;
  674. // If the RHS isn't small, clear this vector and then steal its buffer.
  675. if (!RHS.isSmall()) {
  676. this->destroy_range(this->begin(), this->end());
  677. if (!this->isSmall()) free(this->begin());
  678. this->BeginX = RHS.BeginX;
  679. this->EndX = RHS.EndX;
  680. this->CapacityX = RHS.CapacityX;
  681. RHS.resetToSmall();
  682. return *this;
  683. }
  684. // If we already have sufficient space, assign the common elements, then
  685. // destroy any excess.
  686. size_t RHSSize = RHS.size();
  687. size_t CurSize = this->size();
  688. if (CurSize >= RHSSize) {
  689. // Assign common elements.
  690. iterator NewEnd = this->begin();
  691. if (RHSSize)
  692. NewEnd = this->move(RHS.begin(), RHS.end(), NewEnd);
  693. // Destroy excess elements and trim the bounds.
  694. this->destroy_range(NewEnd, this->end());
  695. this->setEnd(NewEnd);
  696. // Clear the RHS.
  697. RHS.clear();
  698. return *this;
  699. }
  700. // If we have to grow to have enough elements, destroy the current elements.
  701. // This allows us to avoid copying them during the grow.
  702. // FIXME: this may not actually make any sense if we can efficiently move
  703. // elements.
  704. if (this->capacity() < RHSSize) {
  705. // Destroy current elements.
  706. this->destroy_range(this->begin(), this->end());
  707. this->setEnd(this->begin());
  708. CurSize = 0;
  709. this->grow(RHSSize);
  710. } else if (CurSize) {
  711. // Otherwise, use assignment for the already-constructed elements.
  712. this->move(RHS.begin(), RHS.end(), this->begin());
  713. }
  714. // Move-construct the new elements in place.
  715. this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
  716. this->begin()+CurSize);
  717. // Set end.
  718. this->setEnd(this->begin()+RHSSize);
  719. RHS.clear();
  720. return *this;
  721. }
  722. #endif
  723. /// Storage for the SmallVector elements which aren't contained in
  724. /// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
  725. /// element is in the base class. This is specialized for the N=1 and N=0 cases
  726. /// to avoid allocating unnecessary storage.
  727. template <typename T, unsigned N>
  728. struct SmallVectorStorage {
  729. typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
  730. };
  731. template <typename T> struct SmallVectorStorage<T, 1> {};
  732. template <typename T> struct SmallVectorStorage<T, 0> {};
  733. /// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
  734. /// for the case when the array is small. It contains some number of elements
  735. /// in-place, which allows it to avoid heap allocation when the actual number of
  736. /// elements is below that threshold. This allows normal "small" cases to be
  737. /// fast without losing generality for large inputs.
  738. ///
  739. /// Note that this does not attempt to be exception safe.
  740. ///
  741. template <typename T, unsigned N>
  742. class SmallVector : public SmallVectorImpl<T> {
  743. /// Storage - Inline space for elements which aren't stored in the base class.
  744. SmallVectorStorage<T, N> Storage;
  745. public:
  746. SmallVector() : SmallVectorImpl<T>(N) {
  747. }
  748. explicit SmallVector(unsigned Size, const T &Value = T())
  749. : SmallVectorImpl<T>(N) {
  750. this->assign(Size, Value);
  751. }
  752. template<typename ItTy>
  753. SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
  754. this->append(S, E);
  755. }
  756. SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
  757. if (!RHS.empty())
  758. SmallVectorImpl<T>::operator=(RHS);
  759. }
  760. const SmallVector &operator=(const SmallVector &RHS) {
  761. SmallVectorImpl<T>::operator=(RHS);
  762. return *this;
  763. }
  764. #if LLVM_HAS_RVALUE_REFERENCES
  765. SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
  766. if (!RHS.empty())
  767. SmallVectorImpl<T>::operator=(::std::move(RHS));
  768. }
  769. const SmallVector &operator=(SmallVector &&RHS) {
  770. SmallVectorImpl<T>::operator=(::std::move(RHS));
  771. return *this;
  772. }
  773. #endif
  774. };
  775. template<typename T, unsigned N>
  776. static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
  777. return X.capacity_in_bytes();
  778. }
  779. } // End llvm namespace
  780. namespace std {
  781. /// Implement std::swap in terms of SmallVector swap.
  782. template<typename T>
  783. inline void
  784. swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
  785. LHS.swap(RHS);
  786. }
  787. /// Implement std::swap in terms of SmallVector swap.
  788. template<typename T, unsigned N>
  789. inline void
  790. swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
  791. LHS.swap(RHS);
  792. }
  793. }
  794. #endif