[libc-commits] [libc] f6b6568 - [libc] Add slice/take/drop methods to ArrayRef
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Fri Apr 16 00:55:18 PDT 2021
Author: Guillaume Chatelet
Date: 2021-04-16T07:54:48Z
New Revision: f6b656853644a058534bffb0708c2e95347bd233
URL: https://github.com/llvm/llvm-project/commit/f6b656853644a058534bffb0708c2e95347bd233
DIFF: https://github.com/llvm/llvm-project/commit/f6b656853644a058534bffb0708c2e95347bd233.diff
LOG: [libc] Add slice/take/drop methods to ArrayRef
Add various methods from llvm::ArrayRef. Refactor implementation to remove code duplication.
Differential Revision: https://reviews.llvm.org/D100569
Added:
Modified:
libc/utils/CPP/ArrayRef.h
Removed:
################################################################################
diff --git a/libc/utils/CPP/ArrayRef.h b/libc/utils/CPP/ArrayRef.h
index bad415eba74d6..7a2ea09131c4b 100644
--- a/libc/utils/CPP/ArrayRef.h
+++ b/libc/utils/CPP/ArrayRef.h
@@ -20,74 +20,82 @@ namespace cpp {
// on the implementations of the types with the same names in
// llvm/ADT/ArrayRef.h. The implementations in this file are of a limited
// functionality, but can be extended in an as needed basis.
-
-template <typename T> class ArrayRef {
+namespace internal {
+template <typename T> class ArrayRefBase {
public:
- using iterator = const T *;
-
-private:
- const T *Data = nullptr;
- size_t Length = 0;
+ using iterator = T *;
+ using pointer = T *;
+ using reference = T &;
-public:
- ArrayRef() = default;
+ ArrayRefBase() = default;
// From Array.
template <size_t N>
- ArrayRef(const Array<T, N> &Arr) : Data(Arr.Data), Length(N) {}
+ ArrayRefBase(Array<T, N> &Arr) : Data(Arr.Data), Length(N) {}
- // Construct an ArrayRef from a single element.
- explicit ArrayRef(const T &OneElt) : Data(&OneElt), Length(1) {}
+ // Construct an ArrayRefBase from a single element.
+ explicit ArrayRefBase(T &OneElt) : Data(&OneElt), Length(1) {}
- // Construct an ArrayRef from a pointer and length.
- ArrayRef(const T *data, size_t length) : Data(data), Length(length) {}
+ // Construct an ArrayRefBase from a pointer and length.
+ ArrayRefBase(pointer Data, size_t Length) : Data(Data), Length(Length) {}
- // Construct an ArrayRef from a range.
- ArrayRef(const T *begin, const T *end) : Data(begin), Length(end - begin) {}
+ // Construct an ArrayRefBase from a range.
+ ArrayRefBase(iterator Begin, iterator End)
+ : Data(Begin), Length(End - Begin) {}
- // Construct an ArrayRef from a C array.
+ // Construct an ArrayRefBase from a C array.
template <size_t N>
- constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
+ constexpr ArrayRefBase(T (&Arr)[N]) : Data(Arr), Length(N) {}
iterator begin() const { return Data; }
iterator end() const { return Data + Length; }
bool empty() const { return Length == 0; }
- const T *data() const { return Data; }
+ pointer data() const { return Data; }
size_t size() const { return Length; }
- const T &operator[](size_t Index) const { return Data[Index]; }
-};
-
-template <typename T> class MutableArrayRef : public ArrayRef<T> {
-public:
- using iterator = T *;
-
- // From Array.
- template <size_t N> MutableArrayRef(Array<T, N> &Arr) : ArrayRef<T>(Arr) {}
-
- // Construct from a single element.
- explicit MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
-
- // Construct from a pointer and length.
- MutableArrayRef(T *data, size_t length) : ArrayRef<T>(data, length) {}
-
- // Construct from a range.
- MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
-
- // Construct from a C array.
- template <size_t N>
- constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {}
+ reference operator[](size_t Index) const { return Data[Index]; }
+
+ // slice(n, m) - Chop off the first N elements of the array, and keep M
+ // elements in the array.
+ ArrayRefBase<T> slice(size_t N, size_t M) const {
+ return ArrayRefBase<T>(data() + N, M);
+ }
+ // slice(n) - Chop off the first N elements of the array.
+ ArrayRefBase<T> slice(size_t N) const { return slice(N, size() - N); }
+
+ // Drop the first \p N elements of the array.
+ ArrayRefBase<T> drop_front(size_t N = 1) const {
+ return slice(N, size() - N);
+ }
+
+ // Drop the last \p N elements of the array.
+ ArrayRefBase<T> drop_back(size_t N = 1) const { return slice(0, size() - N); }
+
+ // Return a copy of *this with only the first \p N elements.
+ ArrayRefBase<T> take_front(size_t N = 1) const {
+ if (N >= size())
+ return *this;
+ return drop_back(size() - N);
+ }
+
+ // Return a copy of *this with only the last \p N elements.
+ ArrayRefBase<T> take_back(size_t N = 1) const {
+ if (N >= size())
+ return *this;
+ return drop_front(size() - N);
+ }
- T *data() const { return const_cast<T *>(ArrayRef<T>::data()); }
-
- iterator begin() const { return data(); }
- iterator end() const { return data() + this->size(); }
-
- T &operator[](size_t Index) const { return data()[Index]; }
+private:
+ pointer Data = nullptr;
+ size_t Length = 0;
};
+} // namespace internal
+
+template <typename T> using ArrayRef = internal::ArrayRefBase<const T>;
+template <typename T> using MutableArrayRef = internal::ArrayRefBase<T>;
} // namespace cpp
} // namespace __llvm_libc
More information about the libc-commits
mailing list