13cab2bb3Spatrick //===-- sanitizer_vector.h -------------------------------------*- C++ -*-===// 23cab2bb3Spatrick // 33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information. 53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63cab2bb3Spatrick // 73cab2bb3Spatrick //===----------------------------------------------------------------------===// 83cab2bb3Spatrick // 93cab2bb3Spatrick // This file is shared between sanitizers run-time libraries. 103cab2bb3Spatrick // 113cab2bb3Spatrick //===----------------------------------------------------------------------===// 123cab2bb3Spatrick 133cab2bb3Spatrick // Low-fat STL-like vector container. 143cab2bb3Spatrick 153cab2bb3Spatrick #ifndef SANITIZER_VECTOR_H 163cab2bb3Spatrick #define SANITIZER_VECTOR_H 173cab2bb3Spatrick 183cab2bb3Spatrick #include "sanitizer_common/sanitizer_allocator_internal.h" 193cab2bb3Spatrick #include "sanitizer_common/sanitizer_libc.h" 203cab2bb3Spatrick 213cab2bb3Spatrick namespace __sanitizer { 223cab2bb3Spatrick 233cab2bb3Spatrick template<typename T> 243cab2bb3Spatrick class Vector { 253cab2bb3Spatrick public: Vector()263cab2bb3Spatrick Vector() : begin_(), end_(), last_() {} 273cab2bb3Spatrick ~Vector()283cab2bb3Spatrick ~Vector() { 293cab2bb3Spatrick if (begin_) 303cab2bb3Spatrick InternalFree(begin_); 313cab2bb3Spatrick } 323cab2bb3Spatrick Reset()333cab2bb3Spatrick void Reset() { 343cab2bb3Spatrick if (begin_) 353cab2bb3Spatrick InternalFree(begin_); 363cab2bb3Spatrick begin_ = 0; 373cab2bb3Spatrick end_ = 0; 383cab2bb3Spatrick last_ = 0; 393cab2bb3Spatrick } 403cab2bb3Spatrick Size()413cab2bb3Spatrick uptr Size() const { 423cab2bb3Spatrick return end_ - begin_; 433cab2bb3Spatrick } 443cab2bb3Spatrick 453cab2bb3Spatrick T &operator[](uptr i) { 463cab2bb3Spatrick DCHECK_LT(i, end_ - begin_); 473cab2bb3Spatrick return begin_[i]; 483cab2bb3Spatrick } 493cab2bb3Spatrick 503cab2bb3Spatrick const T &operator[](uptr i) const { 513cab2bb3Spatrick DCHECK_LT(i, end_ - begin_); 523cab2bb3Spatrick return begin_[i]; 533cab2bb3Spatrick } 543cab2bb3Spatrick PushBack()553cab2bb3Spatrick T *PushBack() { 563cab2bb3Spatrick EnsureSize(Size() + 1); 573cab2bb3Spatrick T *p = &end_[-1]; 583cab2bb3Spatrick internal_memset(p, 0, sizeof(*p)); 593cab2bb3Spatrick return p; 603cab2bb3Spatrick } 613cab2bb3Spatrick PushBack(const T & v)623cab2bb3Spatrick T *PushBack(const T& v) { 633cab2bb3Spatrick EnsureSize(Size() + 1); 643cab2bb3Spatrick T *p = &end_[-1]; 653cab2bb3Spatrick internal_memcpy(p, &v, sizeof(*p)); 663cab2bb3Spatrick return p; 673cab2bb3Spatrick } 683cab2bb3Spatrick PopBack()693cab2bb3Spatrick void PopBack() { 703cab2bb3Spatrick DCHECK_GT(end_, begin_); 713cab2bb3Spatrick end_--; 723cab2bb3Spatrick } 733cab2bb3Spatrick Resize(uptr size)743cab2bb3Spatrick void Resize(uptr size) { 753cab2bb3Spatrick if (size == 0) { 763cab2bb3Spatrick end_ = begin_; 773cab2bb3Spatrick return; 783cab2bb3Spatrick } 793cab2bb3Spatrick uptr old_size = Size(); 803cab2bb3Spatrick if (size <= old_size) { 813cab2bb3Spatrick end_ = begin_ + size; 823cab2bb3Spatrick return; 833cab2bb3Spatrick } 843cab2bb3Spatrick EnsureSize(size); 853cab2bb3Spatrick if (old_size < size) { 86*810390e3Srobert internal_memset(&begin_[old_size], 0, 87*810390e3Srobert sizeof(begin_[old_size]) * (size - old_size)); 883cab2bb3Spatrick } 893cab2bb3Spatrick } 903cab2bb3Spatrick 913cab2bb3Spatrick private: 923cab2bb3Spatrick T *begin_; 933cab2bb3Spatrick T *end_; 943cab2bb3Spatrick T *last_; 953cab2bb3Spatrick EnsureSize(uptr size)963cab2bb3Spatrick void EnsureSize(uptr size) { 973cab2bb3Spatrick if (size <= Size()) 983cab2bb3Spatrick return; 993cab2bb3Spatrick if (size <= (uptr)(last_ - begin_)) { 1003cab2bb3Spatrick end_ = begin_ + size; 1013cab2bb3Spatrick return; 1023cab2bb3Spatrick } 1033cab2bb3Spatrick uptr cap0 = last_ - begin_; 1043cab2bb3Spatrick uptr cap = cap0 * 5 / 4; // 25% growth 1053cab2bb3Spatrick if (cap == 0) 1063cab2bb3Spatrick cap = 16; 1073cab2bb3Spatrick if (cap < size) 1083cab2bb3Spatrick cap = size; 1093cab2bb3Spatrick T *p = (T*)InternalAlloc(cap * sizeof(T)); 1103cab2bb3Spatrick if (cap0) { 1113cab2bb3Spatrick internal_memcpy(p, begin_, cap0 * sizeof(T)); 1123cab2bb3Spatrick InternalFree(begin_); 1133cab2bb3Spatrick } 1143cab2bb3Spatrick begin_ = p; 1153cab2bb3Spatrick end_ = begin_ + size; 1163cab2bb3Spatrick last_ = begin_ + cap; 1173cab2bb3Spatrick } 1183cab2bb3Spatrick 1193cab2bb3Spatrick Vector(const Vector&); 1203cab2bb3Spatrick void operator=(const Vector&); 1213cab2bb3Spatrick }; 1223cab2bb3Spatrick } // namespace __sanitizer 1233cab2bb3Spatrick 1243cab2bb3Spatrick #endif // #ifndef SANITIZER_VECTOR_H 125