PR c/85696
[official-gcc.git] / libsanitizer / tsan / tsan_vector.h
blobc0485513ee27445cf62a37774d8d0c4090172a2b
1 //===-- tsan_vector.h -------------------------------------------*- C++ -*-===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
9 //
10 //===----------------------------------------------------------------------===//
12 // Low-fat STL-like vector container.
14 #ifndef TSAN_VECTOR_H
15 #define TSAN_VECTOR_H
17 #include "tsan_defs.h"
18 #include "tsan_mman.h"
20 namespace __tsan {
22 template<typename T>
23 class Vector {
24 public:
25 explicit Vector(MBlockType typ)
26 : typ_(typ)
27 , begin_()
28 , end_()
29 , last_() {
32 ~Vector() {
33 if (begin_)
34 internal_free(begin_);
37 void Reset() {
38 if (begin_)
39 internal_free(begin_);
40 begin_ = 0;
41 end_ = 0;
42 last_ = 0;
45 uptr Size() const {
46 return end_ - begin_;
49 T &operator[](uptr i) {
50 DCHECK_LT(i, end_ - begin_);
51 return begin_[i];
54 const T &operator[](uptr i) const {
55 DCHECK_LT(i, end_ - begin_);
56 return begin_[i];
59 T *PushBack() {
60 EnsureSize(Size() + 1);
61 T *p = &end_[-1];
62 internal_memset(p, 0, sizeof(*p));
63 return p;
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;
73 void PopBack() {
74 DCHECK_GT(end_, begin_);
75 end_--;
78 void Resize(uptr size) {
79 if (size == 0) {
80 end_ = begin_;
81 return;
83 uptr old_size = Size();
84 EnsureSize(size);
85 if (old_size < size) {
86 for (uptr i = old_size; i < size; i++)
87 internal_memset(&begin_[i], 0, sizeof(begin_[i]));
91 private:
92 const MBlockType typ_;
93 T *begin_;
94 T *end_;
95 T *last_;
97 void EnsureSize(uptr size) {
98 if (size <= Size())
99 return;
100 if (size <= (uptr)(last_ - begin_)) {
101 end_ = begin_ + size;
102 return;
104 uptr cap0 = last_ - begin_;
105 uptr cap = cap0 * 5 / 4; // 25% growth
106 if (cap == 0)
107 cap = 16;
108 if (cap < size)
109 cap = size;
110 T *p = (T*)internal_alloc(typ_, cap * sizeof(T));
111 if (cap0) {
112 internal_memcpy(p, begin_, cap0 * sizeof(T));
113 internal_free(begin_);
115 begin_ = p;
116 end_ = begin_ + size;
117 last_ = begin_ + cap;
120 Vector(const Vector&);
121 void operator=(const Vector&);
123 } // namespace __tsan
125 #endif // #ifndef TSAN_VECTOR_H