1326943Sdim//===-- sanitizer_vector.h -------------------------------------*- C++ -*-===// 2326943Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326943Sdim// 7326943Sdim//===----------------------------------------------------------------------===// 8326943Sdim// 9326943Sdim// This file is shared between sanitizers run-time libraries. 10326943Sdim// 11326943Sdim//===----------------------------------------------------------------------===// 12326943Sdim 13326943Sdim// Low-fat STL-like vector container. 14326943Sdim 15326943Sdim#ifndef SANITIZER_VECTOR_H 16326943Sdim#define SANITIZER_VECTOR_H 17326943Sdim 18326943Sdim#include "sanitizer_common/sanitizer_allocator_internal.h" 19326943Sdim#include "sanitizer_common/sanitizer_libc.h" 20326943Sdim 21326943Sdimnamespace __sanitizer { 22326943Sdim 23326943Sdimtemplate<typename T> 24326943Sdimclass Vector { 25326943Sdim public: 26360784Sdim Vector() : begin_(), end_(), last_() {} 27326943Sdim 28326943Sdim ~Vector() { 29326943Sdim if (begin_) 30326943Sdim InternalFree(begin_); 31326943Sdim } 32326943Sdim 33326943Sdim void Reset() { 34326943Sdim if (begin_) 35326943Sdim InternalFree(begin_); 36326943Sdim begin_ = 0; 37326943Sdim end_ = 0; 38326943Sdim last_ = 0; 39326943Sdim } 40326943Sdim 41326943Sdim uptr Size() const { 42326943Sdim return end_ - begin_; 43326943Sdim } 44326943Sdim 45326943Sdim T &operator[](uptr i) { 46326943Sdim DCHECK_LT(i, end_ - begin_); 47326943Sdim return begin_[i]; 48326943Sdim } 49326943Sdim 50326943Sdim const T &operator[](uptr i) const { 51326943Sdim DCHECK_LT(i, end_ - begin_); 52326943Sdim return begin_[i]; 53326943Sdim } 54326943Sdim 55326943Sdim T *PushBack() { 56326943Sdim EnsureSize(Size() + 1); 57326943Sdim T *p = &end_[-1]; 58326943Sdim internal_memset(p, 0, sizeof(*p)); 59326943Sdim return p; 60326943Sdim } 61326943Sdim 62326943Sdim T *PushBack(const T& v) { 63326943Sdim EnsureSize(Size() + 1); 64326943Sdim T *p = &end_[-1]; 65326943Sdim internal_memcpy(p, &v, sizeof(*p)); 66326943Sdim return p; 67326943Sdim } 68326943Sdim 69326943Sdim void PopBack() { 70326943Sdim DCHECK_GT(end_, begin_); 71326943Sdim end_--; 72326943Sdim } 73326943Sdim 74326943Sdim void Resize(uptr size) { 75326943Sdim if (size == 0) { 76326943Sdim end_ = begin_; 77326943Sdim return; 78326943Sdim } 79326943Sdim uptr old_size = Size(); 80341825Sdim if (size <= old_size) { 81341825Sdim end_ = begin_ + size; 82341825Sdim return; 83341825Sdim } 84326943Sdim EnsureSize(size); 85326943Sdim if (old_size < size) { 86326943Sdim for (uptr i = old_size; i < size; i++) 87326943Sdim internal_memset(&begin_[i], 0, sizeof(begin_[i])); 88326943Sdim } 89326943Sdim } 90326943Sdim 91326943Sdim private: 92326943Sdim T *begin_; 93326943Sdim T *end_; 94326943Sdim T *last_; 95326943Sdim 96326943Sdim void EnsureSize(uptr size) { 97326943Sdim if (size <= Size()) 98326943Sdim return; 99326943Sdim if (size <= (uptr)(last_ - begin_)) { 100326943Sdim end_ = begin_ + size; 101326943Sdim return; 102326943Sdim } 103326943Sdim uptr cap0 = last_ - begin_; 104326943Sdim uptr cap = cap0 * 5 / 4; // 25% growth 105326943Sdim if (cap == 0) 106326943Sdim cap = 16; 107326943Sdim if (cap < size) 108326943Sdim cap = size; 109326943Sdim T *p = (T*)InternalAlloc(cap * sizeof(T)); 110326943Sdim if (cap0) { 111326943Sdim internal_memcpy(p, begin_, cap0 * sizeof(T)); 112326943Sdim InternalFree(begin_); 113326943Sdim } 114326943Sdim begin_ = p; 115326943Sdim end_ = begin_ + size; 116326943Sdim last_ = begin_ + cap; 117326943Sdim } 118326943Sdim 119326943Sdim Vector(const Vector&); 120326943Sdim void operator=(const Vector&); 121326943Sdim}; 122326943Sdim} // namespace __sanitizer 123326943Sdim 124326943Sdim#endif // #ifndef SANITIZER_VECTOR_H 125