Spec-Zone.ru › C++

std::ranges::search

Defined in header <algorithm>
Call signature
template< std::forward_iterator I1, std::sentinel_for<I1> S1,
          std::forward_iterator I2, std::sentinel_for<I2> S2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
constexpr ranges::subrange<I1>
    search( I1 first1, S1 last1, I2 first2, S2 last2,
            Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
(1) (since C++20)
template< ranges::forward_range R1, ranges::forward_range R2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::indirectly_comparable
                 <ranges::iterator_t<R1>,
                  ranges::iterator_t<R2>, Pred, Proj1, Proj2>
constexpr ranges::borrowed_subrange_t<R1>
    search( R1&& r1, R2&& r2,
            Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
(2) (since C++20)
template< /*execution-policy*/ Ep,
          std::random_access_iterator I1, std::sized_sentinel_for<I1> S1,
          std::random_access_iterator I2, std::sized_sentinel_for<I2> S2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
ranges::subrange<I1>
    search( Ep&& policy, I1 first1, S1 last1, I2 first2, S2 last2,
            Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
(3) (since C++26)
template< /*execution-policy*/ Ep,
          /*sized-random-access-range*/ R1, /*sized-random-access-range*/ R2,
          class Pred = ranges::equal_to,
          class Proj1 = std::identity, class Proj2 = std::identity >
    requires std::indirectly_comparable
                 <ranges::iterator_t<R1>,
                  ranges::iterator_t<R2>, Pred, Proj1, Proj2>
constexpr ranges::borrowed_subrange_t<R1>
    search( Ep&& policy, R1&& r1, R2&& r2,
            Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
(4) (since C++26)

For the definition of /*execution-policy*/, see this page; for the definition of /*sized-random-access-range*/, see this page.

Searches for the first occurrence of the target range in the source range. The elements (projected by proj1 and proj2 respectively) are compared using the binary predicate pred.

1) The source range is [first1, last1), and the target range is [first2, last2).
2) The source range is r1, and the target range is r2.
3,4) Same as (1,2), but executed according to policy.

The function-like entities described on this page are algorithm function objects (informally known as niebloids), that is:

  • Explicit template argument lists cannot be specified when calling any of them.
  • None of them are visible to argument-dependent lookup.
  • When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.

Parameters

first1, last1 - the iterator-sentinel pair defining the source range
first2, last2 - the iterator-sentinel pair defining the target range
r1 - the source range
r2 - the target range
pred - the predicate to be applied to the (projected) elements
proj1 - the projection to be applied to the elements in the source range
proj2 - the projection to be applied to the elements in the target range
policy - the execution policy to use

Return value

A subrange corresponding to the first occurrence of the target range in the source range.

If the target range is empty or it does not appear in the source range, an empty range is returned.

Complexity

Given

  • \(\scriptsize N_1\)N1 as ranges::distance(first1, last1) or ranges::distance(r1), and
  • \(\scriptsize N_2\)N2 as ranges::distance(first2, last2) or ranges::distance(r2):
1,2) At most \(\scriptsize N_1 \cdot N_2\)N1⋅N2 applications of pred, proj1 and proj2.
3,4) \(\scriptsize \mathcal{O}(N_1 \cdot N_2)\)𝓞(N1⋅N2) applications of pred, proj1 and proj2.

Exceptions

3,4) During the execution process:
  • If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
  • If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).

Possible implementation

struct search_fn
{
    template<std::forward_iterator I1, std::sentinel_for<I1> S1,
             std::forward_iterator I2, std::sentinel_for<I2> S2,
             class Pred = ranges::equal_to,
             class Proj1 = std::identity, class Proj2 = std::identity>
        requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
    constexpr ranges::subrange<I1>
        operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
                   Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        for (;; ++first1)
        {
            I1 it1 = first1;
            for (I2 it2 = first2;; ++it1, ++it2)
            {
                if (it2 == last2)
                    return {first1, it1};
                if (it1 == last1)
                    return {it1, it1};
                if (!std::invoke(pred, std::invoke(proj1, *it1), std::invoke(proj2, *it2)))
                    break;
            }
        }
    }
    
    template<ranges::forward_range R1, ranges::forward_range R2,
             class Pred = ranges::equal_to,
             class Proj1 = std::identity, class Proj2 = std::identity>
        requires std::indirectly_comparable
                     <ranges::iterator_t<R1>,
                      ranges::iterator_t<R2>, Pred, Proj1, Proj2>
    constexpr ranges::borrowed_subrange_t<R1>
        operator()(R1&& r1, R2&& r2,
                   Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
    {
        return (*this)(ranges::begin(r1),
                       ranges::next(ranges::begin(r1), ranges::end(r1)),
                       ranges::begin(r2),
                       ranges::next(ranges::begin(r2), ranges::end(r2)),
                       std::move(pred), std::move(proj1), std::move(proj2));
    }
};

inline constexpr search_fn search{};

Example

#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <string_view>

using namespace std::literals;

void print(int id, const auto& haystack, const auto& needle, const auto& found)
{
    std::cout << id << ") search(\"" << haystack << "\", \"" << needle << "\"); ";
    const auto first = std::distance(haystack.begin(), found.begin());
    const auto last = std::distance(haystack.begin(), found.end());
    if (found.empty())
        std::cout << "not found;";
    else
    {
        std::cout << "found: \"";
        for (const auto x : found)
            std::cout << x;
        std::cout << "\";";
    }
    std::cout << " subrange: {" << first << ", " << last << "}\n";
}

int main()
{
    constexpr auto haystack{"abcd abcd"sv};
    constexpr auto needle{"bcd"sv};
    
    // the search uses iterator pairs begin()/end():
    constexpr auto found1 = std::ranges::search(
        haystack.begin(), haystack.end(),
        needle.begin(), needle.end());
    print(1, haystack, needle, found1);
    
    // the search uses ranges r1, r2:
    constexpr auto found2 = std::ranges::search(haystack, needle);
    print(2, haystack, needle, found2);
    
    // “needle” range is empty:
    constexpr auto none{""sv};
    constexpr auto found3 = std::ranges::search(haystack, none);
    print(3, haystack, none, found3);
    
    // “needle” will not be found:
    constexpr auto awl{"efg"sv};
    constexpr auto found4 = std::ranges::search(haystack, awl);
    print(4, haystack, awl, found4);
    
    // the search uses custom comparator and projections:
    constexpr auto bodkin{"234"sv};
    auto found5 = std::ranges::search(haystack, bodkin,
        [](const int x, const int y) { return x == y; }, // pred
        [](const int x) { return std::toupper(x); }, // proj1
        [](const int y) { return y + 'A' - '1'; }); // proj2
    print(5, haystack, bodkin, found5);
}

Output:

1) search("abcd abcd", "bcd"); found: "bcd"; subrange: {1, 4}
2) search("abcd abcd", "bcd"); found: "bcd"; subrange: {1, 4}
3) search("abcd abcd", ""); not found; subrange: {0, 0}
4) search("abcd abcd", "efg"); not found; subrange: {9, 9}
5) search("abcd abcd", "234"); found: "bcd"; subrange: {1, 4}

See also

search
searches for the first occurrence of a range of elements
(function template)
ranges::search_n
(C++20)
searches for the first occurrence of a number consecutive copies of an element in a range
(algorithm function object)
ranges::adjacent_find
(C++20)
finds the first two adjacent items that are equal (or satisfy a given predicate)
(algorithm function object)
ranges::findranges::find_ifranges::find_if_not
(C++20)(C++20)(C++20)
finds the first element satisfying specific criteria
(algorithm function object)
ranges::find_end
(C++20)
finds the last sequence of elements in a certain range
(algorithm function object)
ranges::find_first_of
(C++20)
searches for any one of a set of elements
(algorithm function object)
ranges::containsranges::contains_subrange
(C++23)(C++23)
checks if the range contains the given element or subrange
(algorithm function object)
ranges::includes
(C++20)
determines if one sequence is a subsequence of another
(algorithm function object)
ranges::mismatch
(C++20)
finds the first position where two ranges differ
(algorithm function object)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/search

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API