]>
Commit | Line | Data |
---|---|---|
d2ef4bee | 1 | //===-- sanitizer_vector.h -------------------------------------*- C++ -*-===// |
9cf75457 | 2 | // |
2fc4da48 | 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 | |
9cf75457 | 6 | // |
7 | //===----------------------------------------------------------------------===// | |
8 | // | |
d2ef4bee | 9 | // This file is shared between sanitizers run-time libraries. |
9cf75457 | 10 | // |
11 | //===----------------------------------------------------------------------===// | |
12 | ||
13 | // Low-fat STL-like vector container. | |
14 | ||
d2ef4bee | 15 | #ifndef SANITIZER_VECTOR_H |
16 | #define SANITIZER_VECTOR_H | |
9cf75457 | 17 | |
d2ef4bee | 18 | #include "sanitizer_common/sanitizer_allocator_internal.h" |
19 | #include "sanitizer_common/sanitizer_libc.h" | |
9cf75457 | 20 | |
d2ef4bee | 21 | namespace __sanitizer { |
9cf75457 | 22 | |
23 | template<typename T> | |
24 | class Vector { | |
25 | public: | |
d2ef4bee | 26 | explicit Vector() |
27 | : begin_() | |
9cf75457 | 28 | , end_() |
29 | , last_() { | |
30 | } | |
31 | ||
32 | ~Vector() { | |
33 | if (begin_) | |
d2ef4bee | 34 | InternalFree(begin_); |
9cf75457 | 35 | } |
36 | ||
37 | void Reset() { | |
38 | if (begin_) | |
d2ef4bee | 39 | InternalFree(begin_); |
9cf75457 | 40 | begin_ = 0; |
41 | end_ = 0; | |
42 | last_ = 0; | |
43 | } | |
44 | ||
45 | uptr Size() const { | |
46 | return end_ - begin_; | |
47 | } | |
48 | ||
49 | T &operator[](uptr i) { | |
50 | DCHECK_LT(i, end_ - begin_); | |
51 | return begin_[i]; | |
52 | } | |
53 | ||
54 | const T &operator[](uptr i) const { | |
55 | DCHECK_LT(i, end_ - begin_); | |
56 | return begin_[i]; | |
57 | } | |
58 | ||
7d752f28 | 59 | T *PushBack() { |
9cf75457 | 60 | EnsureSize(Size() + 1); |
7d752f28 | 61 | T *p = &end_[-1]; |
62 | internal_memset(p, 0, sizeof(*p)); | |
63 | return p; | |
64 | } | |
65 | ||
66 | T *PushBack(const T& v) { | |
67 | EnsureSize(Size() + 1); | |
68 | T *p = &end_[-1]; | |
69 | internal_memcpy(p, &v, sizeof(*p)); | |
70 | return p; | |
9cf75457 | 71 | } |
72 | ||
1e80ce41 | 73 | void PopBack() { |
74 | DCHECK_GT(end_, begin_); | |
75 | end_--; | |
76 | } | |
77 | ||
9cf75457 | 78 | void Resize(uptr size) { |
a9586c9c | 79 | if (size == 0) { |
80 | end_ = begin_; | |
81 | return; | |
82 | } | |
9cf75457 | 83 | uptr old_size = Size(); |
d2ef4bee | 84 | if (size <= old_size) { |
85 | end_ = begin_ + size; | |
86 | return; | |
87 | } | |
9cf75457 | 88 | EnsureSize(size); |
89 | if (old_size < size) { | |
90 | for (uptr i = old_size; i < size; i++) | |
7d752f28 | 91 | internal_memset(&begin_[i], 0, sizeof(begin_[i])); |
9cf75457 | 92 | } |
93 | } | |
94 | ||
95 | private: | |
9cf75457 | 96 | T *begin_; |
97 | T *end_; | |
98 | T *last_; | |
99 | ||
100 | void EnsureSize(uptr size) { | |
101 | if (size <= Size()) | |
102 | return; | |
103 | if (size <= (uptr)(last_ - begin_)) { | |
104 | end_ = begin_ + size; | |
105 | return; | |
106 | } | |
107 | uptr cap0 = last_ - begin_; | |
a9586c9c | 108 | uptr cap = cap0 * 5 / 4; // 25% growth |
9cf75457 | 109 | if (cap == 0) |
110 | cap = 16; | |
111 | if (cap < size) | |
112 | cap = size; | |
d2ef4bee | 113 | T *p = (T*)InternalAlloc(cap * sizeof(T)); |
9cf75457 | 114 | if (cap0) { |
115 | internal_memcpy(p, begin_, cap0 * sizeof(T)); | |
d2ef4bee | 116 | InternalFree(begin_); |
9cf75457 | 117 | } |
118 | begin_ = p; | |
119 | end_ = begin_ + size; | |
120 | last_ = begin_ + cap; | |
121 | } | |
122 | ||
123 | Vector(const Vector&); | |
124 | void operator=(const Vector&); | |
125 | }; | |
d2ef4bee | 126 | } // namespace __sanitizer |
9cf75457 | 127 | |
d2ef4bee | 128 | #endif // #ifndef SANITIZER_VECTOR_H |