Skip to content

Commit d91b397

Browse files
Merge pull request #4347 from romainbrenguier/feature/range-drop
Add ranget drop and skip methods
2 parents 902fec4 + 962c9f4 commit d91b397

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/util/range.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ struct ranget final
289289
public:
290290
using value_type = typename iteratort::value_type;
291291

292-
ranget(iteratort begin, iteratort end) : begin_value(begin), end_value(end)
292+
ranget(iteratort begin, iteratort end)
293+
: begin_value(std::move(begin)), end_value(std::move(end))
293294
{
294295
}
295296

@@ -341,6 +342,24 @@ struct ranget final
341342
return begin_value == end_value;
342343
}
343344

345+
/// Return an new range containing the same elements except for the first
346+
/// \p count elements.
347+
/// If the range has fewer elements, returns an empty range.
348+
ranget<iteratort> drop(std::size_t count) &&
349+
{
350+
for(; count > 0 && begin_value != end_value; --count)
351+
++begin_value;
352+
return ranget<iteratort>{std::move(begin_value), std::move(end_value)};
353+
}
354+
355+
/// Return an new range containing the same elements except for the first
356+
/// \p count elements.
357+
/// If the range has fewer elements, returns an empty range.
358+
ranget<iteratort> drop(std::size_t count) const &
359+
{
360+
return ranget<iteratort>{begin(), end()}.drop(count);
361+
}
362+
344363
iteratort begin() const
345364
{
346365
return begin_value;

unit/util/range.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,45 @@ SCENARIO("range tests", "[core][util][range]")
5757
++it;
5858
REQUIRE(it == filtered_range.end());
5959
}
60+
61+
THEN("Drop first 2 elements")
62+
{
63+
auto range = make_range(list);
64+
auto drop_range = range.drop(2);
65+
auto it = drop_range.begin();
66+
REQUIRE(*it == "acdef");
67+
drop_range = std::move(drop_range).drop(1);
68+
REQUIRE(drop_range.empty());
69+
// Check the original is unmodified
70+
REQUIRE(!range.empty());
71+
REQUIRE(*range.begin() == "abc");
72+
}
73+
THEN("Drop first 5 elements")
74+
{
75+
auto range = make_range(list);
76+
auto skip_range = range.drop(5);
77+
REQUIRE(skip_range.empty());
78+
// Check the original is unmodified
79+
REQUIRE(!range.empty());
80+
REQUIRE(*range.begin() == "abc");
81+
}
82+
THEN("Drop first 2 elements, move version")
83+
{
84+
auto range = make_range(list);
85+
range = std::move(range).drop(2);
86+
REQUIRE(!range.empty());
87+
auto it = range.begin();
88+
REQUIRE(*it == "acdef");
89+
range = std::move(range).drop(1);
90+
REQUIRE(range.empty());
91+
}
92+
THEN("Drop first 5 elements, move version")
93+
{
94+
auto range = make_range(list);
95+
range = std::move(range).drop(5);
96+
REQUIRE(range.empty());
97+
}
98+
6099
THEN(
61100
"A const instance of a `filter_iteratort` can mutate the input "
62101
"collection.")

0 commit comments

Comments
 (0)