зеркало из https://github.com/microsoft/STL.git
Implement ranges::adjacent_find (#822)
This commit is contained in:
Родитель
79c602144b
Коммит
995401051f
|
@ -504,6 +504,46 @@ _NODISCARD _FwdIt adjacent_find(_ExPo&& _Exec, const _FwdIt _First, const _FwdIt
|
|||
|
||||
#ifdef __cpp_lib_concepts
|
||||
namespace ranges {
|
||||
// VARIABLE ranges::adjacent_find
|
||||
class _Adjacent_find_fn : private _Not_quite_object {
|
||||
public:
|
||||
using _Not_quite_object::_Not_quite_object;
|
||||
|
||||
template <forward_iterator _It, sentinel_for<_It> _Se, class _Pj = identity,
|
||||
indirect_binary_predicate<projected<_It, _Pj>, projected<_It, _Pj>> _Pr = ranges::equal_to>
|
||||
_NODISCARD constexpr _It operator()(_It _First, const _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const {
|
||||
// find first satisfying _Pred with successor
|
||||
_Adl_verify_range(_First, _Last);
|
||||
auto _UFirst = _Get_unwrapped(_First);
|
||||
const auto _ULast = _Get_unwrapped(_Last);
|
||||
|
||||
if (_UFirst == _ULast) {
|
||||
return _First;
|
||||
}
|
||||
|
||||
for (auto _UNext = _UFirst;; _UFirst = _UNext) {
|
||||
if (++_UNext == _ULast) {
|
||||
_Seek_wrapped(_First, _UNext);
|
||||
return _First;
|
||||
}
|
||||
|
||||
if (_STD invoke(_Pred, _STD invoke(_Proj, *_UFirst), _STD invoke(_Proj, *_UNext))) {
|
||||
_Seek_wrapped(_First, _UFirst);
|
||||
return _First;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <forward_range _Rng, class _Pj = identity,
|
||||
indirect_binary_predicate<projected<iterator_t<_Rng>, _Pj>, projected<iterator_t<_Rng>, _Pj>> _Pr =
|
||||
ranges::equal_to>
|
||||
_NODISCARD constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const {
|
||||
return (*this)(_RANGES begin(_Range), _RANGES end(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj));
|
||||
}
|
||||
};
|
||||
|
||||
inline constexpr _Adjacent_find_fn adjacent_find{_Not_quite_object::_Construct_tag{}};
|
||||
|
||||
// VARIABLE ranges::count
|
||||
class _Count_fn : private _Not_quite_object {
|
||||
public:
|
||||
|
|
|
@ -542,6 +542,11 @@ void test_in() {
|
|||
with_input_ranges<Instantiator>::call();
|
||||
}
|
||||
|
||||
template <class Instantiator>
|
||||
void test_fwd() {
|
||||
with_forward_ranges<Instantiator>::call();
|
||||
}
|
||||
|
||||
template <class Instantiator>
|
||||
void test_in_in() {
|
||||
with_input_ranges<with_input_ranges<Instantiator>>::call();
|
||||
|
|
|
@ -231,6 +231,7 @@ tests\P0784R7_library_support_for_more_constexpr_containers
|
|||
tests\P0811R3_midpoint_lerp
|
||||
tests\P0896R4_P1614R2_comparisons
|
||||
tests\P0896R4_ranges_algorithm_machinery
|
||||
tests\P0896R4_ranges_alg_adjacent_find
|
||||
tests\P0896R4_ranges_alg_all_of
|
||||
tests\P0896R4_ranges_alg_any_of
|
||||
tests\P0896R4_ranges_alg_copy
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\concepts_matrix.lst
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <ranges>
|
||||
#include <utility>
|
||||
//
|
||||
#include <range_algorithm_support.hpp>
|
||||
|
||||
constexpr void smoke_test() {
|
||||
using ranges::adjacent_find, ranges::iterator_t, std::same_as;
|
||||
using P = std::pair<int, int>;
|
||||
|
||||
// Validate dangling story
|
||||
STATIC_ASSERT(same_as<decltype(adjacent_find(borrowed<false>{}, ranges::equal_to{})), ranges::dangling>);
|
||||
STATIC_ASSERT(same_as<decltype(adjacent_find(borrowed<true>{}, ranges::equal_to{})), int*>);
|
||||
|
||||
const std::array pairs = {P{0, 42}, P{1, 42}, P{2, 42}, P{4, 42}, P{5, 42}};
|
||||
const auto pred = [](const int x, const int y) { return y - x > 1; };
|
||||
|
||||
{
|
||||
// Validate range overload [found case]
|
||||
const auto result = adjacent_find(pairs, pred, get_first);
|
||||
STATIC_ASSERT(same_as<decltype(result), const iterator_t<decltype(pairs)>>);
|
||||
assert(result == pairs.begin() + 2);
|
||||
}
|
||||
{
|
||||
// Validate iterator + sentinel overload [found case]
|
||||
const auto result = adjacent_find(pairs.begin(), pairs.end(), pred, get_first);
|
||||
STATIC_ASSERT(same_as<decltype(result), const iterator_t<decltype(pairs)>>);
|
||||
assert(result == pairs.begin() + 2);
|
||||
}
|
||||
{
|
||||
// Validate range overload [not found case]
|
||||
const auto result = adjacent_find(pairs, ranges::equal_to{}, get_first);
|
||||
STATIC_ASSERT(same_as<decltype(result), const iterator_t<decltype(pairs)>>);
|
||||
assert(result == pairs.end());
|
||||
}
|
||||
{
|
||||
// Validate iterator + sentinel overload [not found case]
|
||||
const auto result = adjacent_find(pairs.begin(), pairs.end(), ranges::equal_to{}, get_first);
|
||||
STATIC_ASSERT(same_as<decltype(result), const iterator_t<decltype(pairs)>>);
|
||||
assert(result == pairs.end());
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
STATIC_ASSERT((smoke_test(), true));
|
||||
smoke_test();
|
||||
}
|
||||
|
||||
struct instantiator {
|
||||
template <class Fwd>
|
||||
static void call(Fwd&& fwd = {}) {
|
||||
using ranges::adjacent_find, ranges::iterator_t;
|
||||
|
||||
(void) adjacent_find(fwd);
|
||||
(void) adjacent_find(begin(fwd), end(fwd));
|
||||
|
||||
BinaryPredicateFor<iterator_t<Fwd>, iterator_t<Fwd>> pred{};
|
||||
(void) adjacent_find(fwd, pred);
|
||||
(void) adjacent_find(begin(fwd), end(fwd), pred);
|
||||
|
||||
ProjectedBinaryPredicate<0, 0> projpred{};
|
||||
ProjectionFor<iterator_t<Fwd>, 0> proj{};
|
||||
(void) adjacent_find(fwd, projpred, proj);
|
||||
(void) adjacent_find(begin(fwd), end(fwd), projpred, proj);
|
||||
}
|
||||
};
|
||||
|
||||
template void test_fwd<instantiator>();
|
Загрузка…
Ссылка в новой задаче