summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_vector.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sanitizer_common/sanitizer_vector.h')
-rw-r--r--lib/sanitizer_common/sanitizer_vector.h125
1 files changed, 125 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_vector.h b/lib/sanitizer_common/sanitizer_vector.h
new file mode 100644
index 000000000..25cfeed35
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_vector.h
@@ -0,0 +1,125 @@
+//===-- sanitizer_vector.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between sanitizers run-time libraries.
+//
+//===----------------------------------------------------------------------===//
+
+// Low-fat STL-like vector container.
+
+#ifndef SANITIZER_VECTOR_H
+#define SANITIZER_VECTOR_H
+
+#include "sanitizer_common/sanitizer_allocator_internal.h"
+#include "sanitizer_common/sanitizer_libc.h"
+
+namespace __sanitizer {
+
+template<typename T>
+class Vector {
+ public:
+ explicit Vector()
+ : begin_()
+ , end_()
+ , last_() {
+ }
+
+ ~Vector() {
+ if (begin_)
+ InternalFree(begin_);
+ }
+
+ void Reset() {
+ if (begin_)
+ InternalFree(begin_);
+ begin_ = 0;
+ end_ = 0;
+ last_ = 0;
+ }
+
+ uptr Size() const {
+ return end_ - begin_;
+ }
+
+ T &operator[](uptr i) {
+ DCHECK_LT(i, end_ - begin_);
+ return begin_[i];
+ }
+
+ const T &operator[](uptr i) const {
+ DCHECK_LT(i, end_ - begin_);
+ return begin_[i];
+ }
+
+ T *PushBack() {
+ EnsureSize(Size() + 1);
+ T *p = &end_[-1];
+ internal_memset(p, 0, sizeof(*p));
+ return p;
+ }
+
+ T *PushBack(const T& v) {
+ EnsureSize(Size() + 1);
+ T *p = &end_[-1];
+ internal_memcpy(p, &v, sizeof(*p));
+ return p;
+ }
+
+ void PopBack() {
+ DCHECK_GT(end_, begin_);
+ end_--;
+ }
+
+ void Resize(uptr size) {
+ if (size == 0) {
+ end_ = begin_;
+ return;
+ }
+ uptr old_size = Size();
+ EnsureSize(size);
+ if (old_size < size) {
+ for (uptr i = old_size; i < size; i++)
+ internal_memset(&begin_[i], 0, sizeof(begin_[i]));
+ }
+ }
+
+ private:
+ T *begin_;
+ T *end_;
+ T *last_;
+
+ void EnsureSize(uptr size) {
+ if (size <= Size())
+ return;
+ if (size <= (uptr)(last_ - begin_)) {
+ end_ = begin_ + size;
+ return;
+ }
+ uptr cap0 = last_ - begin_;
+ uptr cap = cap0 * 5 / 4; // 25% growth
+ if (cap == 0)
+ cap = 16;
+ if (cap < size)
+ cap = size;
+ T *p = (T*)InternalAlloc(cap * sizeof(T));
+ if (cap0) {
+ internal_memcpy(p, begin_, cap0 * sizeof(T));
+ InternalFree(begin_);
+ }
+ begin_ = p;
+ end_ = begin_ + size;
+ last_ = begin_ + cap;
+ }
+
+ Vector(const Vector&);
+ void operator=(const Vector&);
+};
+} // namespace __sanitizer
+
+#endif // #ifndef SANITIZER_VECTOR_H