sanitizer_array_ref.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //===-- sanitizer_array_ref.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. #ifndef SANITIZER_ARRAY_REF_H
  9. #define SANITIZER_ARRAY_REF_H
  10. #include "sanitizer_internal_defs.h"
  11. namespace __sanitizer {
  12. /// ArrayRef - Represent a constant reference to an array (0 or more elements
  13. /// consecutively in memory), i.e. a start pointer and a length. It allows
  14. /// various APIs to take consecutive elements easily and conveniently.
  15. ///
  16. /// This class does not own the underlying data, it is expected to be used in
  17. /// situations where the data resides in some other buffer, whose lifetime
  18. /// extends past that of the ArrayRef. For this reason, it is not in general
  19. /// safe to store an ArrayRef.
  20. ///
  21. /// This is intended to be trivially copyable, so it should be passed by
  22. /// value.
  23. template <typename T>
  24. class ArrayRef {
  25. public:
  26. constexpr ArrayRef() {}
  27. constexpr ArrayRef(const T *begin, const T *end) : begin_(begin), end_(end) {
  28. DCHECK(empty() || begin);
  29. }
  30. constexpr ArrayRef(const T *data, uptr length)
  31. : ArrayRef(data, data + length) {}
  32. template <uptr N>
  33. constexpr ArrayRef(const T (&src)[N]) : ArrayRef(src, src + N) {}
  34. template <typename C>
  35. constexpr ArrayRef(const C &src)
  36. : ArrayRef(src.data(), src.data() + src.size()) {}
  37. ArrayRef(const T &one_elt) : ArrayRef(&one_elt, &one_elt + 1) {}
  38. const T *data() const { return empty() ? nullptr : begin_; }
  39. const T *begin() const { return begin_; }
  40. const T *end() const { return end_; }
  41. bool empty() const { return begin_ == end_; }
  42. uptr size() const { return end_ - begin_; }
  43. /// equals - Check for element-wise equality.
  44. bool equals(ArrayRef rhs) const {
  45. if (size() != rhs.size())
  46. return false;
  47. auto r = rhs.begin();
  48. for (auto &l : *this) {
  49. if (!(l == *r))
  50. return false;
  51. ++r;
  52. }
  53. return true;
  54. }
  55. /// slice(n, m) - Chop off the first N elements of the array, and keep M
  56. /// elements in the array.
  57. ArrayRef<T> slice(uptr N, uptr M) const {
  58. DCHECK_LE(N + M, size());
  59. return ArrayRef<T>(data() + N, M);
  60. }
  61. /// slice(n) - Chop off the first N elements of the array.
  62. ArrayRef<T> slice(uptr N) const { return slice(N, size() - N); }
  63. /// Drop the first \p N elements of the array.
  64. ArrayRef<T> drop_front(uptr N = 1) const {
  65. DCHECK_GE(size(), N);
  66. return slice(N, size() - N);
  67. }
  68. /// Drop the last \p N elements of the array.
  69. ArrayRef<T> drop_back(uptr N = 1) const {
  70. DCHECK_GE(size(), N);
  71. return slice(0, size() - N);
  72. }
  73. /// Return a copy of *this with only the first \p N elements.
  74. ArrayRef<T> take_front(uptr N = 1) const {
  75. if (N >= size())
  76. return *this;
  77. return drop_back(size() - N);
  78. }
  79. /// Return a copy of *this with only the last \p N elements.
  80. ArrayRef<T> take_back(uptr N = 1) const {
  81. if (N >= size())
  82. return *this;
  83. return drop_front(size() - N);
  84. }
  85. const T &operator[](uptr index) const {
  86. DCHECK_LT(index, size());
  87. return begin_[index];
  88. }
  89. private:
  90. const T *begin_ = nullptr;
  91. const T *end_ = nullptr;
  92. };
  93. template <typename T>
  94. inline bool operator==(ArrayRef<T> lhs, ArrayRef<T> rhs) {
  95. return lhs.equals(rhs);
  96. }
  97. template <typename T>
  98. inline bool operator!=(ArrayRef<T> lhs, ArrayRef<T> rhs) {
  99. return !(lhs == rhs);
  100. }
  101. } // namespace __sanitizer
  102. #endif // SANITIZER_ARRAY_REF_H