|
3 | 3 | // 1. 数据较少时没有堆分配 |
4 | 4 | // 2. 没有强异常保证,因此某些情况下更快 |
5 | 5 | // 3. 对于 POD 类型直接操作内存而不是使用啰嗦且低效的 Allocator |
6 | | -// 移植自 https://github.com/llvm/llvm-project/blob/7fbdee3e29203f2ffd1996c2919096e0bfe7c93b/llvm/include/llvm/ADT/SmallVector.h 和 https://github.com/llvm/llvm-project/blob/7fbdee3e29203f2ffd1996c2919096e0bfe7c93b/llvm/lib/Support/SmallVector.cpp |
| 6 | +// 移植自 https://github.com/llvm/llvm-project/blob/a6eddf9a79709e3161d3aad86d44ab1097f57f22/llvm/include/llvm/ADT/SmallVector.h 和 https://github.com/llvm/llvm-project/blob/a6eddf9a79709e3161d3aad86d44ab1097f57f22/llvm/lib/Support/SmallVector.cpp |
7 | 7 | // 所作修改如下: |
8 | 8 | // 1. 删除跨编译器逻辑 |
9 | 9 | // 2. 修复 MSVC 警告 |
@@ -63,7 +63,7 @@ template <class Size_T> class SmallVectorBase { |
63 | 63 |
|
64 | 64 | SmallVectorBase() = delete; |
65 | 65 | SmallVectorBase(void* FirstEl, size_t TotalCapacity) |
66 | | - : BeginX(FirstEl), Capacity((Size_T)TotalCapacity) { |
| 66 | + : BeginX(FirstEl), Capacity(static_cast<Size_T>(TotalCapacity)) { |
67 | 67 | } |
68 | 68 |
|
69 | 69 | /// This is a helper for \a grow() that's out of line to reduce code |
@@ -102,8 +102,18 @@ template <class Size_T> class SmallVectorBase { |
102 | 102 | /// |
103 | 103 | /// This does not construct or destroy any elements in the vector. |
104 | 104 | void set_size(size_t N) { |
105 | | - assert(N <= capacity()); |
106 | | - Size = (Size_T)N; |
| 105 | + assert(N <= capacity()); // implies no overflow in assignment |
| 106 | + Size = static_cast<Size_T>(N); |
| 107 | + } |
| 108 | + |
| 109 | + /// Set the array data pointer to \p Begin and capacity to \p N. |
| 110 | + /// |
| 111 | + /// This does not construct or destroy any elements in the vector. |
| 112 | + // This does not clean up any existing allocation. |
| 113 | + void set_allocation_range(void* Begin, size_t N) { |
| 114 | + assert(N <= SizeTypeMax()); |
| 115 | + BeginX = Begin; |
| 116 | + Capacity = static_cast<Size_T>(N); |
107 | 117 | } |
108 | 118 | }; |
109 | 119 |
|
@@ -468,8 +478,7 @@ void SmallVectorTemplateBase<T, TriviallyCopyable>::takeAllocationForGrow( |
468 | 478 | if (!this->isSmall()) |
469 | 479 | free(this->begin()); |
470 | 480 |
|
471 | | - this->BeginX = NewElts; |
472 | | - this->Capacity = (decltype(this->Capacity))NewCapacity; |
| 481 | + this->set_allocation_range(NewElts, NewCapacity); |
473 | 482 | } |
474 | 483 |
|
475 | 484 | /// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put |
@@ -602,16 +611,16 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { |
602 | 611 | RHS.resetToSmall(); |
603 | 612 | } |
604 | 613 |
|
605 | | -public: |
606 | | - SmallVectorImpl(const SmallVectorImpl&) = delete; |
607 | | - |
608 | 614 | ~SmallVectorImpl() { |
609 | 615 | // Subclass has already destructed this vector's elements. |
610 | 616 | // If this wasn't grown from the inline copy, deallocate the old space. |
611 | 617 | if (!this->isSmall()) |
612 | 618 | free(this->begin()); |
613 | 619 | } |
614 | 620 |
|
| 621 | +public: |
| 622 | + SmallVectorImpl(const SmallVectorImpl&) = delete; |
| 623 | + |
615 | 624 | void clear() { |
616 | 625 | this->destroy_range(this->begin(), this->end()); |
617 | 626 | this->Size = 0; |
@@ -1210,7 +1219,12 @@ class SmallVector : public SmallVectorImpl<T>, |
1210 | 1219 | this->destroy_range(this->begin(), this->end()); |
1211 | 1220 | } |
1212 | 1221 |
|
1213 | | - explicit SmallVector(size_t Size, const T& Value = T()) |
| 1222 | + explicit SmallVector(size_t Size) |
| 1223 | + : SmallVectorImpl<T>(N) { |
| 1224 | + this->resize(Size); |
| 1225 | + } |
| 1226 | + |
| 1227 | + SmallVector(size_t Size, const T& Value) |
1214 | 1228 | : SmallVectorImpl<T>(N) { |
1215 | 1229 | this->assign(Size, Value); |
1216 | 1230 | } |
|
0 commit comments