aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorswarmer <swarmer@yandex-team.ru>2022-06-10 03:48:46 +0300
committerswarmer <swarmer@yandex-team.ru>2022-06-10 03:48:46 +0300
commit649b24b6e528a274568b079f18aed32b07d1a9f3 (patch)
treee132dbc3ed150e69fb3724a413a4fee3a39d93d4
parent3aa159dd2eff94953b58fd3244e4e3c0969403e6 (diff)
downloadydb-649b24b6e528a274568b079f18aed32b07d1a9f3.tar.gz
[util] AdjacentFind + AdjacentFindBy
ref:76575abc5c39caf128339b56115c217c15766b51
-rw-r--r--util/generic/algorithm.h28
-rw-r--r--util/generic/algorithm_ut.cpp30
2 files changed, 58 insertions, 0 deletions
diff --git a/util/generic/algorithm.h b/util/generic/algorithm.h
index bce242679f..d3b198fb23 100644
--- a/util/generic/algorithm.h
+++ b/util/generic/algorithm.h
@@ -714,6 +714,34 @@ constexpr std::pair<It, It> EqualRange(It begin, It end, const Val& val, Comp co
return std::equal_range(begin, end, val, comp);
}
+template <class TContainer>
+constexpr auto AdjacentFind(const 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) {
+ using std::begin;
+ using std::end;
+ return std::adjacent_find(begin(c), end(c), comp);
+}
+
+namespace NPrivate {
+ template <class TForwardIterator, class TGetKey>
+ constexpr TForwardIterator AdjacentFindBy(TForwardIterator begin, TForwardIterator end, const TGetKey& getKey) {
+ return std::adjacent_find(begin, end, [&](auto&& left, auto&& right) { return getKey(left) == getKey(right); });
+ }
+}
+
+template <class TContainer, class TGetKey>
+constexpr auto AdjacentFindBy(const TContainer& c, const TGetKey& getKey) {
+ using std::begin;
+ using std::end;
+ return ::NPrivate::AdjacentFindBy(begin(c), end(c), getKey);
+}
+
template <class ForwardIt>
constexpr bool IsSorted(ForwardIt begin, ForwardIt end) {
return std::is_sorted(begin, end);
diff --git a/util/generic/algorithm_ut.cpp b/util/generic/algorithm_ut.cpp
index 72b326ebbe..4cdeef0a80 100644
--- a/util/generic/algorithm_ut.cpp
+++ b/util/generic/algorithm_ut.cpp
@@ -416,6 +416,36 @@ Y_UNIT_TEST_SUITE(TAlgorithm) {
}
}
+ Y_UNIT_TEST(AdjacentFindTest) {
+ TVector<int> v0;
+ UNIT_ASSERT_EQUAL(AdjacentFind(v0), v0.end());
+
+ TVector<int> v1 = {1};
+ UNIT_ASSERT_EQUAL(AdjacentFind(v1), v1.end());
+
+ const int v2[] = {8, 7, 6, 6, 5, 5, 5, 4, 3, 2, 1};
+ UNIT_ASSERT_EQUAL(AdjacentFind(v2), std::begin(v2) + 2);
+
+ TVector<TStringBuf> v3 = {"six", "five", "four", "three", "two", "one"};
+ UNIT_ASSERT_EQUAL(AdjacentFind(v3), v3.end());
+ }
+
+ Y_UNIT_TEST(AdjacentFindByTest) {
+ TVector<int> v0;
+ UNIT_ASSERT_EQUAL(AdjacentFindBy(v0, std::negate<int>()), v0.end());
+
+ TVector<int> v1 = {1};
+ UNIT_ASSERT_EQUAL(AdjacentFindBy(v1, std::negate<int>()), v1.end());
+
+ const int v2[] = {8, 7, 6, 6, 5, 5, 5, 4, 3, 2, 1};
+ UNIT_ASSERT_EQUAL(AdjacentFindBy(v2, std::negate<int>()), std::begin(v2) + 2);
+ UNIT_ASSERT_EQUAL(AdjacentFindBy(v2, [](const auto& e) { return e / 8; }), std::begin(v2) + 1);
+
+ 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);
+ }
+
Y_UNIT_TEST(IsSortedTest) {
TVector<int> v0;
UNIT_ASSERT_VALUES_EQUAL(IsSorted(v0.begin(), v0.end()), true);