Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_array_ref.h
35233 views
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
9
#ifndef SANITIZER_ARRAY_REF_H
10
#define SANITIZER_ARRAY_REF_H
11
12
#include "sanitizer_internal_defs.h"
13
14
namespace __sanitizer {
15
16
/// ArrayRef - Represent a constant reference to an array (0 or more elements
17
/// consecutively in memory), i.e. a start pointer and a length. It allows
18
/// 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 in
21
/// situations where the data resides in some other buffer, whose lifetime
22
/// extends past that of the ArrayRef. For this reason, it is not in general
23
/// safe to store an ArrayRef.
24
///
25
/// This is intended to be trivially copyable, so it should be passed by
26
/// value.
27
template <typename T>
28
class 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 M
66
/// 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
111
template <typename T>
112
inline bool operator==(ArrayRef<T> lhs, ArrayRef<T> rhs) {
113
return lhs.equals(rhs);
114
}
115
116
template <typename T>
117
inline bool operator!=(ArrayRef<T> lhs, ArrayRef<T> rhs) {
118
return !(lhs == rhs);
119
}
120
121
} // namespace __sanitizer
122
123
#endif // SANITIZER_ARRAY_REF_H
124
125