Skip to content

Commit 85b5450

Browse files
committed
[ArrayRef] Add constructor from iterator_range<U*> (NFC).
Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. I will share a follow-up soon.
1 parent 6ffccea commit 85b5450

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

llvm/include/llvm/ADT/ArrayRef.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,19 @@ namespace llvm {
149149
* = nullptr)
150150
: Data(Vec.data()), Length(Vec.size()) {}
151151

152+
/// Construct an ArrayRef<T> from iterator_range<U*>. This uses SFINAE
153+
/// to ensure that this is only used for iterator ranges of random access
154+
/// iterators that can be converted.
155+
template <typename U>
156+
ArrayRef(const iterator_range<U *> &Range,
157+
std::enable_if_t<std::is_base_of<std::random_access_iterator_tag,
158+
typename std::iterator_traits<
159+
decltype(Range.begin())>::
160+
iterator_category>::value &&
161+
std::is_convertible<U *, T const *>::value,
162+
void> * = nullptr)
163+
: Data(Range.begin()), Length(llvm::size(Range)) {}
164+
152165
/// @}
153166
/// @name Simple Operations
154167
/// @{

llvm/unittests/ADT/ArrayRefTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,26 @@ TEST(ArrayRefTest, ArrayRefFromStdArray) {
255255
}
256256
}
257257

258+
TEST(ArrayRefTest, ArrayRefFromIteratorRange) {
259+
std::array<int, 5> A1{{42, -5, 0, 1000000, -1000000}};
260+
ArrayRef<int> A2 = make_range(A1.begin(), A1.end());
261+
262+
EXPECT_EQ(A1.size(), A2.size());
263+
for (std::size_t i = 0; i < A1.size(); ++i) {
264+
EXPECT_EQ(A1[i], A2[i]);
265+
}
266+
}
267+
268+
TEST(ArrayRefTest, ArrayRefFromIteratorConstRange) {
269+
std::array<const int, 5> A1{{42, -5, 0, 1000000, -1000000}};
270+
ArrayRef<const int> A2 = make_range(A1.begin(), A1.end());
271+
272+
EXPECT_EQ(A1.size(), A2.size());
273+
for (std::size_t i = 0; i < A1.size(); ++i) {
274+
EXPECT_EQ(A1[i], A2[i]);
275+
}
276+
}
277+
258278
static_assert(std::is_trivially_copyable_v<ArrayRef<int>>,
259279
"trivially copyable");
260280

0 commit comments

Comments
 (0)