https://github.com/denzor200 updated https://github.com/llvm/llvm-project/pull/171666
>From 8a87ecbc298fbc62d8b0d82d677a87ac074ea6c7 Mon Sep 17 00:00:00 2001 From: denzor200 <[email protected]> Date: Wed, 10 Dec 2025 21:12:34 +0300 Subject: [PATCH 1/4] Add llvm::search and llvm::adjacent_find --- .../clang-tidy/llvm/UseRangesCheck.cpp | 5 +- llvm/include/llvm/ADT/STLExtras.h | 27 +++ llvm/unittests/ADT/STLExtrasTest.cpp | 156 ++++++++++++++++++ 3 files changed, 186 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp index 2c7a644b7a793..420cf63c033a1 100644 --- a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp @@ -69,11 +69,12 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { "is_sorted", "min_element", "max_element", "binary_search", "lower_bound", "upper_bound", - "unique", "uninitialized_copy"}); + "unique", "uninitialized_copy", + "adjacent_find"}); // Two range algorithms AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(TwoSig), - {"equal", "mismatch", "includes"}); + {"equal", "mismatch", "includes", "search"}); return Results; } diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index af0e4a36be1b1..560edbee5ac1c 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1778,6 +1778,33 @@ OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) { return std::copy_if(adl_begin(Range), adl_end(Range), Out, P); } +/// Wrapper for std::search. +template <typename R1, typename R2> +auto search(R1 &&Range1, R2 &&Range2) { + return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), + adl_end(Range2)); +} + +/// Wrapper for std::search. +template <typename R1, typename R2, typename BinaryPredicate> +auto search(R1 &&Range1, R2 &&Range2, BinaryPredicate P) { + return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), + adl_end(Range2), P); +} + +/// Wrapper for std::adjacent_find. +template <typename R> +auto adjacent_find(R &&Range) { + return std::adjacent_find(adl_begin(Range), adl_end(Range)); +} + +/// Wrapper for std::adjacent_find. +template <typename R, typename BinaryPredicate> +auto adjacent_find(R &&Range, BinaryPredicate P) { + return std::adjacent_find(adl_begin(Range), adl_end(Range), + P); +} + /// Return the single value in \p Range that satisfies /// \p P(<member of \p Range> *, AllowRepeats)->T * returning nullptr /// when no values or multiple values were found. diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 85567775e4ebd..73127bf9cf64c 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -1699,4 +1699,160 @@ struct Bar {}; static_assert(is_incomplete_v<Foo>, "Foo is incomplete"); static_assert(!is_incomplete_v<Bar>, "Bar is defined"); +TEST(STLExtrasTest, Search) { + // Test finding a subsequence in the middle + std::vector<int> Haystack = {1, 2, 3, 4, 5, 6, 7, 8}; + std::vector<int> Needle = {4, 5, 6}; + auto It = llvm::search(Haystack, Needle); + EXPECT_NE(It, Haystack.end()); + EXPECT_EQ(It, Haystack.begin() + 3); + EXPECT_THAT(std::vector<int>(It, It + 3), ElementsAre(4, 5, 6)); + + // Test finding at the beginning + std::vector<int> Needle2 = {1, 2, 3}; + auto It2 = llvm::search(Haystack, Needle2); + EXPECT_NE(It2, Haystack.end()); + EXPECT_EQ(It2, Haystack.begin()); + EXPECT_THAT(std::vector<int>(It2, It2 + 3), ElementsAre(1, 2, 3)); + + // Test finding at the end + std::vector<int> Needle3 = {6, 7, 8}; + auto It3 = llvm::search(Haystack, Needle3); + EXPECT_NE(It3, Haystack.end()); + EXPECT_EQ(It3, Haystack.begin() + 5); + EXPECT_THAT(std::vector<int>(It3, It3 + 3), ElementsAre(6, 7, 8)); + + // Test not finding a subsequence + std::vector<int> Needle4 = {9, 10, 11}; + auto It4 = llvm::search(Haystack, Needle4); + EXPECT_EQ(It4, Haystack.end()); + + // Test with empty needle (should find at beginning) + std::vector<int> EmptyNeedle; + auto It5 = llvm::search(Haystack, EmptyNeedle); + EXPECT_NE(It5, Haystack.end()); + EXPECT_EQ(It5, Haystack.begin()); + + // Test with empty haystack + std::vector<int> EmptyHaystack; + auto It6 = llvm::search(EmptyHaystack, Needle); + EXPECT_EQ(It6, EmptyHaystack.end()); + // Test with both empty + auto It7 = llvm::search(EmptyHaystack, EmptyNeedle); + EXPECT_EQ(It7, EmptyHaystack.end()); + EXPECT_EQ(It7, EmptyHaystack.begin()); + + // Test with predicate version + std::vector<int> Haystack2 = {10, 20, 30, 40, 50}; + std::vector<int> Needle5 = {20, 30}; + std::vector<int> Needle6 = {200, 300}; + auto It8 = llvm::search(Haystack2, Needle5, + [](int a, int b) { return a == b; }); + EXPECT_NE(It8, Haystack2.end()); + EXPECT_EQ(It8, Haystack2.begin() + 1); + + // Test with predicate that doesn't match + auto It9 = llvm::search(Haystack2, Needle6, + [](int a, int b) { return a == b; }); + EXPECT_EQ(It9, Haystack2.end()); + + // Test with StringRef + StringRef Str = "Hello, World!"; + StringRef Sub = "World"; + auto It10 = llvm::search(Str, Sub); + EXPECT_NE(It10, Str.end()); + EXPECT_EQ(*It10, 'W'); + + // Test with ArrayRef + ArrayRef<int> ArrRef = Haystack; + ArrayRef<int> NeedleRef = Needle; + auto It11 = llvm::search(ArrRef, NeedleRef); + EXPECT_NE(It11, ArrRef.end()); + EXPECT_EQ(It11, ArrRef.begin() + 3); +} + +TEST(STLExtrasTest, AdjacentFind) { + // Test finding adjacent equal elements + std::vector<int> V = {1, 2, 3, 3, 4, 5}; + auto It = llvm::adjacent_find(V); + EXPECT_NE(It, V.end()); + EXPECT_EQ(It, V.begin() + 2); + EXPECT_EQ(*It, 3); + EXPECT_EQ(*(It + 1), 3); + + // Test not finding adjacent equal elements + std::vector<int> V2 = {1, 2, 3, 4, 5}; + auto It2 = llvm::adjacent_find(V2); + EXPECT_EQ(It2, V2.end()); + + // Test finding at the beginning + std::vector<int> V3 = {1, 1, 2, 3, 4}; + auto It3 = llvm::adjacent_find(V3); + EXPECT_NE(It3, V3.end()); + EXPECT_EQ(It3, V3.begin()); + EXPECT_EQ(*It3, 1); + EXPECT_EQ(*(It3 + 1), 1); + + // Test finding at the end + std::vector<int> V4 = {1, 2, 3, 4, 5, 5}; + auto It4 = llvm::adjacent_find(V4); + EXPECT_NE(It4, V4.end()); + EXPECT_EQ(It4, V4.begin() + 4); + EXPECT_EQ(*It4, 5); + EXPECT_EQ(*(It4 + 1), 5); + + // Test with empty range + std::vector<int> Empty; + auto It5 = llvm::adjacent_find(Empty); + EXPECT_EQ(It5, Empty.end()); + + // Test with single element + std::vector<int> Single = {42}; + auto It6 = llvm::adjacent_find(Single); + EXPECT_EQ(It6, Single.end()); + + // Test with predicate version - finding adjacent elements that satisfy predicate + std::vector<int> V5 = {1, 2, 4, 3, 5, 6}; + auto It7 = llvm::adjacent_find(V5, [](int a, int b) { return a > b; }); + EXPECT_NE(It7, V5.end()); + EXPECT_EQ(It7, V5.begin() + 2); + EXPECT_EQ(*It7, 4); + EXPECT_EQ(*(It7 + 1), 3); + + // Test with predicate that doesn't match + std::vector<int> V6 = {1, 2, 3, 4, 5}; + auto It8 = llvm::adjacent_find(V6, [](int a, int b) { return a > b; }); + EXPECT_EQ(It8, V6.end()); + + // Test with predicate finding equal elements + std::vector<int> V7 = {1, 2, 3, 3, 4}; + auto It9 = llvm::adjacent_find(V7, [](int a, int b) { return a == b; }); + EXPECT_NE(It9, V7.end()); + EXPECT_EQ(It9, V7.begin() + 2); + + // Test with StringRef + StringRef Str = "Helo"; + auto It10 = llvm::adjacent_find(Str); + EXPECT_EQ(It10, Str.end()); + + StringRef Str2 = "Helllo"; + auto It11 = llvm::adjacent_find(Str2); + EXPECT_NE(It11, Str2.end()); + EXPECT_EQ(*It11, 'l'); + EXPECT_EQ(*(It11 + 1), 'l'); + + // Test with ArrayRef + ArrayRef<int> ArrRef = V; + auto It12 = llvm::adjacent_find(ArrRef); + EXPECT_NE(It12, ArrRef.end()); + EXPECT_EQ(It12, ArrRef.begin() + 2); + + // Test with list (non-random access iterator) + std::list<int> L = {1, 2, 3, 3, 4, 5}; + auto It13 = llvm::adjacent_find(L); + EXPECT_NE(It13, L.end()); + EXPECT_EQ(*It13, 3); + EXPECT_EQ(*std::next(It13), 3); +} + } // namespace >From cd55badfb2f491a4621776a2ba1b3eece7d27d81 Mon Sep 17 00:00:00 2001 From: denzor200 <[email protected]> Date: Wed, 10 Dec 2025 22:08:53 +0300 Subject: [PATCH 2/4] format --- .../clang-tidy/llvm/UseRangesCheck.cpp | 26 +++++++++---------- llvm/include/llvm/ADT/STLExtras.h | 9 +++---- llvm/unittests/ADT/STLExtrasTest.cpp | 11 ++++---- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp index 420cf63c033a1..5e7392b09fb33 100644 --- a/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/UseRangesCheck.cpp @@ -57,19 +57,19 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { // Single range algorithms AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(SingleSig), - {"all_of", "any_of", - "none_of", "for_each", - "find", "find_if", - "find_if_not", "fill", - "count", "count_if", - "copy", "copy_if", - "transform", "replace", - "remove_if", "stable_sort", - "partition", "partition_point", - "is_sorted", "min_element", - "max_element", "binary_search", - "lower_bound", "upper_bound", - "unique", "uninitialized_copy", + {"all_of", "any_of", + "none_of", "for_each", + "find", "find_if", + "find_if_not", "fill", + "count", "count_if", + "copy", "copy_if", + "transform", "replace", + "remove_if", "stable_sort", + "partition", "partition_point", + "is_sorted", "min_element", + "max_element", "binary_search", + "lower_bound", "upper_bound", + "unique", "uninitialized_copy", "adjacent_find"}); // Two range algorithms diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 560edbee5ac1c..9b358b0ac39f6 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1779,8 +1779,7 @@ OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) { } /// Wrapper for std::search. -template <typename R1, typename R2> -auto search(R1 &&Range1, R2 &&Range2) { +template <typename R1, typename R2> auto search(R1 &&Range1, R2 &&Range2) { return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), adl_end(Range2)); } @@ -1793,16 +1792,14 @@ auto search(R1 &&Range1, R2 &&Range2, BinaryPredicate P) { } /// Wrapper for std::adjacent_find. -template <typename R> -auto adjacent_find(R &&Range) { +template <typename R> auto adjacent_find(R &&Range) { return std::adjacent_find(adl_begin(Range), adl_end(Range)); } /// Wrapper for std::adjacent_find. template <typename R, typename BinaryPredicate> auto adjacent_find(R &&Range, BinaryPredicate P) { - return std::adjacent_find(adl_begin(Range), adl_end(Range), - P); + return std::adjacent_find(adl_begin(Range), adl_end(Range), P); } /// Return the single value in \p Range that satisfies diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 73127bf9cf64c..e91412f88e315 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -1746,14 +1746,14 @@ TEST(STLExtrasTest, Search) { std::vector<int> Haystack2 = {10, 20, 30, 40, 50}; std::vector<int> Needle5 = {20, 30}; std::vector<int> Needle6 = {200, 300}; - auto It8 = llvm::search(Haystack2, Needle5, - [](int a, int b) { return a == b; }); + auto It8 = + llvm::search(Haystack2, Needle5, [](int a, int b) { return a == b; }); EXPECT_NE(It8, Haystack2.end()); EXPECT_EQ(It8, Haystack2.begin() + 1); // Test with predicate that doesn't match - auto It9 = llvm::search(Haystack2, Needle6, - [](int a, int b) { return a == b; }); + auto It9 = + llvm::search(Haystack2, Needle6, [](int a, int b) { return a == b; }); EXPECT_EQ(It9, Haystack2.end()); // Test with StringRef @@ -1811,7 +1811,8 @@ TEST(STLExtrasTest, AdjacentFind) { auto It6 = llvm::adjacent_find(Single); EXPECT_EQ(It6, Single.end()); - // Test with predicate version - finding adjacent elements that satisfy predicate + // Test with predicate version - finding adjacent elements that satisfy + // predicate std::vector<int> V5 = {1, 2, 4, 3, 5, 6}; auto It7 = llvm::adjacent_find(V5, [](int a, int b) { return a > b; }); EXPECT_NE(It7, V5.end()); >From caba615a43a0d0209bb99d87d47c910a3956d9c6 Mon Sep 17 00:00:00 2001 From: denzor200 <[email protected]> Date: Sat, 20 Dec 2025 00:28:07 +0300 Subject: [PATCH 3/4] review --- llvm/include/llvm/ADT/STLExtras.h | 12 +++++--- llvm/unittests/ADT/STLExtrasTest.cpp | 46 ++++++++++++++-------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index dd71533364869..462a6466b3948 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1790,25 +1790,29 @@ OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) { return std::copy_if(adl_begin(Range), adl_end(Range), Out, P); } -/// Wrapper for std::search. +/// Provide wrappers to std::search which searches for the first occurrence of +/// Range2 within Range1. template <typename R1, typename R2> auto search(R1 &&Range1, R2 &&Range2) { return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), adl_end(Range2)); } -/// Wrapper for std::search. +/// Provide wrappers to std::search which searches for the first occurrence of +/// Range2 within Range1 using predicate `P`. template <typename R1, typename R2, typename BinaryPredicate> auto search(R1 &&Range1, R2 &&Range2, BinaryPredicate P) { return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), adl_end(Range2), P); } -/// Wrapper for std::adjacent_find. +/// Provide wrappers to std::adjacent_find which finds the first pair of +/// adjacent elements that are equal. template <typename R> auto adjacent_find(R &&Range) { return std::adjacent_find(adl_begin(Range), adl_end(Range)); } -/// Wrapper for std::adjacent_find. +/// Provide wrappers to std::adjacent_find which finds the first pair of +/// adjacent elements that are satisfy `P`. template <typename R, typename BinaryPredicate> auto adjacent_find(R &&Range, BinaryPredicate P) { return std::adjacent_find(adl_begin(Range), adl_end(Range), P); diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 96031276b4716..c712df11d382e 100644 --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -1759,7 +1759,7 @@ static_assert(is_incomplete_v<Foo>, "Foo is incomplete"); static_assert(!is_incomplete_v<Bar>, "Bar is defined"); TEST(STLExtrasTest, Search) { - // Test finding a subsequence in the middle + // Test finding a subsequence in the middle. std::vector<int> Haystack = {1, 2, 3, 4, 5, 6, 7, 8}; std::vector<int> Needle = {4, 5, 6}; auto It = llvm::search(Haystack, Needle); @@ -1767,41 +1767,41 @@ TEST(STLExtrasTest, Search) { EXPECT_EQ(It, Haystack.begin() + 3); EXPECT_THAT(std::vector<int>(It, It + 3), ElementsAre(4, 5, 6)); - // Test finding at the beginning + // Test finding at the beginning. std::vector<int> Needle2 = {1, 2, 3}; auto It2 = llvm::search(Haystack, Needle2); EXPECT_NE(It2, Haystack.end()); EXPECT_EQ(It2, Haystack.begin()); EXPECT_THAT(std::vector<int>(It2, It2 + 3), ElementsAre(1, 2, 3)); - // Test finding at the end + // Test finding at the end. std::vector<int> Needle3 = {6, 7, 8}; auto It3 = llvm::search(Haystack, Needle3); EXPECT_NE(It3, Haystack.end()); EXPECT_EQ(It3, Haystack.begin() + 5); EXPECT_THAT(std::vector<int>(It3, It3 + 3), ElementsAre(6, 7, 8)); - // Test not finding a subsequence + // Test not finding a subsequence. std::vector<int> Needle4 = {9, 10, 11}; auto It4 = llvm::search(Haystack, Needle4); EXPECT_EQ(It4, Haystack.end()); - // Test with empty needle (should find at beginning) + // Test with empty needle (should find at beginning). std::vector<int> EmptyNeedle; auto It5 = llvm::search(Haystack, EmptyNeedle); EXPECT_NE(It5, Haystack.end()); EXPECT_EQ(It5, Haystack.begin()); - // Test with empty haystack + // Test with empty haystack. std::vector<int> EmptyHaystack; auto It6 = llvm::search(EmptyHaystack, Needle); EXPECT_EQ(It6, EmptyHaystack.end()); - // Test with both empty + // Test with both empty. auto It7 = llvm::search(EmptyHaystack, EmptyNeedle); EXPECT_EQ(It7, EmptyHaystack.end()); EXPECT_EQ(It7, EmptyHaystack.begin()); - // Test with predicate version + // Test with predicate version. std::vector<int> Haystack2 = {10, 20, 30, 40, 50}; std::vector<int> Needle5 = {20, 30}; std::vector<int> Needle6 = {200, 300}; @@ -1810,19 +1810,19 @@ TEST(STLExtrasTest, Search) { EXPECT_NE(It8, Haystack2.end()); EXPECT_EQ(It8, Haystack2.begin() + 1); - // Test with predicate that doesn't match + // Test with predicate that doesn't match. auto It9 = llvm::search(Haystack2, Needle6, [](int a, int b) { return a == b; }); EXPECT_EQ(It9, Haystack2.end()); - // Test with StringRef + // Test with StringRef. StringRef Str = "Hello, World!"; StringRef Sub = "World"; auto It10 = llvm::search(Str, Sub); EXPECT_NE(It10, Str.end()); EXPECT_EQ(*It10, 'W'); - // Test with ArrayRef + // Test with ArrayRef. ArrayRef<int> ArrRef = Haystack; ArrayRef<int> NeedleRef = Needle; auto It11 = llvm::search(ArrRef, NeedleRef); @@ -1831,7 +1831,7 @@ TEST(STLExtrasTest, Search) { } TEST(STLExtrasTest, AdjacentFind) { - // Test finding adjacent equal elements + // Test finding adjacent equal elements. std::vector<int> V = {1, 2, 3, 3, 4, 5}; auto It = llvm::adjacent_find(V); EXPECT_NE(It, V.end()); @@ -1839,12 +1839,12 @@ TEST(STLExtrasTest, AdjacentFind) { EXPECT_EQ(*It, 3); EXPECT_EQ(*(It + 1), 3); - // Test not finding adjacent equal elements + // Test not finding adjacent equal elements. std::vector<int> V2 = {1, 2, 3, 4, 5}; auto It2 = llvm::adjacent_find(V2); EXPECT_EQ(It2, V2.end()); - // Test finding at the beginning + // Test finding at the beginning. std::vector<int> V3 = {1, 1, 2, 3, 4}; auto It3 = llvm::adjacent_find(V3); EXPECT_NE(It3, V3.end()); @@ -1852,7 +1852,7 @@ TEST(STLExtrasTest, AdjacentFind) { EXPECT_EQ(*It3, 1); EXPECT_EQ(*(It3 + 1), 1); - // Test finding at the end + // Test finding at the end. std::vector<int> V4 = {1, 2, 3, 4, 5, 5}; auto It4 = llvm::adjacent_find(V4); EXPECT_NE(It4, V4.end()); @@ -1860,18 +1860,18 @@ TEST(STLExtrasTest, AdjacentFind) { EXPECT_EQ(*It4, 5); EXPECT_EQ(*(It4 + 1), 5); - // Test with empty range + // Test with empty range. std::vector<int> Empty; auto It5 = llvm::adjacent_find(Empty); EXPECT_EQ(It5, Empty.end()); - // Test with single element + // Test with single element. std::vector<int> Single = {42}; auto It6 = llvm::adjacent_find(Single); EXPECT_EQ(It6, Single.end()); // Test with predicate version - finding adjacent elements that satisfy - // predicate + // predicate. std::vector<int> V5 = {1, 2, 4, 3, 5, 6}; auto It7 = llvm::adjacent_find(V5, [](int a, int b) { return a > b; }); EXPECT_NE(It7, V5.end()); @@ -1879,18 +1879,18 @@ TEST(STLExtrasTest, AdjacentFind) { EXPECT_EQ(*It7, 4); EXPECT_EQ(*(It7 + 1), 3); - // Test with predicate that doesn't match + // Test with predicate that doesn't match. std::vector<int> V6 = {1, 2, 3, 4, 5}; auto It8 = llvm::adjacent_find(V6, [](int a, int b) { return a > b; }); EXPECT_EQ(It8, V6.end()); - // Test with predicate finding equal elements + // Test with predicate finding equal elements. std::vector<int> V7 = {1, 2, 3, 3, 4}; auto It9 = llvm::adjacent_find(V7, [](int a, int b) { return a == b; }); EXPECT_NE(It9, V7.end()); EXPECT_EQ(It9, V7.begin() + 2); - // Test with StringRef + // Test with StringRef. StringRef Str = "Helo"; auto It10 = llvm::adjacent_find(Str); EXPECT_EQ(It10, Str.end()); @@ -1901,13 +1901,13 @@ TEST(STLExtrasTest, AdjacentFind) { EXPECT_EQ(*It11, 'l'); EXPECT_EQ(*(It11 + 1), 'l'); - // Test with ArrayRef + // Test with ArrayRef. ArrayRef<int> ArrRef = V; auto It12 = llvm::adjacent_find(ArrRef); EXPECT_NE(It12, ArrRef.end()); EXPECT_EQ(It12, ArrRef.begin() + 2); - // Test with list (non-random access iterator) + // Test with list (non-random access iterator). std::list<int> L = {1, 2, 3, 3, 4, 5}; auto It13 = llvm::adjacent_find(L); EXPECT_NE(It13, L.end()); >From 29d30b9df325b0947e3de8c3271d885a6ebe1d32 Mon Sep 17 00:00:00 2001 From: denzor200 <[email protected]> Date: Sat, 20 Dec 2025 01:01:43 +0300 Subject: [PATCH 4/4] review --- llvm/include/llvm/ADT/STLExtras.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 462a6466b3948..7b0304fd99463 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1792,6 +1792,8 @@ OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) { /// Provide wrappers to std::search which searches for the first occurrence of /// Range2 within Range1. +/// \returns An iterator to the start of Range2 within Range1 if found, or +/// the end iterator of Range1 if not found. template <typename R1, typename R2> auto search(R1 &&Range1, R2 &&Range2) { return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), adl_end(Range2)); @@ -1799,6 +1801,8 @@ template <typename R1, typename R2> auto search(R1 &&Range1, R2 &&Range2) { /// Provide wrappers to std::search which searches for the first occurrence of /// Range2 within Range1 using predicate `P`. +/// \returns An iterator to the start of Range2 within Range1 if found, or +/// the end iterator of Range1 if not found. template <typename R1, typename R2, typename BinaryPredicate> auto search(R1 &&Range1, R2 &&Range2, BinaryPredicate P) { return std::search(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), @@ -1807,12 +1811,16 @@ auto search(R1 &&Range1, R2 &&Range2, BinaryPredicate P) { /// Provide wrappers to std::adjacent_find which finds the first pair of /// adjacent elements that are equal. +/// \returns An iterator to the first adjacent element within Range1 if found, +/// or the end iterator of Range1 if not found. template <typename R> auto adjacent_find(R &&Range) { return std::adjacent_find(adl_begin(Range), adl_end(Range)); } /// Provide wrappers to std::adjacent_find which finds the first pair of /// adjacent elements that are satisfy `P`. +/// \returns An iterator to the first adjacent element within Range1 if found, +/// or the end iterator of Range1 if not found. template <typename R, typename BinaryPredicate> auto adjacent_find(R &&Range, BinaryPredicate P) { return std::adjacent_find(adl_begin(Range), adl_end(Range), P); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
