Commit c51c9f7c authored by Philip Pfaffe's avatar Philip Pfaffe Committed by Commit Bot

Improve iterator_range to take non-&& arguments

The current implementation takes forwarding reference arguments, which
is fine when you call it with rvalues, like
make_iterator_range(V.begin(), V.end()). If you call it with lvalues
though, it doesn't do what you'd expect. ForwardIterator becomes a
reference:

Foo I = V.begin();
make_iterator_range(I, I); //ForwardIterator is deduced as Foo&

Since iterator are supposed to be small, no harm in passing them by
value.

Change-Id: I151c87304949d810c72c42f60e9d1a7151f61f83
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2020780
Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66007}
parent 8c8732f4
...@@ -37,9 +37,8 @@ class iterator_range { ...@@ -37,9 +37,8 @@ class iterator_range {
iterator_range() : begin_(), end_() {} iterator_range() : begin_(), end_() {}
template <typename ForwardIterator1, typename ForwardIterator2> template <typename ForwardIterator1, typename ForwardIterator2>
iterator_range(ForwardIterator1&& begin, ForwardIterator2&& end) iterator_range(ForwardIterator1 begin, ForwardIterator2 end)
: begin_(std::forward<ForwardIterator1>(begin)), : begin_(begin), end_(end) {}
end_(std::forward<ForwardIterator2>(end)) {}
iterator begin() { return begin_; } iterator begin() { return begin_; }
iterator end() { return end_; } iterator end() { return end_; }
...@@ -60,9 +59,8 @@ class iterator_range { ...@@ -60,9 +59,8 @@ class iterator_range {
}; };
template <typename ForwardIterator> template <typename ForwardIterator>
auto make_iterator_range(ForwardIterator&& begin, ForwardIterator&& end) { auto make_iterator_range(ForwardIterator begin, ForwardIterator end) {
return iterator_range<ForwardIterator>{std::forward<ForwardIterator>(begin), return iterator_range<ForwardIterator>{begin, end};
std::forward<ForwardIterator>(end)};
} }
// {Reversed} returns a container adapter usable in a range-based "for" // {Reversed} returns a container adapter usable in a range-based "for"
......
...@@ -20,7 +20,6 @@ TEST(IteratorTest, IteratorRangeEmpty) { ...@@ -20,7 +20,6 @@ TEST(IteratorTest, IteratorRangeEmpty) {
EXPECT_EQ(0, r.size()); EXPECT_EQ(0, r.size());
} }
TEST(IteratorTest, IteratorRangeArray) { TEST(IteratorTest, IteratorRangeArray) {
int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
base::iterator_range<int*> r1(&array[0], &array[10]); base::iterator_range<int*> r1(&array[0], &array[10]);
...@@ -40,7 +39,6 @@ TEST(IteratorTest, IteratorRangeArray) { ...@@ -40,7 +39,6 @@ TEST(IteratorTest, IteratorRangeArray) {
} }
} }
TEST(IteratorTest, IteratorRangeDeque) { TEST(IteratorTest, IteratorRangeDeque) {
using C = std::deque<int>; using C = std::deque<int>;
C c; C c;
...@@ -57,5 +55,18 @@ TEST(IteratorTest, IteratorRangeDeque) { ...@@ -57,5 +55,18 @@ TEST(IteratorTest, IteratorRangeDeque) {
EXPECT_EQ(2, std::count(r.begin(), r.end(), 2)); EXPECT_EQ(2, std::count(r.begin(), r.end(), 2));
} }
TEST(IteratorTest, IteratorTypeDeduction) {
base::iterator_range<char*> r;
auto r2 = make_iterator_range(r.begin(), r.end());
EXPECT_EQ(r2.begin(), r.begin());
EXPECT_EQ(r2.end(), r2.end());
auto I = r.begin(), E = r.end();
// Check that this compiles and does the correct thing even if the iterators
// are lvalues:
auto r3 = make_iterator_range(I, E);
EXPECT_TRUE((std::is_same<decltype(r2), decltype(r3)>::value));
EXPECT_EQ(r3.begin(), r.begin());
EXPECT_EQ(r3.end(), r2.end());
}
} // namespace base } // namespace base
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment