std::ranges::mismatch() algorithm
- od C++20
- Simplified
- Detailed
// (1)
constexpr mismatch_result<I1, I2>
mismatch( I1 first1, S1 last1, I2 first2, S2 last2,
Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
// (2)
constexpr mismatch_result<ranges::borrowed_iterator_t<R1>,
ranges::borrowed_iterator_t<R2>>
mismatch( R1&& r1, R2&& r2, Pred pred = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );
The type of arguments are generic and have the following constraints:
I1
,I2
-std::input_iterator
S1
,S2
-std::sentinel_for<I>
,std::sentinel_for<I1>
,std::sentinel_for<I2>
R1
,R2
-std::ranges::input_range
Pred
- (none)Proj1
,Proj2
- (none)
The Pred
template arguments has the following default type of std::equal_to
for all overloads.
The Proj1
and Proj2
template arguments have a default type of std::identity
for all overloads.
Additionally, each overload has the following constraints:
- (1) -
indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
- (2) -
indirectly_comparable< ranges::iterator_t<R1>, ranges::iterator_t<R2>, Pred, Proj1, Proj2>
(The std::
namespace was ommitted here for readability)
// (1)
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 mismatch_result<I1, I2>
mismatch( I1 first1, S1 last1, I2 first2, S2 last2,
Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {} );
// (2)
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 mismatch_result<ranges::borrowed_iterator_t<R1>,
ranges::borrowed_iterator_t<R2>>
mismatch( R1&& r1, R2&& r2, Pred pred = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );
With the helper types defined as follows:
template< class I1, class I2 >
using mismatch_result = ranges::in_in_result<I1, I2>;
Returns the first mismatching pair of projected elements from two ranges: one defined by [first1
; last1
) or r1
and another defined by [first2
; last2
) or r2
.
-
(1) Elements are compared using the given binary predicate
p
. -
(2) Same as (1), but uses
r
as the source range, as if usingranges::begin(r)
asfirst
andranges::end(r)
aslast
.
The function-like entities described on this page are niebloids.
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
ranges::mismatch_result
with iterators to the first two non-equal elements.
If no mismatches are found when the comparison reaches last1
or last2
, whichever happens first, the object holds the end iterator and the corresponding iterator from the other range.
Complexity
At most std::min(last1 - first1, last2 - first2)
applications of the predicate and corresponding projections.
Exceptions
(none)
Possible implementation
mismatch(1) and mismatch(2)
struct mismatch_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 std::mismatch_result<I1, I2>
operator()(I1 first1, S1 last1, I2 first2, S2 last2,
Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) const
{
for (; first1 != last1 && first2 != last2; ++first1, (void)++first2)
if (not std::invoke(pred, std::invoke(proj1, *first1),
std::invoke(proj2, *first2)))
break;
return {first1, first2};
}
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 ranges::mismatch_result<ranges::borrowed_iterator_t<R1>,
ranges::borrowed_iterator_t<R2>>
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 mismatch_fn mismatch;
Examples
This program determines the longest substring that is simultaneously found at the very beginning and at the very end of the given string, in reverse order (possibly overlapping).
#include <algorithm>
#include <iostream>
#include <ranges>
#include <string_view>
[[nodiscard]]
constexpr std::string_view mirror_ends(const std::string_view in)
{
const auto end = std::ranges::mismatch(in, in | std::views::reverse).in1;
return {in.cbegin(), end};
}
int main()
{
std::cout << mirror_ends("abXYZba") << '\n'
<< mirror_ends("abca") << '\n'
<< mirror_ends("ABBA") << '\n'
<< mirror_ends("level") << '\n';
using namespace std::literals::string_view_literals;
static_assert("123"sv == mirror_ends("123!@#321"));
static_assert("radar"sv == mirror_ends("radar"));
}
ab
a
ABBA
level
Hover to see the original license.