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 for std::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 🌸

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