Defined in header
Call signature
template<std::input_iteratorI,std::sentinel_for<I>S,classT,classProj=std::identity>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<I,Proj>,constT*>constexprboolcontains(Ifirst,Slast,constT&value,Projproj={}); (1)(since C++23)
(until C++26)template<std::input_iteratorI,std::sentinel_for<I>S,classProj=std::identity,classT=std::projected_value_t<I,Proj>>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<I,Proj>,constT*>constexprboolcontains(Ifirst,Slast,constT&value,Projproj={});(since C++26)template<ranges::input_rangeR,classT,classProj=std::identity>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<ranges::iterator_t<R>,Proj>,constT*>constexprboolcontains(R&&r,constT&value,Projproj={}); (2)(since C++23)
(until C++26)template<ranges::input_rangeR,classProj=std::identity,classT=std::projected_value_t<ranges::iterator_t<R>,Proj>>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<ranges::iterator_t<R>,Proj>,constT*>constexprboolcontains(R&&r,constT&value,Projproj={});(since C++26)template<std::forward_iteratorI1,std::sentinel_for<I1>S1,std::forward_iteratorI2,std::sentinel_for<I2>S2,classPred=ranges::equal_to,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_comparable<I1,I2,Pred,Proj1,Proj2>constexprboolcontains_subrange(I1first1,S1last1,I2first2,S2last2,Predpred={},Proj1proj1={},Proj2proj2={}); (3)(since C++23)template<ranges::forward_rangeR1,ranges::forward_rangeR2,classPred=ranges::equal_to,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_comparable<ranges::iterator_t<R1>,ranges::iterator_t<R2>,Pred,Proj1,Proj2>constexprboolcontains_subrange(R1&&r1,R2&&r2,Predpred={},Proj1proj1={},Proj2proj2={}); (4) (since C++23)template</*execution-policy*/Ep,std::random_access_iteratorI,std::sized_sentinel_for<I>S,classProj=std::identity,classT=std::projected_value_t<I,Proj>>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<I,Proj>,constT*>boolcontains(Ep&&policy,Ifirst,Slast,constT&value,Projproj={}); (5) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R,classProj=std::identity,classT=std::projected_value_t<ranges::iterator_t<R>,Proj>>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<ranges::iterator_t<R>,Proj>,constT*>boolcontains(Ep&&policy,R&&r,constT&value,Projproj={}); (6) (since C++26)template</*execution-policy*/Ep,std::random_access_iteratorI1,std::sized_sentinel_for<I1>S1,std::random_access_iteratorI2,std::sized_sentinel_for<I2>S2,classPred=ranges::equal_to,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_comparable<I1,I2,Pred,Proj1,Proj2>boolcontains_subrange(Ep&&policy,I1first1,S1last1,I2first2,S2last2,Predpred={},Proj1proj1={},Proj2proj2={}); (7) (since C++26)template</*execution-policy*/Ep,/*sized-random-access-range*/R1,/*sized-random-access-range*/R2,classPred=ranges::equal_to,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_comparable<ranges::iterator_t<R1>,ranges::iterator_t<R2>,Pred,Proj1,Proj2>boolcontains_subrange(Ep&&policy,R1&&r1,R2&&r2,Predpred={},Proj1proj1={},Proj2proj2={}); (8) (since C++26)For the definition of /*execution-policy*/, see
; for the definition of /*sized-random-access-range*/, see
.
1,2) Checks whether or not the source range contains the target value value.
1) The source range is [first, last).
2) The source range is r.
3,4) Checks whether or not the target range is a subrange of the source range.
3) The source range is [first1, last1), and the target range is [first2, last2).
4) The source range is r1, and the target range is r2.
5-8) Same as (1-4), but executed according to policy.
The function-like entities described on this page are
(informally known as niebloids), that is:
Explicit template argument lists cannot be specified when calling any of them.
None of them are visible to
.
When any of them are found by
as the name to the left of the function-call operator,
is inhibited.
Parameters
first/first1, last/last1 - the iterator-sentinel pair defining the source
first2, last2 - the iterator-sentinel pair defining the target
r/r1 - the source range value - the target value r2 - the target range pred/pred1 - the predicate to be applied to the (projected) elements in the source range pred2 - the predicate to be applied to the (projected) elements in the target range proj/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
to use Return value
1)ranges::find(std::move(first),last,value,proj)!=last
2)ranges::find(r,value,proj)!=ranges::end(r)
3)first2==last2||!ranges::search(first1,last1,first2,last2,pred,proj1,proj2).empty()
4)ranges::empty(r2)||!ranges::search(r1,r2,pred,proj1,proj2).empty()
5-8) Same as (1-4), but inserts std::forward<Ep>(policy) to the argument list of
or
as the first argument.
Complexity
Given
N as ranges::distance(first,last) or ranges::distance(r),
N1 as ranges::distance(first1,last1) or ranges::distance(r1), and
N2 as ranges::distance(first2,last2) or ranges::distance(r2):
1,2) At most N comparisons and applications of proj.
3,4) At most N1·N2 applications of pred and proj.
5,6)𝓞(N) comparisons and applications of proj.
7,8)𝓞(N1·N2) applications of pred and proj.
Exceptions
5-8) During the execution process:
If the temporary memory resources required for parallelization are not available,
is thrown.
If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for
,
is invoked).
Notes
In C++20, one may implement contains with ranges::find(haystack,needle)!=ranges::end(haystack) or contains_subrange with !ranges::search(haystack,needle).empty().
ranges::contains_subrange, like
, and unlike
, has no support for
(such as
).
macro ValueStdFeature
(C++23)ranges::contains and ranges::contains_subrange
__cpp_lib_algorithm_default_value_type
(C++26)
for algorithms (
)Possible implementation
structcontains_fn{template<std::input_iteratorI,std::sentinel_for<I>S,classProj=std::identity,classT=std::projected_value_t<I,Proj>>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<I,Proj>,constT*>constexprbooloperator()(Ifirst,Slast,constT&value,Projproj={})const{returnranges::find(std::move(first),last,value,proj)!=last;}template<ranges::input_rangeR,classProj=std::identity,classT=std::projected_value_t<ranges::iterator_t<R>,Proj>>requiresstd::indirect_binary_predicate<ranges::equal_to,std::projected<ranges::iterator_t<R>,Proj>,constT*>constexprbooloperator()(R&&r,constT&value,Projproj={})const{returnranges::find(r,value,proj)!=ranges::end(r);}};inlineconstexprcontains_fncontains{};
structcontains_subrange_fn{template<std::forward_iteratorI1,std::sentinel_for<I1>S1,std::forward_iteratorI2,std::sentinel_for<I2>S2,classPred=ranges::equal_to,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_comparable<I1,I2,Pred,Proj1,Proj2>constexprbooloperator()(I1first1,S1last1,I2first2,S2last2,Predpred={},Proj1proj1={},Proj2proj2={})const{return(first2==last2)||!ranges::search(first1,last1,first2,last2,pred,proj1,proj2).empty();}template<ranges::forward_rangeR1,ranges::forward_rangeR2,classPred=ranges::equal_to,classProj1=std::identity,classProj2=std::identity>requiresstd::indirectly_comparable<ranges::iterator_t<R1>,ranges::iterator_t<R2>,Pred,Proj1,Proj2>constexprbooloperator()(R1&&r1,R2&&r2,Predpred={},Proj1proj1={},Proj2proj2={})const{returnranges::empty(r2)||!ranges::search(r1,r2,pred,proj1,proj2).empty();}};inlineconstexprcontains_subrange_fncontains_subrange{};Example
Run this code
#include<algorithm>#include<array>#include<complex>namespaceranges=std::ranges;intmain(){constexprautohaystack=std::array{3,1,4,1,5};constexprautoneedle=std::array{1,4,1};constexprautobodkin=std::array{2,5,2};static_assert(ranges::contains(haystack,4)&&!ranges::contains(haystack,6)&&ranges::contains_subrange(haystack,needle)&&!ranges::contains_subrange(haystack,bodkin));constexprstd::array<std::complex<double>,3>nums{{{1,2},{3,4},{5,6}}};#ifdef __cpp_lib_algorithm_default_value_typestatic_assert(ranges::contains(nums,{3,4}));#elsestatic_assert(ranges::contains(nums,std::complex<double>{3,4}));#endif}See also