std::__parallel(3cxx)
π NAME π
okay so welcome to the std::__parallel(3cxx) manual page β yes, that's the manual name folded in right at the top, we're being efficient bestie π
β and this is the whole vibe:
std::__parallelβ GNU parallel code, replaces standard behavior with parallel behavior. periodt.
β¨ SYNOPSIS β¨
π Classes π
struct _CRandNumberβ Functor wrapper forstd::rand(). that's literally it, it's giving tiny but iconic π«Ά
πΈ Functions πΈ
okay bestie, this is the overload zoo π¦ β every single templated __*_switch helper, listed in full. I'm not skipping a one, not even the ones with unnamed parameters (yes, those are real, we'll meet them, stay calm). All fourteen families, in order, no cuts. π
β¨ the __accumulate_switch fam β 6 overloads β¨
Six of them. Six!! The accumulate dispatcher said "more" and honestly it ate. π
template<typename __RAIter , typename _Tp , typename _BinaryOperation >
_Tp __accumulate_switch (__RAIter __begin, __RAIter __end, _Tp
__init, _BinaryOperation __binary_op, random_access_iterator_tag,
__gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _Tp , typename _BinaryOperation ,
typename _IteratorTag > _Tp __accumulate_switch (_IIter __begin,
_IIter __end, _Tp __init, _BinaryOperation __binary_op,
_IteratorTag)
template<typename _IIter , typename _Tp , typename _IteratorTag > _Tp
__accumulate_switch (_IIter __begin, _IIter __end, _Tp __init,
_IteratorTag)
template<typename _IIter , typename _Tp , typename _BinaryOper ,
typename _Tag > _Tp __accumulate_switch (_IIter, _IIter, _Tp,
_BinaryOper, _Tag)
template<typename _IIter , typename _Tp , typename _Tag > _Tp
__accumulate_switch (_IIter, _IIter, _Tp, _Tag)
template<typename _RAIter , typename _Tp , typename _BinaryOper > _Tp
__accumulate_switch (_RAIter, _RAIter, _Tp, _BinaryOper,
random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism=__gnu_parallel::parallel_unbalanced)
π bestie look β the last one has a default: __parallelism=__gnu_parallel::parallel_unbalanced. It literally picked its own setting. main character energy, no notes.
π __adjacent_difference_switch β 4 overloads π
template<typename _IIter , typename _OutputIterator , typename
_BinaryOperation , typename _IteratorTag1 , typename _IteratorTag2 >
_OutputIterator __adjacent_difference_switch (_IIter __begin, _IIter
__end, _OutputIterator __result, _BinaryOperation __bin_op,
_IteratorTag1, _IteratorTag2)
template<typename _IIter , typename _OutputIterator , typename
_BinaryOperation > _OutputIterator __adjacent_difference_switch
(_IIter __begin, _IIter __end, _OutputIterator __result,
_BinaryOperation __bin_op, random_access_iterator_tag,
random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism_tag)
template<typename _IIter , typename _OIter , typename _BinaryOper ,
typename _Tag1 , typename _Tag2 > _OIter
__adjacent_difference_switch (_IIter, _IIter, _OIter, _BinaryOper,
_Tag1, _Tag2)
template<typename _IIter , typename _OIter , typename _BinaryOper >
_OIter __adjacent_difference_switch (_IIter, _IIter, _OIter,
_BinaryOper, random_access_iterator_tag, random_access_iterator_tag,
__gnu_parallel::_Parallelism
__parallelism=__gnu_parallel::parallel_unbalanced)
Two iterator tags, two flavours (named __begin/__end and the anonymous squad), and one carrying that parallel_unbalanced default again. Consistent queen. π
π¦ __adjacent_find_switch β 7 overloads π¦
Seven. This family did NOT come to play. π
template<typename _FIter , typename _BiPredicate , typename _IterTag >
_FIter __adjacent_find_switch (_FIter, _FIter, _BiPredicate,
_IterTag)
template<typename _FIter , typename _IterTag > _FIter
__adjacent_find_switch (_FIter, _FIter, _IterTag)
template<typename _FIterator , typename _BinaryPredicate , typename
_IteratorTag > _FIterator __adjacent_find_switch (_FIterator
__begin, _FIterator __end, _BinaryPredicate __pred, _IteratorTag)
template<typename _FIterator , typename _IteratorTag > _FIterator
__adjacent_find_switch (_FIterator __begin, _FIterator __end,
_IteratorTag)
template<typename _RAIter , typename _BinaryPredicate > _RAIter
__adjacent_find_switch (_RAIter __begin, _RAIter __end,
_BinaryPredicate __pred, random_access_iterator_tag)
template<typename _RAIter > _RAIter __adjacent_find_switch (_RAIter
__begin, _RAIter __end, random_access_iterator_tag)
template<typename _RAIter , typename _BiPredicate > _RAIter
__adjacent_find_switch (_RAIter, _RAIter, _BiPredicate,
random_access_iterator_tag)
The way it flips between _FIter/_BiPredicate/_IterTag and _FIterator/_BinaryPredicate/_IteratorTag?? iconic, honestly. Same person, different font. β¨
π __count_if_switch β 3 overloads π
template<typename _IIter , typename _Predicate , typename _IteratorTag >
iterator_traits< _IIter >::difference_type __count_if_switch (_IIter
__begin, _IIter __end, _Predicate __pred, _IteratorTag)
template<typename _IIter , typename _Predicate , typename _IterTag >
iterator_traits< _IIter >::difference_type __count_if_switch
(_IIter, _IIter, _Predicate, _IterTag)
template<typename _RAIter , typename _Predicate > iterator_traits<
_RAIter >::difference_type __count_if_switch (_RAIter __begin,
_RAIter __end, _Predicate __pred, random_access_iterator_tag,
__gnu_parallel::_Parallelism __parallelism_tag)
Return type is iterator_traits< _IIter >::difference_type on all three β note it, because it's giving "I actually know what I'm returning." π«Ά
β __count_switch β 3 overloads β
template<typename _IIter , typename _Tp , typename _IteratorTag >
iterator_traits< _IIter >::difference_type __count_switch (_IIter
__begin, _IIter __end, const _Tp &__value, _IteratorTag)
template<typename _IIter , typename _Tp , typename _IterTag >
iterator_traits< _IIter >::difference_type __count_switch (_IIter,
_IIter, const _Tp &, _IterTag)
template<typename _RAIter , typename _Tp > iterator_traits< _RAIter
>::difference_type __count_switch (_RAIter __begin, _RAIter __end,
const _Tp &__value, random_access_iterator_tag,
__gnu_parallel::_Parallelism __parallelism_tag)
The const _Tp &__value is doing the searching, and the random-access one brought a _Parallelism tag to the party. Slay. π
π __equal_switch β 2 overloads π
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _IteratorTag1 , typename _IteratorTag2 > bool
__equal_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
_IIter2 __end2, _Predicate __pred, _IteratorTag1, _IteratorTag2)
template<typename _RAIter1 , typename _RAIter2 , typename _Predicate >
bool __equal_switch (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2
__begin2, _RAIter2 __end2, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag)
Just two, both returning bool, both taking __begin1/__end1/__begin2/__end2 because numbering your iterators is self-care. π§
πΈ __find_first_of_switch β 6 overloads πΈ
template<typename _IIter , typename _FIterator , typename
_BinaryPredicate , typename _IteratorTag1 , typename _IteratorTag2 >
_IIter __find_first_of_switch (_IIter __begin1, _IIter __end1,
_FIterator __begin2, _FIterator __end2, _BinaryPredicate __comp,
_IteratorTag1, _IteratorTag2)
template<typename _IIter , typename _FIterator , typename _IteratorTag1
, typename _IteratorTag2 > _IIter __find_first_of_switch (_IIter
__begin1, _IIter __end1, _FIterator __begin2, _FIterator __end2,
_IteratorTag1, _IteratorTag2)
template<typename _IIter , typename _FIter , typename _BiPredicate ,
typename _IterTag1 , typename _IterTag2 > _IIter
__find_first_of_switch (_IIter, _IIter, _FIter, _FIter,
_BiPredicate, _IterTag1, _IterTag2)
template<typename _IIter , typename _FIter , typename _IterTag1 ,
typename _IterTag2 > _IIter __find_first_of_switch (_IIter, _IIter,
_FIter, _FIter, _IterTag1, _IterTag2)
template<typename _RAIter , typename _FIterator , typename
_BinaryPredicate , typename _IteratorTag > _RAIter
__find_first_of_switch (_RAIter __begin1, _RAIter __end1, _FIterator
__begin2, _FIterator __end2, _BinaryPredicate __comp,
random_access_iterator_tag, _IteratorTag)
template<typename _RAIter , typename _FIter , typename _BiPredicate ,
typename _IterTag > _RAIter __find_first_of_switch (_RAIter,
_RAIter, _FIter, _FIter, _BiPredicate, random_access_iterator_tag,
_IterTag)
Notice the random-access ones only tag the first iterator random_access_iterator_tag and leave the second as plain _IteratorTag / _IterTag. Lowkey a flex. π₯
π __find_if_switch β 3 overloads π
template<typename _IIter , typename _Predicate , typename _IteratorTag >
_IIter __find_if_switch (_IIter __begin, _IIter __end, _Predicate
__pred, _IteratorTag)
template<typename _IIter , typename _Predicate , typename _IterTag >
_IIter __find_if_switch (_IIter, _IIter, _Predicate, _IterTag)
template<typename _RAIter , typename _Predicate > _RAIter
__find_if_switch (_RAIter __begin, _RAIter __end, _Predicate __pred,
random_access_iterator_tag)
No _Parallelism parameter here, FYI β just saying, since other families have one. π
π¦ __find_switch β 3 overloads π¦
template<typename _IIter , typename _Tp , typename _IteratorTag > _IIter
__find_switch (_IIter __begin, _IIter __end, const _Tp &__val,
_IteratorTag)
template<typename _IIter , typename _Tp , typename _IterTag > _IIter
__find_switch (_IIter, _IIter, const _Tp &, _IterTag)
template<typename _RAIter , typename _Tp > _RAIter __find_switch
(_RAIter __begin, _RAIter __end, const _Tp &__val,
random_access_iterator_tag)
__find_switch and __find_if_switch are literally siblings and I love that for them. π«Ά
β¨ __for_each_switch β 3 overloads β¨
template<typename _IIter , typename _Function , typename _IteratorTag >
_Function __for_each_switch (_IIter __begin, _IIter __end, _Function
__f, _IteratorTag)
template<typename _IIter , typename _Function , typename _IterTag >
_Function __for_each_switch (_IIter, _IIter, _Function, _IterTag)
template<typename _RAIter , typename _Function > _Function
__for_each_switch (_RAIter __begin, _RAIter __end, _Function __f,
random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism_tag)
Returns _Function β it gives the function back, which is such a cute move, honestly. π
π __generate_n_switch β 3 overloads π
template<typename _OIter , typename _Size , typename _Generator ,
typename _IterTag > _OIter __generate_n_switch (_OIter, _Size,
_Generator, _IterTag)
template<typename _OutputIterator , typename _Size , typename _Generator
, typename _IteratorTag > _OutputIterator __generate_n_switch
(_OutputIterator __begin, _Size __n, _Generator __gen, _IteratorTag)
template<typename _RAIter , typename _Size , typename _Generator >
_RAIter __generate_n_switch (_RAIter __begin, _Size __n, _Generator
__gen, random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism_tag)
Output iterators + a _Size + a _Generator, and the third one clocked in with the _Parallelism param. All three return the iterator. β¨
π __generate_switch β 3 overloads π
template<typename _FIter , typename _Generator , typename _IterTag >
void __generate_switch (_FIter, _FIter, _Generator, _IterTag)
template<typename _FIterator , typename _Generator , typename
_IteratorTag > void __generate_switch (_FIterator __begin,
_FIterator __end, _Generator __gen, _IteratorTag)
template<typename _RAIter , typename _Generator > void __generate_switch
(_RAIter __begin, _RAIter __end, _Generator __gen,
random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism_tag)
These three return void β unlike their __generate_n_switch cousins. Not me noticing the difference. π
π __inner_product_switch β 3 overloads π
template<typename _IIter1 , typename _IIter2 , typename _Tp , typename
_BinaryFunction1 , typename _BinaryFunction2 , typename
_IteratorTag1 , typename _IteratorTag2 > _Tp __inner_product_switch
(_IIter1 __first1, _IIter1 __last1, _IIter2 __first2, _Tp __init,
_BinaryFunction1 __binary_op1, _BinaryFunction2 __binary_op2,
_IteratorTag1, _IteratorTag2)
template<typename _IIter1 , typename _IIter2 , typename _Tp , typename
_BinaryFunction1 , typename _BinaryFunction2 , typename _Tag1 ,
typename _Tag2 > _Tp __inner_product_switch (_IIter1, _IIter1,
_IIter2, _Tp, _BinaryFunction1, _BinaryFunction2, _Tag1, _Tag2)
template<typename _RAIter1 , typename _RAIter2 , typename _Tp , typename
_BinaryFunction1 , typename _BinaryFunction2 > _Tp
__inner_product_switch (_RAIter1, _RAIter1, _RAIter2, _Tp,
_BinaryFunction1, _BinaryFunction2, random_access_iterator_tag,
random_access_iterator_tag,
__gnu_parallel::_Parallelism=__gnu_parallel::parallel_unbalanced)
Two binary functions (__binary_op1 and __binary_op2), two iterator tags, and that third one naming __first1/__last1/__first2/__init β plus the __parallelism=__gnu_parallel::parallel_unbalanced default. It's giving "I have options and I know it." π
β __lexicographical_compare_switch β 2 overloads β
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _IteratorTag1 , typename _IteratorTag2 > bool
__lexicographical_compare_switch (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1,
_IteratorTag2)
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _IterTag1 , typename _IterTag2 > bool
__lexicographical_compare_switch (_IIter1, _IIter1, _IIter2,
_IIter2, _Predicate, _IterTag1, _IterTag2)
And we close the function list on these two β both bool, both with two iterator tags, one named and one anonymous. A perfect little outro. π
...and the tag-dispatch squad keeps rolling, bestie β welcome back to the _switch wall π
Every single one of these bad boys is a template that takes iterator tags at the end so the right impl gets picked. No skipping, we're reading them all. π
template<typename _RAIter1 , typename _RAIter2 , typename _Predicate >
bool __lexicographical_compare_switch (_RAIter1 __begin1, _RAIter1
__end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag)
Lexicographical compare, but make it random_access_iterator_tag on both sides β¨ returns a bool, takes two ranges plus __pred, and the last two params are literally just tags chilling there. it's giving "i'm just here to select the overload" π
template<typename _FIter , typename _Compare , typename _IterTag >
_FIter __max_element_switch (_FIter, _FIter, _Compare, _IterTag)
template<typename _FIterator , typename _Compare , typename _IteratorTag
> _FIterator __max_element_switch (_FIterator __begin, _FIterator
__end, _Compare __comp, _IteratorTag)
template<typename _RAIter , typename _Compare > _RAIter
__max_element_switch (_RAIter __begin, _RAIter __end, _Compare
__comp, random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism_tag)
Three variants of __max_element_switch β forward-iterator flavour (one with unnamed params, one with __begin/__end/__comp named), then the random-access one that also snags a __gnu_parallel::_Parallelism __parallelism_tag at the end π all three hand back an _FIter / _RAIter, so you get the iterator to the winner. main character energy fr.
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Compare , typename _IteratorTag1 , typename
_IteratorTag2 , typename _IteratorTag3 > _OutputIterator
__merge_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
_IIter2 __end2, _OutputIterator __result, _Compare __comp,
_IteratorTag1, _IteratorTag2, _IteratorTag3)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Compare > _OutputIterator __merge_switch (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __result, _Compare __comp,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Compare , typename _IterTag1 , typename _IterTag2 ,
typename _IterTag3 > _OIter __merge_switch (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Compare, _IterTag1, _IterTag2, _IterTag3)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Compare > _OIter __merge_switch (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Compare, random_access_iterator_tag,
random_access_iterator_tag, random_access_iterator_tag)
__merge_switch said "three tags or nothing" π€ four overloads: the _OutputIterator pair (named __result, __comp) and the _OIter pair (params unnamed). All of them return the output iterator. the triple random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag is so satisfying to look at, ngl π¦
template<typename _FIter , typename _Compare , typename _IterTag >
_FIter __min_element_switch (_FIter, _FIter, _Compare, _IterTag)
template<typename _FIterator , typename _Compare , typename _IteratorTag
> _FIterator __min_element_switch (_FIterator __begin, _FIterator
__end, _Compare __comp, _IteratorTag)
template<typename _RAIter , typename _Compare > _RAIter
__min_element_switch (_RAIter __begin, _RAIter __end, _Compare
__comp, random_access_iterator_tag, __gnu_parallel::_Parallelism
__parallelism_tag)
__min_element_switch, the mirror twin of __max_element_switch β same three shapes, same random_access_iterator_tag + __gnu_parallel::_Parallelism __parallelism_tag combo on the last one π returns _FIter/_RAIter. iconic sibling behaviour.
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _IteratorTag1 , typename _IteratorTag2 > pair< _IIter1,
_IIter2 > __mismatch_switch (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _Predicate __pred, _IteratorTag1,
_IteratorTag2)
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _IteratorTag1 , typename _IteratorTag2 > pair< _IIter1,
_IIter2 > __mismatch_switch (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _Predicate __pred, _IteratorTag1, _IteratorTag2)
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _IterTag1 , typename _IterTag2 > pair< _IIter1, _IIter2 >
__mismatch_switch (_IIter1, _IIter1, _IIter2, _Predicate, _IterTag1,
_IterTag2)
template<typename _RAIter1 , typename _RAIter2 , typename _Predicate >
pair< _RAIter1, _RAIter2 > __mismatch_switch (_RAIter1 __begin1,
_RAIter1 __end1, _RAIter2 __begin2, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag)
template<typename _RAIter1 , typename _RAIter2 , typename _Predicate >
pair< _RAIter1, _RAIter2 > __mismatch_switch (_RAIter1 __begin1,
_RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Predicate
__pred, random_access_iterator_tag, random_access_iterator_tag)
Five whole __mismatch_switch overloads and every single one returns pair< _IIter1, _IIter2 > or pair< _RAIter1, _RAIter2 > π«Ά which like, yeah, mismatch gives you a pair of iterators β clock it. Note the middle overloads swap _IteratorTag1/_IteratorTag2 for _IterTag1/_IterTag2 and don't name their params. and the last two are the random_access_iterator_tag twins: one takes a __end2, one doesn't π not me noticing every difference, i'm obsessed.
template<typename _IIter , typename _OutputIterator , typename
_BinaryOperation , typename _IteratorTag1 , typename _IteratorTag2 >
_OutputIterator __partial_sum_switch (_IIter __begin, _IIter __end,
_OutputIterator __result, _BinaryOperation __bin_op, _IteratorTag1,
_IteratorTag2)
template<typename _IIter , typename _OutputIterator , typename
_BinaryOperation > _OutputIterator __partial_sum_switch (_IIter
__begin, _IIter __end, _OutputIterator __result, _BinaryOperation
__bin_op, random_access_iterator_tag, random_access_iterator_tag)
template<typename _IIter , typename _OIter , typename _BinaryOper ,
typename _Tag1 , typename _Tag2 > _OIter __partial_sum_switch
(_IIter, _IIter, _OIter, _BinaryOper, _Tag1, _Tag2)
template<typename _IIter , typename _OIter , typename _BinaryOper >
_OIter __partial_sum_switch (_IIter, _IIter, _OIter, _BinaryOper,
random_access_iterator_tag, random_access_iterator_tag)
__partial_sum_switch, four takes π the _OutputIterator/_BinaryOperation named-attrs version, then its random_access_iterator_tag-tagged twin, then the _OIter/_BinaryOper/_Tag1/_Tag2 unnamed remix and its tagged twin. same algorithm, four outfits. slay.
template<typename _FIter , typename _Predicate , typename _IterTag >
_FIter __partition_switch (_FIter, _FIter, _Predicate, _IterTag)
template<typename _FIterator , typename _Predicate , typename
_IteratorTag > _FIterator __partition_switch (_FIterator __begin,
_FIterator __end, _Predicate __pred, _IteratorTag)
template<typename _RAIter , typename _Predicate > _RAIter
__partition_switch (_RAIter __begin, _RAIter __end, _Predicate
__pred, random_access_iterator_tag)
Three __partition_switch variants, all returning the same iterator type they're fed π₯ and heads up β the random-access one only takes random_access_iterator_tag, no extra parallelism tag here. small detail but we stan accuracy. π§
template<typename _FIter , typename _Predicate , typename _Tp , typename
_IterTag > void __replace_if_switch (_FIter, _FIter, _Predicate,
const _Tp &, _IterTag)
template<typename _FIterator , typename _Predicate , typename _Tp ,
typename _IteratorTag > void __replace_if_switch (_FIterator
__begin, _FIterator __end, _Predicate __pred, const _Tp
&__new_value, _IteratorTag)
template<typename _RAIter , typename _Predicate , typename _Tp > void
__replace_if_switch (_RAIter __begin, _RAIter __end, _Predicate
__pred, const _Tp &__new_value, random_access_iterator_tag,
__gnu_parallel::_Parallelism __parallelism_tag)
__replace_if_switch returns void β it modifies in place, no takebacks π one _Tp for __new_value, and the RA version brings along __gnu_parallel::_Parallelism __parallelism_tag for the ride. π
template<typename _FIter , typename _Tp , typename _IterTag > void
__replace_switch (_FIter, _FIter, const _Tp &, const _Tp &,
_IterTag)
template<typename _FIterator , typename _Tp , typename _IteratorTag >
void __replace_switch (_FIterator __begin, _FIterator __end, const
_Tp &__old_value, const _Tp &__new_value, _IteratorTag)
template<typename _RAIter , typename _Tp > void __replace_switch
(_RAIter __begin, _RAIter __end, const _Tp &__old_value, const _Tp
&__new_value, random_access_iterator_tag,
__gnu_parallel::_Parallelism __parallelism_tag)
and __replace_switch is the no-predicate cousin β two const _Tp & this time (__old_value and __new_value), also void. πΈ the way these two families mirror each other is so satisfying, periodt.
template<typename _FIter , typename _Integer , typename _Tp , typename
_BiPredicate , typename _IterTag > _FIter __search_n_switch (_FIter,
_FIter, _Integer, const _Tp &, _BiPredicate, _IterTag)
template<typename _FIterator , typename _Integer , typename _Tp ,
typename _BinaryPredicate , typename _IteratorTag > _FIterator
__search_n_switch (_FIterator __begin, _FIterator __end, _Integer
__count, const _Tp &__val, _BinaryPredicate __binary_pred,
_IteratorTag)
template<typename _RAIter , typename _Integer , typename _Tp , typename
_BinaryPredicate > _RAIter __search_n_switch (_RAIter __begin,
_RAIter __end, _Integer __count, const _Tp &__val, _BinaryPredicate
__binary_pred, random_access_iterator_tag)
template<typename _RAIter , typename _Integer , typename _Tp , typename
_BiPredicate > _RAIter __search_n_switch (_RAIter, _RAIter,
_Integer, const _Tp &, _BiPredicate, random_access_iterator_tag)
__search_n_switch Γ 4, and watch the predicate name hop: _BiPredicate β _BinaryPredicate β _BinaryPredicate β _BiPredicate π it comes with an _Integer __count and a const _Tp &__val, returns an iterator. all four just random_access_iterator_tag on the RA ones, no parallelism tag. lowkey refreshing tbh.
template<typename _FIter1 , typename _FIter2 , typename _BiPredicate ,
typename _IterTag1 , typename _IterTag2 > _FIter1 __search_switch
(_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate, _IterTag1,
_IterTag2)
template<typename _FIter1 , typename _FIter2 , typename _IterTag1 ,
typename _IterTag2 > _FIter1 __search_switch (_FIter1, _FIter1,
_FIter2, _FIter2, _IterTag1, _IterTag2)
template<typename _FIterator1 , typename _FIterator2 , typename
_BinaryPredicate , typename _IteratorTag1 , typename _IteratorTag2 >
_FIterator1 __search_switch (_FIterator1 __begin1, _FIterator1
__end1, _FIterator2 __begin2, _FIterator2 __end2, _BinaryPredicate
__pred, _IteratorTag1, _IteratorTag2)
template<typename _FIterator1 , typename _FIterator2 , typename
_IteratorTag1 , typename _IteratorTag2 > _FIterator1 __search_switch
(_FIterator1 __begin1, _FIterator1 __end1, _FIterator2 __begin2,
_FIterator2 __end2, _IteratorTag1, _IteratorTag2)
template<typename _RAIter1 , typename _RAIter2 , typename
_BinaryPredicate > _RAIter1 __search_switch (_RAIter1 __begin1,
_RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2,
_BinaryPredicate __pred, random_access_iterator_tag,
random_access_iterator_tag)
template<typename _RAIter1 , typename _RAIter2 > _RAIter1
__search_switch (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2
__begin2, _RAIter2 __end2, random_access_iterator_tag,
random_access_iterator_tag)
template<typename _RAIter1 , typename _RAIter2 , typename _BiPredicate >
_RAIter1 __search_switch (_RAIter1, _RAIter1, _RAIter2, _RAIter2,
_BiPredicate, random_access_iterator_tag,
random_access_iterator_tag)
seven __search_switch overloads, everybody say thank you π they all return _FIter1 / _RAIter1. you got your predicate/no-predicate pairs, your named/unnamed param pairs, _BiPredicate vs _BinaryPredicate, forward vs random-access. the range version and the predicate version and everything in between. this is the whole buffet. π
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _OutputIterator , typename _IteratorTag1 , typename
_IteratorTag2 , typename _IteratorTag3 > _OutputIterator
__set_difference_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2, _OutputIterator __result, _Predicate
__pred, _IteratorTag1, _IteratorTag2, _IteratorTag3)
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _OIter , typename _IterTag1 , typename _IterTag2 , typename
_IterTag3 > _OIter __set_difference_switch (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2,
_IterTag3)
template<typename _RAIter1 , typename _RAIter2 , typename _Output_RAIter
, typename _Predicate > _Output_RAIter __set_difference_switch
(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2
__end2, _Output_RAIter __result, _Predicate __pred,
random_access_iterator_tag, random_access_iterator_tag,
random_access_iterator_tag)
__set_difference_switch β three overloads, three tags, and the random-access one has a special output iterator type: _Output_RAIter π (the others just say _OutputIterator / _OIter). returns the output iterator, obviously. cute and correct.
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
typename _OutputIterator , typename _IteratorTag1 , typename
_IteratorTag2 , typename _IteratorTag3 > _OutputIterator
__set_intersection_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2, _OutputIterator __result, _Predicate
__pred, _IteratorTag1, _IteratorTag2, _IteratorTag3)
template<typename _IIter1 , typename _IIter2 , typename _Predicate ,
...and here's where this part runs out of page π³ __set_intersection_switch kicks off with that same _OutputIterator __result + _Predicate __pred + three tags energy, and the rest of it is waiting for you in the next chunk. don't go anywhere bestie π
okay so we're still deep in the switch-helper zone, and honestly this is where the page starts looking like someone fell asleep on the < key π but stay with me bestie, because these are actually the little dispatch gremlins that pick the fast path for you. none of them are your problem to call β they're just here, being thorough.
first up, __set_intersection_switch in three flavours π
:
template<typename _OIter , typename _IterTag1 , typename _IterTag2 , typename _IterTag3 > _OIter __set_intersection_switch (_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3)
template<typename _RAIter1 , typename _RAIter2 , typename _Output_RAIter , typename _Predicate > _Output_RAIter __set_intersection_switch (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
see how the second one spells out __begin1, __end1, __begin2, __end2, __result, __pred and then three random_access_iterator_tags in a row? that's the version that gets picked when your iterators are random access β the tags are literally the vibe check at compile time π and the first one is the tag-agnostic fallback where the parameters are all unnamed. iconic behaviour, honestly.
same energy for __set_symmetric_difference_switch β yes, three of them, because symmetry deserves options β¨:
template<typename _IIter1 , typename _IIter2 , typename _Predicate , typename _OutputIterator , typename _IteratorTag1 , typename _IteratorTag2 , typename _IteratorTag3 > _OutputIterator __set_symmetric_difference_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3)
template<typename _IIter1 , typename _IIter2 , typename _Predicate , typename _OIter , typename _IterTag1 , typename _IterTag2 , typename _IterTag3 > _OIter __set_symmetric_difference_switch (_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3)
template<typename _RAIter1 , typename _RAIter2 , typename _Output_RAIter , typename _Predicate > _Output_RAIter __set_symmetric_difference_switch (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
and __set_union_switch rounds out the trio of set-operation switches, three overloads each, no crumbs π«Ά:
template<typename _IIter1 , typename _IIter2 , typename _Predicate , typename _OutputIterator , typename _IteratorTag1 , typename _IteratorTag2 , typename _IteratorTag3 > _OutputIterator __set_union_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __result, _Predicate __pred, _IteratorTag1, _IteratorTag2, _IteratorTag3)
template<typename _IIter1 , typename _IIter2 , typename _Predicate , typename _OIter , typename _IterTag1 , typename _IterTag2 , typename _IterTag3 > _OIter __set_union_switch (_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Predicate, _IterTag1, _IterTag2, _IterTag3)
template<typename _RAIter1 , typename _RAIter2 , typename _Output_RAIter , typename _Predicate > _Output_RAIter __set_union_switch (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter2 __end2, _Output_RAIter __result, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
okay now the __transform1_switch family, and this is where it gets interesting because look β someone slipped a default argument in here π <yellow>__gnu_parallel::_Parallelism __parallelism=__gnu_parallel::parallel_balanced</yellow> β and then a *fourth* overload where __parallelism_tag` is a required parameter with no default. four overloads. four. it's giving "i contain multitudes" π:
template<typename _IIter , typename _OIter , typename _UnaryOperation , typename _IterTag1 , typename _IterTag2 > _OIter __transform1_switch (_IIter, _IIter, _OIter, _UnaryOperation, _IterTag1, _IterTag2)
template<typename _RAIIter , typename _RAOIter , typename _UnaryOperation > _RAOIter __transform1_switch (_RAIIter, _RAIIter, _RAOIter, _UnaryOperation, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism=__gnu_parallel::parallel_balanced)
template<typename _RAIter1 , typename _RAIter2 , typename _UnaryOperation , typename _IteratorTag1 , typename _IteratorTag2 > _RAIter2 __transform1_switch (_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, _IteratorTag1, _IteratorTag2)
template<typename _RAIter1 , typename _RAIter2 , typename _UnaryOperation > _RAIter2 __transform1_switch (_RAIter1 __begin, _RAIter1 __end, _RAIter2 __result, _UnaryOperation __unary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag)
and __transform2_switch, same deal but for the two-range flavour β note the template heads swap _OIter/_OutputIterator and _BiOperation/_BinaryOperation between overloads, which is so on brand for this header π and yep, parallel_balanced default shows up again:
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator , typename _BinaryOperation , typename _Tag1 , typename _Tag2 , typename _Tag3 > _OutputIterator __transform2_switch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator __result, _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
template<typename _IIter1 , typename _IIter2 , typename _OIter , typename _BiOperation , typename _Tag1 , typename _Tag2 , typename _Tag3 > _OIter __transform2_switch (_IIter1, _IIter1, _IIter2, _OIter, _BiOperation, _Tag1, _Tag2, _Tag3)
template<typename _RAIter1 , typename _RAIter2 , typename _RAIter3 , typename _BinaryOperation > _RAIter3 __transform2_switch (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _RAIter3 __result, _BinaryOperation __binary_op, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _RAIter1 , typename _RAIter2 , typename _RAIter3 , typename _BiOperation > _RAIter3 __transform2_switch (_RAIter1, _RAIter1, _RAIter2, _RAIter3, _BiOperation, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::_Parallelism __parallelism=__gnu_parallel::parallel_balanced)
__unique_copy_switch next, four overloads, and the naming goes feral in the last two β _RandomAccessOutputIterator vs. _RandomAccess_OIter, bestie they could NOT commit to a convention and i respect the chaos π:
template<typename _IIter , typename _OutputIterator , typename _Predicate , typename _IteratorTag1 , typename _IteratorTag2 > _OutputIterator __unique_copy_switch (_IIter __begin, _IIter __last, _OutputIterator __out, _Predicate __pred, _IteratorTag1, _IteratorTag2)
template<typename _IIter , typename _OIter , typename _Predicate , typename _IterTag1 , typename _IterTag2 > _OIter __unique_copy_switch (_IIter, _IIter, _OIter, _Predicate, _IterTag1, _IterTag2)
template<typename _RAIter , typename _RandomAccessOutputIterator , typename _Predicate > _RandomAccessOutputIterator __unique_copy_switch (_RAIter __begin, _RAIter __last, _RandomAccessOutputIterator __out, _Predicate __pred, random_access_iterator_tag, random_access_iterator_tag)
template<typename _RAIter , typename _RandomAccess_OIter , typename _Predicate > _RandomAccess_OIter __unique_copy_switch (_RAIter, _RAIter, _RandomAccess_OIter, _Predicate, random_access_iterator_tag, random_access_iterator_tag)
okay and NOW we hit the actual named algorithms, the ones you might genuinely call π starting with accumulate, which has nine overloads and i need you to breathe:
template<typename _IIter , typename _Tp , typename _BinaryOperation > _Tp accumulate (_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op)
template<typename _IIter , typename _Tp , typename _BinaryOperation > _Tp accumulate (_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _Tp , typename _BinaryOperation > _Tp accumulate (_IIter __begin, _IIter __end, _Tp __init, _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _Tp > _Tp accumulate (_IIter, _IIter, _Tp)
template<typename _IIter , typename _Tp > _Tp accumulate (_IIter, _IIter, _Tp, __gnu_parallel::_Parallelism)
template<typename _IIter , typename _Tp > _Tp accumulate (_IIter, _IIter, _Tp, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _Tp , typename _BinaryOper > _Tp accumulate (_IIter, _IIter, _Tp, _BinaryOper)
template<typename _IIter , typename _Tp , typename _BinaryOper > _Tp accumulate (_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::_Parallelism)
template<typename _IIter , typename _Tp , typename _BinaryOper > _Tp accumulate (_IIter, _IIter, _Tp, _BinaryOper, __gnu_parallel::sequential_tag)
three shapes of the same idea, each in three tag-variants: no tag, __gnu_parallel::_Parallelism, and __gnu_parallel::sequential_tag. and yes the parameter types are named _BinaryOperation in the first group and _BinaryOper in the last group. no cap, that's just how it is π
adjacent_difference is also out here with twelve overloads, because why have three when you can have twelve, slay i guess π₯ β and tagging in __bin_op in exactly one of them because consistency is a myth:
template<typename _IIter , typename _OutputIterator > _OutputIterator adjacent_difference (_IIter __begin, _IIter __end, _OutputIterator __result)
template<typename _IIter , typename _OutputIterator > _OutputIterator adjacent_difference (_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _OutputIterator > _OutputIterator adjacent_difference (_IIter __begin, _IIter __end, _OutputIterator __result, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _OutputIterator , typename _BinaryOperation > _OutputIterator adjacent_difference (_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _OutputIterator , typename _BinaryOperation > _OutputIterator adjacent_difference (_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op)
template<typename _IIter , typename _OutputIterator , typename _BinaryOperation > _OutputIterator adjacent_difference (_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _OIter > _OIter adjacent_difference (_IIter, _IIter, _OIter)
template<typename _IIter , typename _OIter > _OIter adjacent_difference (_IIter, _IIter, _OIter, __gnu_parallel::_Parallelism)
template<typename _IIter , typename _OIter > _OIter adjacent_difference (_IIter, _IIter, _OIter, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _OIter , typename _BinaryOper > _OIter adjacent_difference (_IIter, _IIter, _OIter, _BinaryOper)
template<typename _IIter , typename _OIter , typename _BinaryOper > _OIter adjacent_difference (_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::_Parallelism)
template<typename _IIter , typename _OIter , typename _BinaryOper > _OIter adjacent_difference (_IIter, _IIter, _OIter, _BinaryOper, __gnu_parallel::sequential_tag)
adjacent_find keeps it comparatively chill β eight overloads, split between _FIter/_BiPredicate and _FIterator/_BinaryPredicate spellings, with sequential_tag riding shotgun in half of them π:
template<typename _FIter > _FIter adjacent_find (_FIter, _FIter)
template<typename _FIter > _FIter adjacent_find (_FIter, _FIter, __gnu_parallel::sequential_tag)
template<typename _FIter , typename _BiPredicate > _FIter adjacent_find (_FIter, _FIter, _BiPredicate)
template<typename _FIter , typename _BiPredicate > _FIter adjacent_find (_FIter, _FIter, _BiPredicate, __gnu_parallel::sequential_tag)
template<typename _FIterator > _FIterator adjacent_find (_FIterator __begin, _FIterator __end)
template<typename _FIterator > _FIterator adjacent_find (_FIterator __begin, _FIterator __end, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _BinaryPredicate > _FIterator adjacent_find (_FIterator __begin, _FIterator __end, _BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _BinaryPredicate > _FIterator adjacent_find (_FIterator __begin, _FIterator __end, _BinaryPredicate __pred)
and then, right at the edge of this part, count shows up and it's bringing the <lavender>iterator_traits< _IIter >::difference_type</lavender> return type with it β fancy π¦ and note the const _Tp &__value`, that reference is load-bearing:
template<typename _IIter , typename _Tp > iterator_traits< _IIter >::difference_type count (_IIter __begin, _IIter __end, const _Tp &__value)
and there's more coming, we're only getting started on the actual algorithm list ππ«Ά
okay bestie, we are deep in the synopsis trenches now and honestly? it's giving overload appreciation post π
the pattern is gonna click real soon β every family comes in flavours: a plain one, one with a __gnu_parallel::_Parallelism __parallelism_tag, and one with a __gnu_parallel::sequential_tag. same algorithm, different vibes. let's go π¦
count / count_if β the whole squad, all five of them, returning iterator_traits< _IIter >::difference_type like the icon it is:
template<typename _IIter , typename _Tp > iterator_traits< _IIter
>::difference_type count (_IIter __begin, _IIter __end, const _Tp
&__value, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _Tp > iterator_traits< _IIter
>::difference_type count (_IIter __begin, _IIter __end, const _Tp
&__value, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _Predicate > iterator_traits< _IIter
>::difference_type count_if (_IIter __begin, _IIter __end,
_Predicate __pred)
template<typename _IIter , typename _Predicate > iterator_traits< _IIter
>::difference_type count_if (_IIter __begin, _IIter __end,
_Predicate __pred, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _Predicate > iterator_traits< _IIter
>::difference_type count_if (_IIter __begin, _IIter __end,
_Predicate __pred, __gnu_parallel::sequential_tag)
equal β she has EIGHT overloads, she's the main character of this section honestly π note the constexpr ones, and note that some take two iterators and some take four, and some take a _BinaryPredicate and some take a plain _Predicate. all of it, verbatim:
template<typename _IIter1 , typename _IIter2 > constexpr bool equal
(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
template<typename _IIter1 , typename _IIter2 > bool equal (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 > constexpr bool equal
(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2)
template<typename _IIter1 , typename _IIter2 > bool equal (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _BinaryPredicate
> constexpr bool equal (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2, _BinaryPredicate __binary_pred)
template<typename _IIter1 , typename _IIter2 , typename _BinaryPredicate
> bool equal (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
_IIter2 __end2, _BinaryPredicate __binary_pred,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _Predicate >
constexpr bool equal (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _Predicate >
bool equal (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
_Predicate __pred, __gnu_parallel::sequential_tag)
find, find_first_of, find_if β search girlies rise π§ watch how find_first_of gets declared twice over: once with _FIterator/_BinaryPredicate names and once with _FIter/_BiPredicate names. that's not a typo, that's both of them living here, and we respect it:
template<typename _IIter , typename _Tp > _IIter find (_IIter __begin,
_IIter __end, const _Tp &__val)
template<typename _IIter , typename _Tp > _IIter find (_IIter __begin,
_IIter __end, const _Tp &__val, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _FIterator > _IIter find_first_of
(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator
__end2)
template<typename _IIter , typename _FIterator > _IIter find_first_of
(_IIter __begin1, _IIter __end1, _FIterator __begin2, _FIterator
__end2, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _FIterator , typename
_BinaryPredicate > _IIter find_first_of (_IIter __begin1, _IIter
__end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate
__comp)
template<typename _IIter , typename _FIterator , typename
_BinaryPredicate > _IIter find_first_of (_IIter __begin1, _IIter
__end1, _FIterator __begin2, _FIterator __end2, _BinaryPredicate
__comp, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _FIter > _IIter find_first_of
(_IIter, _IIter, _FIter, _FIter)
template<typename _IIter , typename _FIter > _IIter find_first_of
(_IIter, _IIter, _FIter, _FIter, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _FIter , typename _BiPredicate >
_IIter find_first_of (_IIter, _IIter, _FIter, _FIter, _BiPredicate)
template<typename _IIter , typename _FIter , typename _BiPredicate >
_IIter find_first_of (_IIter, _IIter, _FIter, _FIter, _BiPredicate,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _Predicate > _IIter find_if (_IIter
__begin, _IIter __end, _Predicate __pred)
template<typename _IIter , typename _Predicate > _IIter find_if (_IIter
__begin, _IIter __end, _Predicate __pred,
__gnu_parallel::sequential_tag)
for_each β four of her, and notice the template parameter names shift between _IIter and _Iterator depending on which one you're looking at. iconic inconsistency, no notes π
template<typename _IIter , typename _Function > _Function for_each
(_IIter __begin, _IIter __end, _Function __f,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _Function > _Function for_each
(_IIter, _IIter, _Function)
template<typename _Iterator , typename _Function > _Function for_each
(_Iterator __begin, _Iterator __end, _Function __f)
template<typename _Iterator , typename _Function > _Function for_each
(_Iterator __begin, _Iterator __end, _Function __f,
__gnu_parallel::_Parallelism __parallelism_tag)
generate β six overloads, void return, and the parameters named either not-at-all or __begin/__end/__gen. keeping every single one because that's the whole assignment π«Ά
template<typename _FIter , typename _Generator > void generate (_FIter,
_FIter, _Generator)
template<typename _FIter , typename _Generator > void generate (_FIter,
_FIter, _Generator, __gnu_parallel::_Parallelism)
template<typename _FIter , typename _Generator > void generate (_FIter,
_FIter, _Generator, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Generator > void generate
(_FIterator __begin, _FIterator __end, _Generator __gen)
template<typename _FIterator , typename _Generator > void generate
(_FIterator __begin, _FIterator __end, _Generator __gen,
__gnu_parallel::_Parallelism __parallelism_tag)
template<typename _FIterator , typename _Generator > void generate
(_FIterator __begin, _FIterator __end, _Generator __gen,
__gnu_parallel::sequential_tag)
generate_n β same energy but with a _Size __n in the mix, and she also shows up twice: once with _OIter and once with the full _OutputIterator. slay π
template<typename _OIter , typename _Size , typename _Generator > _OIter
generate_n (_OIter, _Size, _Generator)
template<typename _OIter , typename _Size , typename _Generator > _OIter
generate_n (_OIter, _Size, _Generator, __gnu_parallel::_Parallelism)
template<typename _OIter , typename _Size , typename _Generator > _OIter
generate_n (_OIter, _Size, _Generator,
__gnu_parallel::sequential_tag)
template<typename _OutputIterator , typename _Size , typename _Generator
> _OutputIterator generate_n (_OutputIterator __begin, _Size __n,
_Generator __gen)
template<typename _OutputIterator , typename _Size , typename _Generator
> _OutputIterator generate_n (_OutputIterator __begin, _Size __n,
_Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _OutputIterator , typename _Size , typename _Generator
> _OutputIterator generate_n (_OutputIterator __begin, _Size __n,
_Generator __gen, __gnu_parallel::sequential_tag)
okay yes the pattern is very "same declaration, different trailing tag" and yes you're allowed to be obsessed with how tidy it is π₯
inner_product β six overloads, two shapes: the four-argument one with _Tp for the init value, and the six-argument one that also brings _BinaryFunction1 and _BinaryFunction2 along for the ride. all present, all accounted for π
template<typename _IIter1 , typename _IIter2 , typename _Tp > _Tp
inner_product (_IIter1, _IIter1, _IIter2, _Tp)
template<typename _IIter1 , typename _IIter2 , typename _Tp > _Tp
inner_product (_IIter1, _IIter1, _IIter2, _Tp,
__gnu_parallel::_Parallelism)
template<typename _IIter1 , typename _IIter2 , typename _Tp > _Tp
inner_product (_IIter1, _IIter1, _IIter2, _Tp,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _Tp , typename
_BinaryFunction1 , typename _BinaryFunction2 > _Tp inner_product
(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2)
template<typename _IIter1 , typename _IIter2 , typename _Tp , typename
_BinaryFunction1 , typename _BinaryFunction2 > _Tp inner_product
(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2,
__gnu_parallel::_Parallelism)
template<typename _IIter1 , typename _IIter2 , typename _Tp , typename
_BinaryFunction1 , typename _BinaryFunction2 > _Tp inner_product
(_IIter1, _IIter1, _IIter2, _Tp, _BinaryFunction1, _BinaryFunction2,
__gnu_parallel::sequential_tag)
lexicographical_compare β four overloads, and the long name wraps across so many lines that honestly it deserves a moment of silence π two constexpr ones, two sequential_tag ones, one plain and one with _Predicate __pred:
template<typename _IIter1 , typename _IIter2 > constexpr bool
lexicographical_compare (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2)
template<typename _IIter1 , typename _IIter2 > bool
lexicographical_compare (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2, __gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _Predicate >
constexpr bool lexicographical_compare (_IIter1 __begin1, _IIter1
__end1, _IIter2 __begin2, _IIter2 __end2, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _Predicate >
bool lexicographical_compare (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _Predicate __pred,
__gnu_parallel::sequential_tag)
max_element β TWELVE overloads bestie. twelve!! π two naming conventions (_FIter vs _FIterator), with and without _Compare, with and without __parallelism_tag, with and without sequential_tag. here's the full dozen, no skips:
template<typename _FIter > _FIter max_element (_FIter, _FIter)
template<typename _FIter > _FIter max_element (_FIter, _FIter,
__gnu_parallel::_Parallelism)
template<typename _FIter > _FIter max_element (_FIter, _FIter,
__gnu_parallel::sequential_tag)
template<typename _FIter , typename _Compare > _FIter max_element
(_FIter, _FIter, _Compare)
template<typename _FIter , typename _Compare > _FIter max_element
(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism)
template<typename _FIter , typename _Compare > _FIter max_element
(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag)
template<typename _FIterator > _FIterator max_element (_FIterator
__begin, _FIterator __end)
template<typename _FIterator > _FIterator max_element (_FIterator
__begin, _FIterator __end, __gnu_parallel::_Parallelism
__parallelism_tag)
template<typename _FIterator > _FIterator max_element (_FIterator
__begin, _FIterator __end, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Compare > _FIterator
max_element (_FIterator __begin, _FIterator __end, _Compare __comp)
template<typename _FIterator , typename _Compare > _FIterator
max_element (_FIterator __begin, _FIterator __end, _Compare __comp,
__gnu_parallel::_Parallelism __parallelism_tag)
template<typename _FIterator , typename _Compare > _FIterator
max_element (_FIterator __begin, _FIterator __end, _Compare __comp,
__gnu_parallel::sequential_tag)
merge β and she starts here and keeps going π we get the three-iterator version, the sequential_tag version, the one with _Compare __comp, and then the last declaration is still mid-sentence because the party continues in the next chunk. leaving it exactly as it lands:
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator merge (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2, _OutputIterator __result)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator merge (_IIter1 __begin1, _IIter1 __end1, _IIter2
__begin2, _IIter2 __end2, _OutputIterator __result,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Compare > _OutputIterator merge (_IIter1 __begin1,
_IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator
__result, _Compare __comp)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
and that's where we pause β the synopsis is still typing, bestie, stay tuned πΈ
like the overloads just keep coming and honestly? obsessed. π
last stretch had lower_bound-ish energy, and now we're deep in the classic "two ranges walk into a bar" territory. everything below is listed exactly as it appears β some of these spell out their parameter names, some just list the types, and both flavours are here, so don't come for me if you spot a twin π
π¦ merge β two sorted ranges become one sorted range
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator ,
typename _Compare > _OutputIterator merge (_IIter1 __begin1,
_IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator
__result, _Compare __comp, __gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
merge (_IIter1, _IIter1, _IIter2, _IIter2, _OIter)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
merge (_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Compare > _OIter merge (_IIter1, _IIter1, _IIter2,
_IIter2, _OIter, _Compare)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Compare > _OIter merge (_IIter1, _IIter1, _IIter2,
_IIter2, _OIter, _Compare, __gnu_parallel::sequential_tag)
so you've got your basic five-arg merge (no _Compare), the _Compare version for when "sorted" means your version of sorted π, and for each of those a __gnu_parallel::sequential_tag twin. the first one up top is the fancy one with __begin1, __end1, __begin2, __end2, __result, __comp all named out loud β main character energy, honestly.
π min_element β find the smallest, no cap
template<typename _FIter > _FIter min_element (_FIter, _FIter)
template<typename _FIter > _FIter min_element (_FIter, _FIter,
__gnu_parallel::_Parallelism __parallelism_tag)
template<typename _FIter > _FIter min_element (_FIter, _FIter,
__gnu_parallel::sequential_tag)
template<typename _FIter , typename _Compare > _FIter min_element
(_FIter, _FIter, _Compare)
template<typename _FIter , typename _Compare > _FIter min_element
(_FIter, _FIter, _Compare, __gnu_parallel::_Parallelism)
template<typename _FIter , typename _Compare > _FIter min_element
(_FIter, _FIter, _Compare, __gnu_parallel::sequential_tag)
template<typename _FIterator > _FIterator min_element (_FIterator
__begin, _FIterator __end)
template<typename _FIterator > _FIterator min_element (_FIterator
__begin, _FIterator __end, __gnu_parallel::_Parallelism
__parallelism_tag)
template<typename _FIterator > _FIterator min_element (_FIterator
__begin, _FIterator __end, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Compare > _FIterator
min_element (_FIterator __begin, _FIterator __end, _Compare __comp)
template<typename _FIterator , typename _Compare > _FIterator
min_element (_FIterator __begin, _FIterator __end, _Compare __comp,
__gnu_parallel::_Parallelism __parallelism_tag)
template<typename _FIterator , typename _Compare > _FIterator
min_element (_FIterator __begin, _FIterator __end, _Compare __comp,
__gnu_parallel::sequential_tag)
that's twelve of these bad boys π and yes, they're grouped: first six use _FIter with no parameter names, last six use _FIterator with __begin / __end / __comp / __parallelism_tag spelled out. each group has plain, _Parallelism, and sequential_tag variants, with and without _Compare. money every time π«Ά
β¨ mismatch β find where two ranges stop agreeing
template<typename _IIter1 , typename _IIter2 > pair< _IIter1, _IIter2 >
mismatch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
template<typename _IIter1 , typename _IIter2 > pair< _IIter1, _IIter2 >
mismatch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 > pair< _IIter1, _IIter2 >
mismatch (_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
_IIter2 __end2)
template<typename _IIter1 , typename _IIter2 , typename _Predicate >
pair< _IIter1, _IIter2 > mismatch (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _Predicate >
pair< _IIter1, _IIter2 > mismatch (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _Predicate __pred, __gnu_parallel::sequential_tag)
template<typename _InputIterator1 , typename _InputIterator2 , typename
_BinaryPredicate > pair< _InputIterator1, _InputIterator2 > mismatch
(_InputIterator1 __begin1, _InputIterator1 __end1, _InputIterator2
__begin2, _InputIterator2 __end2, _BinaryPredicate __binary_pred)
template<typename _InputIterator1 , typename _InputIterator2 > pair<
_InputIterator1, _InputIterator2 > mismatch (_InputIterator1
__first1, _InputIterator1 __last1, _InputIterator2 __first2,
_InputIterator2 __last2, __gnu_parallel::sequential_tag)
template<typename _InputIterator1 , typename _InputIterator2 , typename
_BinaryPredicate > pair< _InputIterator1, _InputIterator2 > mismatch
(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
__first2, _InputIterator2 __last2, _BinaryPredicate __binary_pred,
__gnu_parallel::sequential_tag)
notice the return type is a pair< _IIter1, _IIter2 > (or the _InputIterator1 / _InputIterator2 flavour) β you get both iterators back, so cute π also: some of these take __begin1/__end1 style names, others take __first1/__last1. same energy, different naming, both listed, moving on π
πΈ nth_element
template<typename _RAIter > void nth_element (_RAIter __begin, _RAIter
__nth, _RAIter __end)
template<typename _RAIter > void nth_element (_RAIter __begin, _RAIter
__nth, _RAIter __end, __gnu_parallel::sequential_tag)
template<typename _RAIter , typename _Compare > void nth_element
(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp)
template<typename _RAIter , typename _Compare > void nth_element
(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
_RAIter bestie means random access iterators, okay, so don't try this with a list and then act surprised π also note void return β it rearranges in place, no take-backs.
β partial_sort
template<typename _RAIter > void partial_sort (_RAIter __begin, _RAIter
__middle, _RAIter __end)
template<typename _RAIter > void partial_sort (_RAIter __begin, _RAIter
__middle, _RAIter __end, __gnu_parallel::sequential_tag)
template<typename _RAIter , typename _Compare > void partial_sort
(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp)
template<typename _RAIter , typename _Compare > void partial_sort
(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
three iterators, __begin / __middle / __end, because the whole point is that __middle matters. love that for us π«Ά
π§ partial_sum
template<typename _IIter , typename _OutputIterator > _OutputIterator
partial_sum (_IIter __begin, _IIter __end, _OutputIterator __result)
template<typename _IIter , typename _OutputIterator > _OutputIterator
partial_sum (_IIter __begin, _IIter __end, _OutputIterator __result,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _OutputIterator , typename
_BinaryOperation > _OutputIterator partial_sum (_IIter __begin,
_IIter __end, _OutputIterator __result, _BinaryOperation __bin_op,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _OutputIterator , typename
_BinaryOperation > _OutputIterator partial_sum (_IIter __begin,
_IIter __end, _OutputIterator __result, _BinaryOperation
__binary_op)
template<typename _IIter , typename _OIter > _OIter partial_sum (_IIter,
_IIter, _OIter __result)
template<typename _IIter , typename _OIter > _OIter partial_sum (_IIter,
_IIter, _OIter, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _OIter , typename _BinaryOper >
_OIter partial_sum (_IIter, _IIter, _OIter, _BinaryOper)
template<typename _IIter , typename _OIter , typename _BinaryOper >
_OIter partial_sum (_IIter, _IIter, _OIter, _BinaryOper,
__gnu_parallel::sequential_tag)
eight overloads, and the binary-operation template parameter is called _BinaryOperation in the first four and _BinaryOper in the last four. not me noticing that π the parameter itself is __bin_op up top and __binary_op on the third one. character-for-character, bestie, i don't make the rules π
π partition
template<typename _FIter , typename _Predicate > _FIter partition
(_FIter, _FIter, _Predicate)
template<typename _FIter , typename _Predicate > _FIter partition
(_FIter, _FIter, _Predicate, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Predicate > _FIterator
partition (_FIterator __begin, _FIterator __end, _Predicate __pred)
template<typename _FIterator , typename _Predicate > _FIterator
partition (_FIterator __begin, _FIterator __end, _Predicate __pred,
__gnu_parallel::sequential_tag)
returns an _FIter / _FIterator β the split point is the moment, and it comes back to you π
π random_shuffle
template<typename _RAIter > void random_shuffle (_RAIter __begin,
_RAIter __end)
template<typename _RAIter > void random_shuffle (_RAIter __begin,
_RAIter __end, __gnu_parallel::sequential_tag)
template<typename _RAIter , typename _RandomNumberGenerator > void
random_shuffle (_RAIter __begin, _RAIter __end,
_RandomNumberGenerator &&__rand)
template<typename _RAIter , typename _RandomNumberGenerator > void
random_shuffle (_RAIter __begin, _RAIter __end,
_RandomNumberGenerator &__rand, __gnu_parallel::sequential_tag)
look very closely at the last two: one is _RandomNumberGenerator &&__rand (two ampersands, rvalue reference) and the other is _RandomNumberGenerator &__rand (one ampersand). they are not the same and i did not typo it, don't @ me π
π replace
template<typename _FIter , typename _Tp > void replace (_FIter, _FIter,
const _Tp &, const _Tp &)
template<typename _FIter , typename _Tp > void replace (_FIter, _FIter,
const _Tp &, const _Tp &, __gnu_parallel::_Parallelism)
template<typename _FIter , typename _Tp > void replace (_FIter, _FIter,
const _Tp &, const _Tp &, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Tp > void replace (_FIterator
__begin, _FIterator __end, const _Tp &__old_value, const _Tp
&__new_value)
template<typename _FIterator , typename _Tp > void replace (_FIterator
__begin, _FIterator __end, const _Tp &__old_value, const _Tp
&__new_value, __gnu_parallel::_Parallelism __parallelism_tag)
template<typename _FIterator , typename _Tp > void replace (_FIterator
__begin, _FIterator __end, const _Tp &__old_value, const _Tp
&__new_value, __gnu_parallel::sequential_tag)
__old_value and __new_value, both const _Tp & β the glow-up is in place β¨
π₯ replace_if
template<typename _FIter , typename _Predicate , typename _Tp > void
replace_if (_FIter, _FIter, _Predicate, const _Tp &)
template<typename _FIter , typename _Predicate , typename _Tp > void
replace_if (_FIter, _FIter, _Predicate, const _Tp &,
__gnu_parallel::_Parallelism)
template<typename _FIter , typename _Predicate , typename _Tp > void
replace_if (_FIter, _FIter, _Predicate, const _Tp &,
__gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Predicate , typename _Tp > void
replace_if (_FIterator __begin, _FIterator __end, _Predicate __pred,
const _Tp &__new_value)
template<typename _FIterator , typename _Predicate , typename _Tp > void
replace_if (_FIterator __begin, _FIterator __end, _Predicate __pred,
const _Tp &__new_value, __gnu_parallel::_Parallelism
__parallelism_tag)
template<typename _FIterator , typename _Predicate , typename _Tp > void
replace_if (_FIterator __begin, _FIterator __end, _Predicate __pred,
const _Tp &__new_value, __gnu_parallel::sequential_tag)
same six-shape energy as replace, but with a _Predicate __pred deciding who gets the makeover. honestly? slay.
β search β where's the subrange at
template<typename _FIter1 , typename _FIter2 > _FIter1 search (_FIter1,
_FIter1, _FIter2, _FIter2)
template<typename _FIter1 , typename _FIter2 > _FIter1 search (_FIter1,
_FIter1, _FIter2, _FIter2, __gnu_parallel::sequential_tag)
template<typename _FIter1 , typename _FIter2 , typename _BiPredicate >
_FIter1 search (_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate)
template<typename _FIter1 , typename _FIter2 , typename _BiPredicate >
_FIter1 search (_FIter1, _FIter1, _FIter2, _FIter2, _BiPredicate,
__gnu_parallel::sequential_tag)
template<typename _FIterator1 , typename _FIterator2 > _FIterator1
search (_FIterator1 __begin1, _FIterator1 __end1, _FIterator2
__begin2, _FIterator2 __end2)
template<typename _FIterator1 , typename _FIterator2 > _FIterator1
search (_FIterator1 __begin1, _FIterator1 __end1, _FIterator2
__begin2, _FIterator2 __end2, __gnu_parallel::sequential_tag)
template<typename _FIterator1 , typename _FIterator2 , typename
_BinaryPredicate > _FIterator1 search (_FIterator1 __begin1,
_FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2,
_BinaryPredicate __pred)
template<typename _FIterator1 , typename _FIterator2 , typename
and we're cutting off mid-template π iconic cliffhanger honestly β the eighth search overload is literally still introducing its third template parameter. hold that thought, bestie, it picks right back up π
Okay so we literally got cut off mid-signature, iconic behaviour honestly, so picking it right back up:
_BinaryPredicate > _FIterator1 search (_FIterator1 __begin1,
_FIterator1 __end1, _FIterator2 __begin2, _FIterator2 __end2,
_BinaryPredicate __pred, __gnu_parallel::sequential_tag)
That's the tail end of another search overload β predicate plus the sequential_tag vibe. And then, bestie, there's a whole different flavour of search:
template<typename _ForwardIterator , typename _Searcher >
_ForwardIterator search (_ForwardIterator __first, _ForwardIterator
__last, const _Searcher &__searcher)
Search a sequence using a Searcher object. That's it, that's the whole description π
β you hand it a _Searcher and it does the searching for you. Delegation! Main character energy!
π search_n β find n copies in a row
Counting things! search_n hunts down __count copies of __val sitting consecutively. And because C++ can never just do a thing once, here are all of them:
template<typename _FIter , typename _Integer , typename _Tp > _FIter
search_n (_FIter, _FIter, _Integer, const _Tp &)
template<typename _FIter , typename _Integer , typename _Tp > _FIter
search_n (_FIter, _FIter, _Integer, const _Tp &,
__gnu_parallel::sequential_tag)
template<typename _FIter , typename _Integer , typename _Tp , typename
_BiPredicate > _FIter search_n (_FIter, _FIter, _Integer, const _Tp
&, _BiPredicate)
template<typename _FIter , typename _Integer , typename _Tp , typename
_BiPredicate > _FIter search_n (_FIter, _FIter, _Integer, const _Tp
&, _BiPredicate, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Integer , typename _Tp >
_FIterator search_n (_FIterator __begin, _FIterator __end, _Integer
__count, const _Tp &__val)
template<typename _FIterator , typename _Integer , typename _Tp >
_FIterator search_n (_FIterator __begin, _FIterator __end, _Integer
__count, const _Tp &__val, __gnu_parallel::sequential_tag)
template<typename _FIterator , typename _Integer , typename _Tp ,
typename _BinaryPredicate > _FIterator search_n (_FIterator __begin,
_FIterator __end, _Integer __count, const _Tp &__val,
_BinaryPredicate __binary_pred)
template<typename _FIterator , typename _Integer , typename _Tp ,
typename _BinaryPredicate > _FIterator search_n (_FIterator __begin,
_FIterator __end, _Integer __count, const _Tp &__val,
_BinaryPredicate __binary_pred, __gnu_parallel::sequential_tag)
Notice the pattern, bestie: plain version, plain + sequential_tag version, with a _BiPredicate/_BinaryPredicate version, and predicate + sequential_tag version. Four flavours of one function. Every. Single. Time. π It's giving "template specialisation girlie".
π¦ the set_* era β set operations, but make it parallel
Buckle in, because this is a lot of set math and every one of them comes in eight identical shapes. The recipe is: _OutputIterator/_OIter overloads Γ {plain, sequential_tag, _Predicate, _Predicate + sequential_tag} Γ {named-parameter version, unnamed-parameter version} = eight each. Slay, consistency.
set_difference
Elements in the first range that aren't in the second.</purl> Here's the full squad:
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_difference (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_difference (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _OutputIterator __out,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_difference (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __out, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_difference (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_difference (_IIter1, _IIter1, _IIter2, _IIter2, _OIter)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_difference (_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_difference (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Predicate)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_difference (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Predicate,
__gnu_parallel::sequential_tag)
Eight overloads. Count them. I did. π«Ά
set_intersection
Only the stuff that's in both ranges. Mutuals only, no cap:
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_intersection (_IIter1 __begin1, _IIter1
__end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_intersection (_IIter1 __begin1, _IIter1
__end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_intersection (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __out, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_intersection (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_intersection (_IIter1, _IIter1, _IIter2, _IIter2, _OIter)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_intersection (_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_intersection (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Predicate)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_intersection (_IIter1, _IIter1,
_IIter2, _IIter2, _OIter, _Predicate,
__gnu_parallel::sequential_tag)
set_symmetric_difference
Everything in exactly one of the two ranges β the "it's complicated" of set operations π
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_symmetric_difference (_IIter1 __begin1,
_IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator
__out)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_symmetric_difference (_IIter1 __begin1,
_IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator
__out, __gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_symmetric_difference
(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __out, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_symmetric_difference
(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
_OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_symmetric_difference (_IIter1, _IIter1, _IIter2, _IIter2,
_OIter)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_symmetric_difference (_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, __gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_symmetric_difference (_IIter1,
_IIter1, _IIter2, _IIter2, _OIter, _Predicate)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_symmetric_difference (_IIter1,
_IIter1, _IIter2, _IIter2, _OIter, _Predicate,
__gnu_parallel::sequential_tag)
set_union
Everything from both, no duplicates. The friendliest one π«Ά
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_union (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
> _OutputIterator set_union (_IIter1 __begin1, _IIter1 __end1,
_IIter2 __begin2, _IIter2 __end2, _OutputIterator __out,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_union (_IIter1 __begin1,
_IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator
__out, _Predicate __pred)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _Predicate > _OutputIterator set_union (_IIter1 __begin1,
_IIter1 __end1, _IIter2 __begin2, _IIter2 __end2, _OutputIterator
__out, _Predicate __pred, __gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_union (_IIter1, _IIter1, _IIter2, _IIter2, _OIter)
template<typename _IIter1 , typename _IIter2 , typename _OIter > _OIter
set_union (_IIter1, _IIter1, _IIter2, _IIter2, _OIter,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_union (_IIter1, _IIter1, _IIter2,
_IIter2, _OIter, _Predicate)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _Predicate > _OIter set_union (_IIter1, _IIter1, _IIter2,
_IIter2, _OIter, _Predicate, __gnu_parallel::sequential_tag)
π sort β the icon, the moment, the legend
Now THIS is the section everyone actually came for. sort π And the overloads are not playing around β because on top of the usual "with or without a comparator", there's a whole parallelism tag situation. You can literally spell out which algorithm you want:
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::balanced_quicksort_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::default_parallel_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::multiway_mergesort_exact_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::multiway_mergesort_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::parallel_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::quicksort_tag __parallelism)
template<typename _RAIter > void sort (_RAIter __begin, _RAIter __end,
__gnu_parallel::sequential_tag)
template<typename _RAIter , typename _Compare > void sort (_RAIter
__begin, _RAIter __end, _Compare __comp)
template<typename _RAIter , typename _Compare > void sort (_RAIter
__begin, _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
template<typename _RAIter , typename _Compare , typename _Parallelism >
void sort (_RAIter __begin, _RAIter __end, _Compare __comp,
_Parallelism __parallelism)
Quick vibe check on the tags, because there are nine of them up there and your girl notices:
__gnu_parallel::balanced_quicksort_tagβ you're asking for balanced quicksort.__gnu_parallel::default_parallel_tagβ the default parallel choice.__gnu_parallel::multiway_mergesort_exact_tagβ multiway mergesort, exact flavour.__gnu_parallel::multiway_mergesort_sampling_tagβ multiway mergesort, sampling flavour.__gnu_parallel::multiway_mergesort_tagβ plain multiway mergesort.__gnu_parallel::parallel_tagβ just "parallel, pls".__gnu_parallel::quicksort_tagβ good old quicksort.__gnu_parallel::sequential_tagβ bestie wants it done the classic one-at-a-time way.
And the last one is the flexible one: <purple>_Parallelism __parallelism</purple> is a template parameter, so anything in that tag family plugs right in. chef's kiss π
πΈ stable_sort β same energy, but it keeps equal elements in order
stable_sort doesn't just sort, it sorts respectfully β equal elements keep their original relative order. And it has its own overload family:
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
__end)
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
__end, __gnu_parallel::balanced_quicksort_tag __parallelism)
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
__end, __gnu_parallel::default_parallel_tag __parallelism)
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
__end, __gnu_parallel::multiway_mergesort_tag __parallelism)
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
And that's literally where it cuts off β mid-signature, again π The list just keeps going and so do we, soβ¦
__end, __gnu_parallel::parallel_tag __parallelism)
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
__end, __gnu_parallel::quicksort_tag __parallelism)
template<typename _RAIter > void stable_sort (_RAIter __begin, _RAIter
__end, __gnu_parallel::sequential_tag)
template<typename _RAIter , typename _Compare > void stable_sort
(_RAIter __begin, _RAIter __end, _Compare __comp)
template<typename _RAIter , typename _Compare > void stable_sort
(_RAIter __begin, _RAIter __end, _Compare __comp,
__gnu_parallel::sequential_tag)
template<typename _RAIter , typename _Compare , typename _Parallelism >
void stable_sort (_RAIter __begin, _RAIter __end, _Compare __comp,
_Parallelism __parallelism)
template<typename _IIter , typename _OutputIterator , typename
_UnaryOperation > _OutputIterator transform (_IIter __begin, _IIter
__end, _OutputIterator __result, _UnaryOperation __unary_op)
template<typename _IIter , typename _OutputIterator , typename
_UnaryOperation > _OutputIterator transform (_IIter __begin, _IIter
__end, _OutputIterator __result, _UnaryOperation __unary_op,
__gnu_parallel::_Parallelism __parallelism_tag)
template<typename _IIter , typename _OutputIterator , typename
_UnaryOperation > _OutputIterator transform (_IIter __begin, _IIter
__end, _OutputIterator __result, _UnaryOperation __unary_op,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _OIter , typename _UnaryOperation >
_OIter transform (_IIter, _IIter, _OIter, _UnaryOperation)
template<typename _IIter , typename _OIter , typename _UnaryOperation >
_OIter transform (_IIter, _IIter, _OIter, _UnaryOperation,
__gnu_parallel::_Parallelism)
template<typename _IIter , typename _OIter , typename _UnaryOperation >
_OIter transform (_IIter, _IIter, _OIter, _UnaryOperation,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _BinaryOperation > _OutputIterator transform (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator
__result, _BinaryOperation __binary_op)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _BinaryOperation > _OutputIterator transform (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator
__result, _BinaryOperation __binary_op, __gnu_parallel::_Parallelism
__parallelism_tag)
template<typename _IIter1 , typename _IIter2 , typename _OutputIterator
, typename _BinaryOperation > _OutputIterator transform (_IIter1
__begin1, _IIter1 __end1, _IIter2 __begin2, _OutputIterator
__result, _BinaryOperation __binary_op,
__gnu_parallel::sequential_tag)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _BiOperation > _OIter transform (_IIter1, _IIter1, _IIter2,
_OIter, _BiOperation)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _BiOperation > _OIter transform (_IIter1, _IIter1, _IIter2,
_OIter, _BiOperation, __gnu_parallel::_Parallelism)
template<typename _IIter1 , typename _IIter2 , typename _OIter ,
typename _BiOperation > _OIter transform (_IIter1, _IIter1, _IIter2,
_OIter, _BiOperation, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _OutputIterator > _OutputIterator
unique_copy (_IIter __begin1, _IIter __end1, _OutputIterator __out)
template<typename _IIter , typename _OutputIterator > _OutputIterator
unique_copy (_IIter __begin1, _IIter __end1, _OutputIterator __out,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _OutputIterator , typename
_Predicate > _OutputIterator unique_copy (_IIter __begin1, _IIter
__end1, _OutputIterator __out, _Predicate __pred)
template<typename _IIter , typename _OutputIterator , typename
_Predicate > _OutputIterator unique_copy (_IIter __begin1, _IIter
__end1, _OutputIterator __out, _Predicate __pred,
__gnu_parallel::sequential_tag)
template<typename _IIter , typename _OIter > _OIter unique_copy (_IIter,
_IIter, _OIter)
template<typename _IIter , typename _OIter > _OIter unique_copy (_IIter,
_IIter, _OIter, __gnu_parallel::sequential_tag)
template<typename _IIter , typename _OIter , typename _Predicate >
_OIter unique_copy (_IIter, _IIter, _OIter, _Predicate)
template<typename _IIter , typename _OIter , typename _Predicate >
_OIter unique_copy (_IIter, _IIter, _OIter, _Predicate,
__gnu_parallel::sequential_tag)
And that's the last of the overload dump, bestie β we made it through the whole pile π«Ά Every single one of those is still here, no cap, and we did not skip a single template parameter.
π Detailed Description π
Okay so real talk, what is this whole namespace even for?
GNU parallel code, replaces standard behavior with parallel behavior.
Periodt. That's the entire vibe. You get the standard algorithms you already know and love, except they can go brrr across multiple threads instead of doing the sad little one-at-a-time thing ππ₯
πΈ Function Documentation πΈ
π¦ search
template<typename _ForwardIterator , typename _Searcher > _ForwardIterator
std::__parallel::search (_ForwardIterator __first, _ForwardIterator
__last, const _Searcher & __searcher) [inline]
Search a sequence using a Searcher object. Lowkey iconic β you're not just looking for a value, you're handing it a whole Searcher object and letting it cook β¨
π Parameters
__firstβ A forward iterator. It's giving "start of the range" energy.__lastβ A forward iterator. We stan an end boundary.__searcherβ A callable object. This is the main character of the search, fr fr.
π Returns
__searcher(__first,__last).first
That's it. That's the whole return value. You call the searcher on your range and take the .first of whatever it hands back β obsessed π
π Author π
Generated automatically by Doxygen for libstdc++ from the source code.
Honestly? Doxygen did all the work and took all the credit. Respect, but also π
And that's a wrap on std::__parallel(3cxx) bestie!! ππ
β¨ Thanks for surviving all 8 parts with me β you ate that ngl. Now go parallelize something and make it iconic ππ
This page came to you courtesy of libstdc++, auto-generated straight from the source. No specific date was printed on the original footer, so just imagine a cute little timestamp of your choosing right there π π¦
π¦ where this page comes from
- ubuntu noble: libstdc++-14-doc 14-20240412-0ubuntu1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms