std::ranges::contains, std::ranges::contains_subrange
Defined in header <algorithm> |
||
|---|---|---|
| Call signature | ||
template< std::input_iterator I, std::sentinel_for<I> S,
class T, class Proj = std::identity >
requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>,
const T*>
constexpr bool contains( I first, S last, const T& value, Proj proj = {} ); |
(1) | (since C++23) |
template< ranges::input_range R, class T, class Proj = std::identity >
requires std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>,
const T*>
constexpr bool contains( R&& r, const T& value, Proj proj = {} );
|
(2) | (since C++23) |
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 bool contains_subrange( I1 first1, S1 last1,
I2 first2, S2 last2,
Pred pred = {},
Proj1 proj1 = {}, Proj2 proj2 = {} ); |
(3) | (since C++23) |
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 bool contains_subrange( R1&& r1, R2&& r2,
Pred pred = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );
|
(4) | (since C++23) |
r в качестве исходного диапазона, как если бы ranges::begin(r) использовался как first и ranges::end(r) как last.
r1 в качестве первого исходного диапазона и r2 в качестве второго исходного диапазона, как если бы ranges::begin(r1) использовался как first1, ranges::end(r1) как last1, ranges::begin(r2) как first2, и ranges::end(r2) как last2.
Функциональные сущности, описанные на этой странице, являются niebloids, то есть:
- Явные списки шаблонов аргументов не могут быть указаны при вызове любого из них.
- Ни один из них не виден для поиска зависимых от аргументов.
- Если любой из них найден нормальным поиском без указания имени функции, поиск зависимых от аргументов заблокирован.
На практике они могут быть реализованы в виде объектов-функций или с использованием специальных расширений компилятора.
Параметры
| first, last | - | диапазон элементов для проверки |
| r | - | диапазон элементов для проверки |
| value | - | значение для сравнения с элементами |
| pred | - | предикат для применения к спроектированным элементам |
| proj | - | проекция для применения к элементам |
Возвращаемое значение
ranges::find(std::move(first), last, value, proj) != last
first2 == last2 || !ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty()
Сложность
Максимум last - first применений предиката и проекции.
Примечания
До C++20 нам приходилось писать std::ranges::find(r, value) != std::ranges::end(r) для определения, входит ли отдельное значение в диапазон. А для проверки, содержит ли диапазон поддиапазон, мы использовали not std::ranges::search(haystack, needle).empty(). Хотя это верно, это не обязательно удобно, и это плохо отражает намерение (особенно в последнем случае). Возможность сказать std::ranges::contains(r, value) решает обе эти проблемы.
ranges::contains_subrange, так же как и ranges::search, но в отличие от std::search, не предоставляет доступа к Searchers (таким как Boyer-Moore).
| Макро-тест функции | Значение | Стандарт | Функция |
|---|---|---|---|
__cpp_lib_ranges_contains |
202207L | (C++23) |
std::ranges::contains и ranges::contains_subrange |
Возможная реализация
| contains |
|---|
struct __contains_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
class T, class Proj = std::identity>
requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>,
const T*>
constexpr bool operator()(I first, S last, const T& value, Proj proj = {}) const
{
return ranges::find(std::move(first), last, value, proj) != last;
}
template<ranges::input_range R, class T, class Proj = std::identity>
requires std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>,
const T*>
constexpr bool operator()(R&& r, const T& value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(value), proj);
}
};
inline constexpr __contains_fn contains {}; |
| contains_subrange |
struct __contains_subrange_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 bool operator()(I1 first1, S1 last1,
I2 first2, S2 last2,
Pred pred = {},
Proj1 proj1 = {}, Proj2 proj2 = {}) const
{
return (first2 == last2) ||
!ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty();
}
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 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::move(pred),
std::move(proj1), std::move(proj2));
}
};
inline constexpr __contains_subrange_fn contains_subrange {}; |
Пример
#include <algorithm>
#include <array>
int main()
{
constexpr auto haystack = std::array{3, 1, 4, 1, 5};
constexpr auto needle = std::array{1, 4, 1};
constexpr auto bodkin = std::array{2, 5, 2};
auto increment = [](int x) { return ++x; };
auto decrement = [](int x) { return --x; };
static_assert(
std::ranges::contains(haystack, 4) &&
!std::ranges::contains(haystack, 6) &&
std::ranges::contains_subrange(haystack, needle) &&
!std::ranges::contains_subrange(haystack, bodkin) &&
std::ranges::contains(haystack, 6, increment) &&
!std::ranges::contains(haystack, 1, increment) &&
std::ranges::contains_subrange(haystack, bodkin, {}, increment) &&
!std::ranges::contains_subrange(haystack, bodkin, {}, decrement) &&
std::ranges::contains_subrange(haystack, bodkin, {}, {}, decrement)
);
}См. также
|
(C++20)(C++20)(C++20) |
находит первый элемент, удовлетворяющий определённым критериям (niebloid) |
|
(C++20) |
ищет диапазон элементов (niebloid) |
|
(C++20) |
определяет, существует ли элемент в частично упорядоченном диапазоне (niebloid) |
|
(C++20) |
возвращает true, если одна последовательность является подпоследовательностью другой(niebloid) |
|
(C++20)(C++20)(C++20) |
проверяет, является ли предикат true для всех, любого или ни одного из элементов в диапазоне(niebloid) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/ranges/contains