std::ranges::equal
std::ranges
Non-modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Modifying sequence operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Partitioning operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sorting operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Binary search operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Set operations (on sorted ranges) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Heap operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Minimum/maximum operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Permutation operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Fold operations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Operations on uninitialized storage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Return types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Defined in header <algorithm>
|
||
Call signature |
||
template
<
std::input_iterator I1, std::sentinel_for
<I1> S1,
std::input_iterator I2, std::sentinel_for
<I2> S2, |
(1) | (since C++20) |
template
<
ranges::input_range R1, ranges::input_range R2,
class Pred =
ranges::equal_to, |
(2) | (since C++20) |
[
first1
,
last1
)
are equal to the projected values of the range [
first2,
last2)
, and false
Two ranges are considered equal if they have the same number of elements and every pair of corresponding projected elements satisfies pred. That is, std::invoke (pred, std::invoke (proj1, *first1), std::invoke (proj2, *first2) ) returns true
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
Parameters
first1, last1 | - | an iterator-sentinel pair denoting the first range of the elements to compare |
r1 | - | the first range of the elements to compare |
first2, last2 | - | an iterator-sentinel pair denoting the second range of the elements to compare |
r2 | - | the second range of the elements to compare |
pred | - | predicate to apply to the projected elements |
proj1 | - | projection to apply to the first range of elements |
proj2 | - | projection to apply to the second range of elements |
Return value
If the length of the range
[
first1
,
last1
)
does not equal the length of the range [
first2,
last2)
, returns false
If the elements in the two ranges are equal after projection, returns true.
Otherwise returns false.
Notes
ranges::equal
should not be used to compare the ranges formed by the iterators from std::unordered_set, std::unordered_multiset, std::unordered_map, or
std::unordered_multimap
When comparing entire containers or string views for equality, operator== for the corresponding type are usually preferred.
ranges::equal
std::memcmp
Complexity
At most min(last1 - first1, last2 - first2)
However, if S1 and S2 both model std::sized_sentinel_for their respective iterators, and last1 - first1 != last2 - first2
Possible implementation
struct equal_fn { template<std::input_iterator I1, std::sentinel_for<I1> S1, std::input_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 bool operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { if constexpr (std::sized_sentinel_for<S1, I1> and std::sized_sentinel_for<S2, I2>) if (std::ranges::distance(first1, last1) != std::ranges::distance(first2, last2)) return false; for (; first1 != last1; ++first1, (void)++first2) if (!std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) return false; return true; } template<ranges::input_range R1, ranges::input_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 bool operator()(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const { return (*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), std::ref(pred), std::ref(proj1), std::ref(proj2)); } }; inline constexpr equal_fn equal; |
Example
The following code uses ranges::equal to test if a string is a palindrome.
#include <algorithm> #include <iomanip> #include <iostream> #include <ranges> #include <string_view> constexpr bool is_palindrome(const std::string_view s) { namespace views = std::views; auto forward = s | views::take(s.size() / 2); auto backward = s | views::reverse | views::take(s.size() / 2); return std::ranges::equal(forward, backward); } void test(const std::string_view s) { std::cout << std::quoted(s) << " is " << (is_palindrome(s) ? "" : "not ") << "a palindrome\n"; } int main() { test("radar"); test("hello"); static_assert(is_palindrome("ABBA") and not is_palindrome("AC/DC")); }
Output:
"radar" is a palindrome "hello" is not a palindrome
See also
(C++20)(C++20)(C++20)
|
finds the first element satisfying specific criteria (algorithm function object) |
(C++20)
|
returns true if one range is lexicographically less than another (algorithm function object) |
(C++20)
|
finds the first position where two ranges differ (algorithm function object) |
(C++20)
|
searches for the first occurrence of a range of elements (algorithm function object) |
(C++20)
|
returns range of elements matching a specific key (algorithm function object) |
function object implementing x == y (class template) |
|
determines if two sets of elements are the same (function template) |