brintos

brintos / llvm-project-archived public Read only

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