Skip to content

Commit

Permalink
Remove_copy{_if} takes an input_range
Browse files Browse the repository at this point in the history
  • Loading branch information
miscco committed Jul 9, 2020
1 parent f51c425 commit b3d722d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 20 deletions.
30 changes: 17 additions & 13 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -3489,7 +3489,7 @@ namespace ranges {
using _Not_quite_object::_Not_quite_object;

// clang-format off
template <permutable _It, sentinel_for<_It> _Se, weakly_incrementable _Out, class _Ty, class _Pj = identity>
template <input_iterator _It, sentinel_for<_It> _Se, weakly_incrementable _Out, class _Ty, class _Pj = identity>
requires indirectly_copyable<_It, _Out>
&& indirect_binary_predicate<ranges::equal_to, projected<_It, _Pj>, const _Ty*>
constexpr remove_copy_result<_It, _Out> operator()(
Expand All @@ -3503,24 +3503,26 @@ namespace ranges {
return {_STD move(_First), _STD move(_Result)};
}

template <forward_range _Rng, weakly_incrementable _Out, class _Ty, class _Pj = identity>
requires permutable<iterator_t<_Rng>> && indirectly_copyable<iterator_t<_Rng>, _Out>
template <input_range _Rng, weakly_incrementable _Out, class _Ty, class _Pj = identity>
requires indirectly_copyable<iterator_t<_Rng>, _Out>
&& indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rng>, _Pj>, const _Ty*>
constexpr remove_copy_result<borrowed_iterator_t<_Rng>, _Out> operator()(
_Rng&& _Range, _Out _Result, const _Ty& _Val, _Pj _Proj = {}) const {
auto _UResult = _Remove_copy_unchecked(
_Ubegin(_Range), _Uend(_Range), _Get_unwrapped_unverified(_STD move(_Result)), _Val, _Pass_fn(_Proj));
auto _First = _RANGES begin(_Range);
auto _UResult = _Remove_copy_unchecked(_Get_unwrapped(_STD move(_First)), _Uend(_Range),
_Get_unwrapped_unverified(_STD move(_Result)), _Val, _Pass_fn(_Proj));

_Seek_wrapped(_First, _STD move(_UResult.in));
_Seek_wrapped(_Result, _STD move(_UResult.out));
return {_Rewrap_iterator(_Range, _STD move(_UResult.in)), _STD move(_Result)};
return {_STD move(_First), _STD move(_Result)};
}
// clang-format on
private:
template <class _It, class _Se, class _Out, class _Ty, class _Pj>
_NODISCARD static constexpr remove_copy_result<_It, _Out> _Remove_copy_unchecked(
_It _First, const _Se _Last, _Out _Result, const _Ty& _Val, _Pj _Proj) {
// Copy [_First, _Last) to _Result except projected values equal to _Val
_STL_INTERNAL_STATIC_ASSERT(permutable<_It>);
_STL_INTERNAL_STATIC_ASSERT(input_iterator<_It>);
_STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>);
_STL_INTERNAL_STATIC_ASSERT(weakly_incrementable<_Out>);
_STL_INTERNAL_STATIC_ASSERT(indirectly_copyable<_It, _Out>);
Expand Down Expand Up @@ -3549,7 +3551,7 @@ namespace ranges {
using _Not_quite_object::_Not_quite_object;

// clang-format off
template <permutable _It, sentinel_for<_It> _Se, weakly_incrementable _Out, class _Pj = identity,
template <input_iterator _It, sentinel_for<_It> _Se, weakly_incrementable _Out, class _Pj = identity,
indirect_unary_predicate<projected<_It, _Pj>> _Pr>
requires indirectly_copyable<_It, _Out>
constexpr remove_copy_if_result<_It, _Out> operator()(
Expand All @@ -3564,24 +3566,26 @@ namespace ranges {
return {_STD move(_First), _STD move(_Result)};
}

template <forward_range _Rng, weakly_incrementable _Out, class _Pj = identity,
template <input_range _Rng, weakly_incrementable _Out, class _Pj = identity,
indirect_unary_predicate<projected<iterator_t<_Rng>, _Pj>> _Pr>
requires permutable<iterator_t<_Rng>> && indirectly_copyable<iterator_t<_Rng>, _Out>
requires indirectly_copyable<iterator_t<_Rng>, _Out>
constexpr remove_copy_if_result<borrowed_iterator_t<_Rng>, _Out> operator()(
_Rng&& _Range, _Out _Result, _Pr _Pred, _Pj _Proj = {}) const {
auto _UResult = _Remove_copy_if_unchecked(_Ubegin(_Range), _Uend(_Range),
auto _First = _RANGES begin(_Range);
auto _UResult = _Remove_copy_if_unchecked(_Get_unwrapped(_STD move(_First)), _Uend(_Range),
_Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), _Pass_fn(_Proj));

_Seek_wrapped(_First, _STD move(_UResult.in));
_Seek_wrapped(_Result, _STD move(_UResult.out));
return {_Rewrap_iterator(_Range, _STD move(_UResult.in)), _STD move(_Result)};
return {_STD move(_First), _STD move(_Result)};
}
// clang-format on
private:
template <class _It, class _Se, class _Out, class _Pr, class _Pj>
_NODISCARD static constexpr remove_copy_if_result<_It, _Out> _Remove_copy_if_unchecked(
_It _First, const _Se _Last, _Out _Result, _Pr _Pred, _Pj _Proj) {
// Copy [_First, _Last) to _Result except projected values that satisfy _Pred
_STL_INTERNAL_STATIC_ASSERT(permutable<_It>);
_STL_INTERNAL_STATIC_ASSERT(input_iterator<_It>);
_STL_INTERNAL_STATIC_ASSERT(sentinel_for<_Se, _It>);
_STL_INTERNAL_STATIC_ASSERT(weakly_incrementable<_Out>);
_STL_INTERNAL_STATIC_ASSERT(indirectly_copyable<_It, _Out>);
Expand Down
6 changes: 3 additions & 3 deletions tests/std/tests/P0896R4_ranges_alg_remove_copy/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct instantiator {
static constexpr P input[5] = {{0, 99}, {1, 47}, {2, 99}, {3, 47}, {4, 99}};
static constexpr P expected[3] = {{0, 99}, {2, 99}, {4, 99}};

template <ranges::forward_range Read, indirectly_writable<ranges::range_reference_t<Read>> Write>
template <ranges::input_range Read, indirectly_writable<ranges::range_reference_t<Read>> Write>
static constexpr void call() {
using ranges::remove_copy, ranges::remove_copy_result, ranges::iterator_t;
{ // Validate iterator + sentinel overload
Expand All @@ -51,6 +51,6 @@ struct instantiator {
};

int main() {
STATIC_ASSERT((test_fwd_write<instantiator, P const, P>(), true));
test_fwd_write<instantiator, P const, P>();
STATIC_ASSERT((test_in_write<instantiator, const P, P>(), true));
test_in_write<instantiator, const P, P>();
}
8 changes: 4 additions & 4 deletions tests/std/tests/P0896R4_ranges_alg_remove_copy_if/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
using namespace std;
using P = pair<int, int>;

constexpr auto matches = [](int const val) { return val == 47; };
constexpr auto matches = [](const int val) { return val == 47; };

// Validate that remove_copy_if_result aliases in_out_result
STATIC_ASSERT(same_as<ranges::remove_copy_if_result<int, double>, ranges::in_out_result<int, double>>);
Expand All @@ -26,7 +26,7 @@ struct instantiator {
static constexpr P input[5] = {{0, 99}, {1, 47}, {2, 99}, {3, 47}, {4, 99}};
static constexpr P expected[3] = {{0, 99}, {2, 99}, {4, 99}};

template <ranges::forward_range Read, indirectly_writable<ranges::range_reference_t<Read>> Write>
template <ranges::input_range Read, indirectly_writable<ranges::range_reference_t<Read>> Write>
static constexpr void call() {
using ranges::remove_copy_if, ranges::remove_copy_if_result, ranges::iterator_t;
{ // Validate iterator + sentinel overload
Expand Down Expand Up @@ -54,6 +54,6 @@ struct instantiator {
};

int main() {
STATIC_ASSERT((test_fwd_write<instantiator, P const, P>(), true));
test_fwd_write<instantiator, P const, P>();
STATIC_ASSERT((test_in_write<instantiator, const P, P>(), true));
test_in_write<instantiator, const P, P>();
}

0 comments on commit b3d722d

Please sign in to comment.