]> git.ipfire.org Git - thirdparty/gcc.git/blame - libsanitizer/sanitizer_common/sanitizer_vector.h
Libsanitizer: merge from trunk with merge.sh.
[thirdparty/gcc.git] / libsanitizer / sanitizer_common / sanitizer_vector.h
CommitLineData
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 21namespace __sanitizer {
cd0be65c
WM
22
23template<typename T>
24class 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