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