diff options
author | swarmer <swarmer@yandex-team.com> | 2022-07-19 10:51:56 +0300 |
---|---|---|
committer | swarmer <swarmer@yandex-team.com> | 2022-07-19 10:51:56 +0300 |
commit | c64ee34d9c321fa796868ddca03dddb174704107 (patch) | |
tree | 6d1c404eec735f72b689e4127825e201897d86ac | |
parent | 69194c8f03984728c5a08d32026aab02c0b25f7a (diff) | |
download | ydb-c64ee34d9c321fa796868ddca03dddb174704107.tar.gz |
[util] prefer non-const begin/end method for non-const containers in AdjacentFind* functions
AdjacentFind и AdjacentFindBy принимали контейнер по константной ссылке и из-за этого возвращали константный итератор.
Стоит для некостантного контейнера возвращать также неконстантный итератор (если он есть).
Это позволит
1. использовать итератор для модификации контейнера;
2. обойти проблему, когда методы `end()` и `cend()`/`std::as_const(…).end()` возвращают итераторы разных типов, которые нельзя сравнивать, либо для которых выбор оператора сравнения неоднозначен.
-rw-r--r-- | util/generic/algorithm.h | 6 | ||||
-rw-r--r-- | util/generic/algorithm_ut.cpp | 20 |
2 files changed, 23 insertions, 3 deletions
diff --git a/util/generic/algorithm.h b/util/generic/algorithm.h index d3b198fb232..70efc506092 100644 --- a/util/generic/algorithm.h +++ b/util/generic/algorithm.h @@ -715,14 +715,14 @@ constexpr std::pair<It, It> EqualRange(It begin, It end, const Val& val, Comp co } template <class TContainer> -constexpr auto AdjacentFind(const TContainer& c) { +constexpr auto AdjacentFind(TContainer&& c) { using std::begin; using std::end; return std::adjacent_find(begin(c), end(c)); } template <class TContainer, class Compare> -constexpr auto AdjacentFind(const TContainer& c, Compare comp) { +constexpr auto AdjacentFind(TContainer&& c, Compare comp) { using std::begin; using std::end; return std::adjacent_find(begin(c), end(c), comp); @@ -736,7 +736,7 @@ namespace NPrivate { } template <class TContainer, class TGetKey> -constexpr auto AdjacentFindBy(const TContainer& c, const TGetKey& getKey) { +constexpr auto AdjacentFindBy(TContainer&& c, const TGetKey& getKey) { using std::begin; using std::end; return ::NPrivate::AdjacentFindBy(begin(c), end(c), getKey); diff --git a/util/generic/algorithm_ut.cpp b/util/generic/algorithm_ut.cpp index 4cdeef0a805..0b411fd84d3 100644 --- a/util/generic/algorithm_ut.cpp +++ b/util/generic/algorithm_ut.cpp @@ -428,6 +428,16 @@ Y_UNIT_TEST_SUITE(TAlgorithm) { TVector<TStringBuf> v3 = {"six", "five", "four", "three", "two", "one"}; UNIT_ASSERT_EQUAL(AdjacentFind(v3), v3.end()); + + TVector<int> v4 = {1, 1, 1, 1, 1}; + for (;;) { + if (auto it = AdjacentFind(v4); it == v4.end()) { + break; + } else { + *it += 1; + } + } + UNIT_ASSERT_VALUES_EQUAL(v4, (TVector<int>{5, 4, 3, 2, 1})); } Y_UNIT_TEST(AdjacentFindByTest) { @@ -444,6 +454,16 @@ Y_UNIT_TEST_SUITE(TAlgorithm) { TVector<TStringBuf> v3 = {"six", "five", "four", "three", "two", "one"}; UNIT_ASSERT_EQUAL(AdjacentFind(v3), v3.end()); UNIT_ASSERT_EQUAL(AdjacentFindBy(v3, std::mem_fn(&TStringBuf::size)), v3.begin() + 1); + + TVector<int> v4 = {101, 201, 301, 401, 501}; + for (;;) { + if (auto it = AdjacentFindBy(v4, [](int a) { return a % 10; }); it == v4.end()) { + break; + } else { + *it += 1; + } + } + UNIT_ASSERT_VALUES_EQUAL(v4, (TVector<int>{105, 204, 303, 402, 501})); } Y_UNIT_TEST(IsSortedTest) { |