Path: blob/main/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_array_ref.h
35233 views
//===-- sanitizer_array_ref.h -----------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef SANITIZER_ARRAY_REF_H9#define SANITIZER_ARRAY_REF_H1011#include "sanitizer_internal_defs.h"1213namespace __sanitizer {1415/// ArrayRef - Represent a constant reference to an array (0 or more elements16/// consecutively in memory), i.e. a start pointer and a length. It allows17/// various APIs to take consecutive elements easily and conveniently.18///19/// This class does not own the underlying data, it is expected to be used in20/// situations where the data resides in some other buffer, whose lifetime21/// extends past that of the ArrayRef. For this reason, it is not in general22/// safe to store an ArrayRef.23///24/// This is intended to be trivially copyable, so it should be passed by25/// value.26template <typename T>27class ArrayRef {28public:29constexpr ArrayRef() {}30constexpr ArrayRef(const T *begin, const T *end) : begin_(begin), end_(end) {31DCHECK(empty() || begin);32}33constexpr ArrayRef(const T *data, uptr length)34: ArrayRef(data, data + length) {}35template <uptr N>36constexpr ArrayRef(const T (&src)[N]) : ArrayRef(src, src + N) {}37template <typename C>38constexpr ArrayRef(const C &src)39: ArrayRef(src.data(), src.data() + src.size()) {}40ArrayRef(const T &one_elt) : ArrayRef(&one_elt, &one_elt + 1) {}4142const T *data() const { return empty() ? nullptr : begin_; }4344const T *begin() const { return begin_; }45const T *end() const { return end_; }4647bool empty() const { return begin_ == end_; }4849uptr size() const { return end_ - begin_; }5051/// equals - Check for element-wise equality.52bool equals(ArrayRef rhs) const {53if (size() != rhs.size())54return false;55auto r = rhs.begin();56for (auto &l : *this) {57if (!(l == *r))58return false;59++r;60}61return true;62}6364/// slice(n, m) - Chop off the first N elements of the array, and keep M65/// elements in the array.66ArrayRef<T> slice(uptr N, uptr M) const {67DCHECK_LE(N + M, size());68return ArrayRef<T>(data() + N, M);69}7071/// slice(n) - Chop off the first N elements of the array.72ArrayRef<T> slice(uptr N) const { return slice(N, size() - N); }7374/// Drop the first \p N elements of the array.75ArrayRef<T> drop_front(uptr N = 1) const {76DCHECK_GE(size(), N);77return slice(N, size() - N);78}7980/// Drop the last \p N elements of the array.81ArrayRef<T> drop_back(uptr N = 1) const {82DCHECK_GE(size(), N);83return slice(0, size() - N);84}8586/// Return a copy of *this with only the first \p N elements.87ArrayRef<T> take_front(uptr N = 1) const {88if (N >= size())89return *this;90return drop_back(size() - N);91}9293/// Return a copy of *this with only the last \p N elements.94ArrayRef<T> take_back(uptr N = 1) const {95if (N >= size())96return *this;97return drop_front(size() - N);98}99100const T &operator[](uptr index) const {101DCHECK_LT(index, size());102return begin_[index];103}104105private:106const T *begin_ = nullptr;107const T *end_ = nullptr;108};109110template <typename T>111inline bool operator==(ArrayRef<T> lhs, ArrayRef<T> rhs) {112return lhs.equals(rhs);113}114115template <typename T>116inline bool operator!=(ArrayRef<T> lhs, ArrayRef<T> rhs) {117return !(lhs == rhs);118}119120} // namespace __sanitizer121122#endif // SANITIZER_ARRAY_REF_H123124125