Namespaces
Variants
Actions

std::ranges::binary_search

From cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
Algorithm library
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Numeric operations
 
Constrained algorithms
All names in this menu belong to namespace std::ranges
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
       
       
binary_search
    
Set operations (on sorted ranges)
Heap operations
     
         
Minimum/maximum operations
       
       
Permutation operations
Fold operations
(C++23)
(C++23)  
(C++23)
(C++23)  
Defined in header <algorithm>
Call signature
(1)
template< std::forward_iterator I, std::sentinel_for <I> S,

          class T, class Proj = std::identity,
          std::indirect_strict_weak_order
              <const T*, std::projected <I, Proj>> Comp = ranges::less >
constexpr bool binary_search( I first, S last, const T& value,

                              Comp comp = {}, Proj proj = {} );
(since C++20)
(until C++26)
template< std::forward_iterator I, std::sentinel_for <I> S,

          class Proj = std::identity,
          class T = std::projected_value_t<I, Proj>,
          std::indirect_strict_weak_order
              <const T*, std::projected <I, Proj>> Comp = ranges::less >
constexpr bool binary_search( I first, S last, const T& value,

                              Comp comp = {}, Proj proj = {} );
(since C++26)
(2)
template< ranges::forward_range R,

          class T, class Proj = std::identity,
          std::indirect_strict_weak_order
              <const T*, std::projected <ranges::iterator_t <R>,
                                        Proj>> Comp = ranges::less >
constexpr bool binary_search( R&& r, const T& value,

                              Comp comp = {}, Proj proj = {} );
(since C++20)
(until C++26)
template< ranges::forward_range R,

          class Proj = std::identity,
          class T = std::projected_value_t<ranges::iterator_t <R>, Proj>,
          std::indirect_strict_weak_order
              <const T*, std::projected <ranges::iterator_t <R>,
                                        Proj>> Comp = ranges::less >
constexpr bool binary_search( R&& r, const T& value,

                              Comp comp = {}, Proj proj = {} );
(since C++26)
1) Checks if a projected element equivalent to value appears within the range [firstlast).
2) Same as (1), but uses r as the source range, as if using ranges::begin (r) as first and ranges::end (r) as last.

For ranges::binary_search to succeed, the range [firstlast) must be at least partially ordered with respect to value, i.e. it must satisfy all of the following requirements:

  • partitioned with respect to std::invoke (comp, std::invoke (proj, element), value) (that is, all projected elements for which the expression is true precedes all elements for which the expression is false).
  • partitioned with respect to !std::invoke (comp, value, std::invoke (proj, element)).
  • for all elements, if std::invoke (comp, std::invoke (proj, element), value) is true then !std::invoke (comp, value, std::invoke (proj, element)) is also true.

A fully-sorted range meets these criteria.

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

[edit] Parameters

first, last - the iterator-sentinel pair defining the range of elements to examine
r - the range of elements to examine
value - value to compare the elements to
comp - comparison function to apply to the projected elements
proj - projection to apply to the elements

[edit] Return value

true if an element equal to value is found, false otherwise.

[edit] Complexity

The number of comparisons and projections performed is logarithmic in the distance between first and last (at most log2(last - first) + O(1) comparisons and projections). However, for iterator-sentinel pair that does not model std::random_access_iterator , number of iterator increments is linear.

[edit] Notes

std::ranges::binary_search doesn't return an iterator to the found element when an element whose projection equals value is found. If an iterator is desired, std::ranges::lower_bound should be used instead.

Feature-test macro Value Std Feature
__cpp_lib_algorithm_default_value_type 202403 (C++26) List-initialization for algorithms (1,2)

[edit] Possible implementation

struct binary_search_fn
{
 template<std::forward_iterator I, std::sentinel_for <I> S,
 class Proj = std::identity, class T = std::projected_value_t<I, Proj>,
 std::indirect_strict_weak_order
 <const T*, std::projected <I, Proj>> Comp = ranges::less >
 constexpr bool operator()(I first, S last, const T& value,
 Comp comp = {}, Proj proj = {}) const
 {
 auto x = ranges::lower_bound (first, last, value, comp, proj);
 return (!(x == last) && !(std::invoke (comp, value, std::invoke (proj, *x))));
 }
 
 template<ranges::forward_range R, class Proj = std::identity,
 class T = std::projected_value_t<ranges::iterator_t <R>, Proj>,
 std::indirect_strict_weak_order
 <const T*, std::projected <ranges::iterator_t <R>,
 Proj>> Comp = ranges::less >
 constexpr bool operator()(R&& r, const T& value, Comp comp = {}, Proj proj = {}) const
 {
 return (*this)(ranges::begin (r), ranges::end (r), value,
 std::move(comp), std::move(proj));
 }
};
 
inline constexpr binary_search_fn binary_search;

[edit] Example

Run this code
#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <ranges>
#include <vector>
 
int main()
{
 constexpr static auto haystack = {1, 3, 4, 5, 9};
 static_assert(std::ranges::is_sorted (haystack));
 
 for (const int needle : std::views::iota (1)
 | std::views::take (3))
 {
 std::cout << "Searching for " << needle << ": ";
 std::ranges::binary_search(haystack, needle)
 ? std::cout << "found " << needle << '\n'
 : std::cout << "no dice!\n";
 }
 
 using CD = std::complex <double>;
 std::vector <CD> nums{{1, 1}, {2, 3}, {4, 2}, {4, 3}};
 auto cmpz = [](CD x, CD y){ return abs(x) < abs(y); };
 #ifdef __cpp_lib_algorithm_default_value_type
 assert (std::ranges::binary_search(nums, {4, 2}, cmpz));
 #else
 assert (std::ranges::binary_search(nums, CD{4, 2}, cmpz));
 #endif
}

Output:

Searching for 1: found 1
Searching for 2: no dice!
Searching for 3: found 3

[edit] See also

returns range of elements matching a specific key
(algorithm function object)[edit]
returns an iterator to the first element not less than the given value
(algorithm function object)[edit]
returns an iterator to the first element greater than a certain value
(algorithm function object)[edit]
checks if the range contains the given element or subrange
(algorithm function object)[edit]
determines if an element exists in a partially-ordered range
(function template) [edit]

AltStyle によって変換されたページ (->オリジナル) /