sanitizer_vector.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //===-- sanitizer_vector.h -------------------------------------*- C++ -*-===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is shared between sanitizers run-time libraries.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. // Low-fat STL-like vector container.
  13. #ifndef SANITIZER_VECTOR_H
  14. #define SANITIZER_VECTOR_H
  15. #include "sanitizer_common/sanitizer_allocator_internal.h"
  16. #include "sanitizer_common/sanitizer_libc.h"
  17. namespace __sanitizer {
  18. template<typename T>
  19. class Vector {
  20. public:
  21. Vector() : begin_(), end_(), last_() {}
  22. ~Vector() {
  23. if (begin_)
  24. InternalFree(begin_);
  25. }
  26. void Reset() {
  27. if (begin_)
  28. InternalFree(begin_);
  29. begin_ = 0;
  30. end_ = 0;
  31. last_ = 0;
  32. }
  33. uptr Size() const {
  34. return end_ - begin_;
  35. }
  36. T &operator[](uptr i) {
  37. DCHECK_LT(i, end_ - begin_);
  38. return begin_[i];
  39. }
  40. const T &operator[](uptr i) const {
  41. DCHECK_LT(i, end_ - begin_);
  42. return begin_[i];
  43. }
  44. T *PushBack() {
  45. EnsureSize(Size() + 1);
  46. T *p = &end_[-1];
  47. internal_memset(p, 0, sizeof(*p));
  48. return p;
  49. }
  50. T *PushBack(const T& v) {
  51. EnsureSize(Size() + 1);
  52. T *p = &end_[-1];
  53. internal_memcpy(p, &v, sizeof(*p));
  54. return p;
  55. }
  56. void PopBack() {
  57. DCHECK_GT(end_, begin_);
  58. end_--;
  59. }
  60. void Resize(uptr size) {
  61. if (size == 0) {
  62. end_ = begin_;
  63. return;
  64. }
  65. uptr old_size = Size();
  66. if (size <= old_size) {
  67. end_ = begin_ + size;
  68. return;
  69. }
  70. EnsureSize(size);
  71. if (old_size < size) {
  72. for (uptr i = old_size; i < size; i++)
  73. internal_memset(&begin_[i], 0, sizeof(begin_[i]));
  74. }
  75. }
  76. private:
  77. T *begin_;
  78. T *end_;
  79. T *last_;
  80. void EnsureSize(uptr size) {
  81. if (size <= Size())
  82. return;
  83. if (size <= (uptr)(last_ - begin_)) {
  84. end_ = begin_ + size;
  85. return;
  86. }
  87. uptr cap0 = last_ - begin_;
  88. uptr cap = cap0 * 5 / 4; // 25% growth
  89. if (cap == 0)
  90. cap = 16;
  91. if (cap < size)
  92. cap = size;
  93. T *p = (T*)InternalAlloc(cap * sizeof(T));
  94. if (cap0) {
  95. internal_memcpy(p, begin_, cap0 * sizeof(T));
  96. InternalFree(begin_);
  97. }
  98. begin_ = p;
  99. end_ = begin_ + size;
  100. last_ = begin_ + cap;
  101. }
  102. Vector(const Vector&);
  103. void operator=(const Vector&);
  104. };
  105. } // namespace __sanitizer
  106. #endif // #ifndef SANITIZER_VECTOR_H