__gnu_parallel(3cxx)

โœจ NAME โœจ

okay bestie, welcome to the __gnu_parallel(3cxx) page ๐Ÿ’… โ€” __gnu_parallel is literally the GNU parallel code for public use. that's the whole name vibe, no cap.


๐ŸŒธ SYNOPSIS ๐ŸŒธ

this page is the master list of the public parallel machinery: a whole pile of classes and structs, some typedefs, and the enums. it's giving legendary template energy, so stay with me โœจ

๐Ÿ’… Classes

  • __accumulate_binop_reduct โ€” general reduction using a binary operator. lowkey the reduce bestie.
  • __accumulate_selector โ€” the std::accumulate() selector. slay.
  • __adjacent_difference_selector โ€” selector that gives back the difference between two adjacent __elements.
  • __adjacent_find_selector โ€” tests a predicate on two adjacent elements.
  • __binder1st โ€” like std::binder1st, but it hands the argument types over explicitly.
  • __binder2nd โ€” same deal as std::binder2nd, with the argument types given explicitly.
  • __count_if_selector โ€” the std::count_if () selector.
  • __count_selector โ€” the std::count() selector.
  • __fill_selector โ€” the std::fill() selector.
  • __find_first_of_selector โ€” tests a predicate on several elements.
  • __find_if_selector โ€” tests a predicate on a single element, and it's used for std::find() and std::find_if ().
  • __for_each_selector โ€” the std::for_each() selector.
  • __generate_selector โ€” the std::generate() selector.
  • __generic_find_selector โ€” base class of all __gnu_parallel::__find_template selectors.
  • __generic_for_each_selector โ€” generic __selector for embarrassingly parallel functions.
  • __identity_selector โ€” selector that just returns the iterator you passed in. no thoughts, just vibes.
  • __inner_product_selector โ€” the std::inner_product() selector.
  • __max_element_reduct โ€” reduction for finding the maximum element, using a comparator.
  • __min_element_reduct โ€” reduction for finding the maximum element, using a comparator. yes, the page says maximum here too โ€” I'm just reporting the facts ๐Ÿซถ
  • __mismatch_selector โ€” tests an inverted predicate on a single element.
  • __multiway_merge_3_variant_sentinel_switch โ€” switch for 3-way merging with __sentinels turned off.
  • __multiway_merge_3_variant_sentinel_switch< true, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare > โ€” switch for 3-way merging with __sentinels turned on.
  • __multiway_merge_4_variant_sentinel_switch โ€” switch for 4-way merging with __sentinels turned off.
  • __multiway_merge_4_variant_sentinel_switch< true, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare > โ€” switch for 4-way merging with __sentinels turned on.
  • __multiway_merge_k_variant_sentinel_switch โ€” switch for k-way merging with __sentinels turned on.
  • __multiway_merge_k_variant_sentinel_switch< false, __stable, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare > โ€” switch for k-way merging with __sentinels turned off.
  • __replace_if_selector โ€” the std::replace() selector.
  • __replace_selector โ€” the std::replace() selector.
  • __transform1_selector โ€” std::transform() __selector, one input sequence variant.
  • __transform2_selector โ€” std::transform() __selector, two input sequences variant.
  • __unary_negate โ€” like std::unary_negate, but with the argument types given explicitly.
  • _DRandomShufflingGlobalData โ€” data known to every thread participating in __gnu_parallel::__parallel_random_shuffle().
  • _DRSSorterPU โ€” local data for a thread participating in __gnu_parallel::__parallel_random_shuffle().
  • _DummyReduct โ€” reduction function doing absolutely nothing. iconic.
  • _EqualFromLess โ€” builds an equality predicate from a strict weak ordering predicate.
  • _EqualTo โ€” like std::equal_to, but it allows two different types.
  • _GuardedIterator โ€” _Iterator wrapper supporting an implicit supremum at the end of the sequence, dominating all comparisons.
  • _IteratorPair โ€” a pair of iterators. the usual iterator operations are applied to both child iterators.
  • _IteratorTriple โ€” a triple of iterators. the usual iterator operations are applied to all three child iterators.
  • _Job โ€” one __job for a certain thread.
  • _Less โ€” like std::less, but it allows two different types.
  • _Lexicographic โ€” compares a pair of types lexicographically, ascending.
  • _LexicographicReverse โ€” compares a pair of types lexicographically, descending.
  • _LoserTree โ€” stable _LoserTree variant.
  • _LoserTree< false, _Tp, _Compare > โ€” unstable _LoserTree variant.
  • _LoserTreeBase โ€” guarded loser/tournament tree.
  • _LoserTreePointer โ€” stable _LoserTree implementation.
  • _LoserTreePointer< false, _Tp, _Compare > โ€” unstable _LoserTree implementation.
  • _LoserTreePointerBase โ€” base class of _Loser Tree implementation using pointers.
  • _LoserTreePointerUnguarded โ€” stable unguarded _LoserTree variant storing pointers.
  • _LoserTreePointerUnguarded< false, _Tp, _Compare > โ€” unstable unguarded _LoserTree variant storing pointers.
  • _LoserTreePointerUnguardedBase โ€” unguarded loser tree, keeping only pointers to the elements in the tree structure.
  • _LoserTreeTraits โ€” traits for determining whether the loser tree should use pointers or copies.
  • _LoserTreeUnguarded โ€” stable implementation of unguarded _LoserTree.
  • _LoserTreeUnguarded< false, _Tp, _Compare > โ€” non-stable implementation of unguarded _LoserTree.
  • _LoserTreeUnguardedBase โ€” base class for unguarded _LoserTree implementation.
  • _Multiplies โ€” like std::multiplies, but it allows two different types.
  • _Nothing โ€” functor doing nothing.
  • _Piece โ€” subsequence description.
  • _Plus โ€” like std::plus, but it allows two different types.
  • _PMWMSSortingData โ€” data accessed by all threads.
  • _PseudoSequence โ€” sequence that conceptually consists of multiple copies of the same element. the copies are not stored explicitly, of course.
  • _PseudoSequenceIterator โ€” _Iterator associated with __gnu_parallel::_PseudoSequence. it features the usual random-access iterator functionality.
  • _QSBThreadLocal โ€” information local to one thread in the parallel quicksort run.
  • _RandomNumber โ€” random number generator based on the Mersenne twister.
  • _RestrictedBoundedConcurrentQueue โ€” double-ended queue of bounded size, allowing lock-free atomic access. push_front() and pop_front() must not be called concurrently to each other, while pop_back() can be called concurrently at all times. empty(), size(), and top() are intentionally not provided โ€” calling them would not make sense in a concurrent setting. periodt.
  • _SamplingSorter โ€” stable sorting functor.
  • _SamplingSorter< false, _RAIter, _StrictWeakOrdering > โ€” non-__stable sorting functor.
  • _Settings โ€” class _Settings run-time settings for the parallel mode, including all tunable parameters.
  • _SplitConsistently โ€” split consistently.
  • _SplitConsistently< false, _RAIter, _Compare, _SortingPlacesIterator > โ€” split by sampling.
  • _SplitConsistently< true, _RAIter, _Compare, _SortingPlacesIterator > โ€” split by exact splitting.
  • balanced_quicksort_tag โ€” forces parallel sorting using balanced quicksort at compile time.
  • balanced_tag โ€” recommends parallel execution using dynamic load-balancing at compile time.
  • constant_size_blocks_tag โ€” selects the constant block size variant for std::find().
  • default_parallel_tag โ€” recommends parallel execution using the default parallel algorithm.
  • equal_split_tag โ€” selects the equal splitting variant for std::find().
  • exact_tag โ€” forces parallel merging with exact splitting, at compile time.
  • find_tag โ€” base class for for std::find() variants.
  • growing_blocks_tag โ€” selects the growing block size variant for std::find().
  • multiway_mergesort_exact_tag โ€” forces parallel sorting using multiway mergesort with exact splitting at compile time.
  • multiway_mergesort_sampling_tag โ€” forces parallel sorting using multiway mergesort with splitting by sampling at compile time.
  • multiway_mergesort_tag โ€” forces parallel sorting using multiway mergesort at compile time.
  • omp_loop_static_tag โ€” recommends parallel execution using OpenMP static load-balancing at compile time.
  • omp_loop_tag โ€” recommends parallel execution using OpenMP dynamic load-balancing at compile time.
  • parallel_tag โ€” recommends parallel execution at compile time, optionally using a user-specified number of threads.
  • quicksort_tag โ€” forces parallel sorting using unbalanced quicksort at compile time.
  • sampling_tag โ€” forces parallel merging with exact splitting, at compile time.
  • sequential_tag โ€” forces sequential execution at compile time.
  • unbalanced_tag โ€” recommends parallel execution using static load-balancing at compile time.

โœจ Typedefs

  • _BinIndex โ€” typedef unsigned short. type to hold the index of a bin.
  • _CASable โ€” typedef int64_t. longest compare-and-swappable integer type on this platform.
  • _SequenceIndex โ€” typedef uint64_t. unsigned integer to index __elements. the total number of elements for each algorithm must fit into this type.
  • _ThreadIndex โ€” typedef uint16_t. unsigned integer to index a thread number. the maximum thread number (for each processor) must fit into this type.

๐ŸŽ€ Enumerations

  • _AlgorithmStrategy { heuristic, force_sequential, force_parallel } โ€” strategies for run-time algorithm selection.
  • _FindAlgorithm { GROWING_BLOCKS, CONSTANT_SIZE_BLOCKS, EQUAL_SPLIT } โ€” find algorithms.
  • _MultiwayMergeAlgorithm { LOSER_TREE } โ€” merging algorithms.
  • _Parallelism { sequential, parallel_unbalanced, parallel_balanced, parallel_omp_loop, parallel_omp_loop_static, parallel_taskqueue } โ€” run-time equivalents for the compile-time tags.
  • _PartialSumAlgorithm { RECURSIVE, LINEAR } โ€” partial sum algorithms: recursive, linear.
  • _SortAlgorithm { MWMS, QS, QS_BALANCED } โ€” sorting algorithms.
  • _SplittingAlgorithm { SAMPLING, EXACT } โ€” sorting/merging algorithms: sampling, __exact.

โœจ Functions โœจ

Okay bestie, buckle up ๐Ÿ’– โ€” this is the big function list, like the entire backstage crew of the library, and every single signature is coming with us. Some of them have a lil blurb attached, some are just the signature and the vibes, and honestly? We respect both.

  • template<typename _Tp > _Tp __add_omp (volatile _Tp *__ptr, _Tp __addend) โ€” no description on this one, just the signature doing its thing ๐Ÿซถ
  • template<typename _RAIter , typename _DifferenceTp > void __calc_borders (_RAIter __elements, _DifferenceTp __length, _DifferenceTp *__off) โ€” precalculates the __advances for the Knuth-Morris-Pratt algorithm. Literally the prep work so KMP can slay later โœจ
  • template<typename _Tp > bool __cas_omp (volatile _Tp *__ptr, _Tp __comparand, _Tp __replacement) โ€” signature only, no extra notes, we move ๐Ÿ’…
  • template<typename _Tp > bool __compare_and_swap (volatile _Tp *__ptr, _Tp __comparand, _Tp __replacement) โ€” compare-and-swap. That's the entire note, short and iconic ๐Ÿ‘‘
  • template<typename _IIter , typename _OutputIterator > _OutputIterator __copy_tail (std::pair< _IIter, _IIter > __b, std::pair< _IIter, _IIter > __e, _OutputIterator __r) โ€” no blurb here either, just take the signature as given ๐ŸŽ€
  • void __decode2 (_CASable __x, int &__a, int &__b) โ€” decodes two integers out of one gnu_parallel::_CASable. Two-for-one situation, lowkey efficient ๐Ÿฆ‹
  • template<typename _RAIter , typename _DifferenceTp > void __determine_samples (_PMWMSSortingData< _RAIter > *__sd, _DifferenceTp __num_samples) โ€” selects _M_samples from a sequence. Note the underscore, bestie, it's _M_samples, don't come for me ๐Ÿ’€
  • _CASable __encode2 (int __a, int __b) โ€” encodes two integers into one gnu_parallel::_CASable. The exact reverse of the girl above, we love a matching set ๐ŸŒธ
  • template<typename _DifferenceType , typename _OutputIterator > _OutputIterator __equally_split (_DifferenceType __n, _ThreadIndex __num_threads, _OutputIterator __s) โ€” a function to split a sequence into parts of almost equal size. Almost, okay, nobody's perfect ๐Ÿ™ˆ
  • template<typename _DifferenceType > _DifferenceType __equally_split_point (_DifferenceType __n, _ThreadIndex __num_threads, _ThreadIndex __thread_no) โ€” also a function to split a sequence into parts of almost equal size, except this one hands you the point โœจ
  • template<typename _Tp > _Tp __fetch_and_add (volatile _Tp *__ptr, _Tp __addend) โ€” adds a value to a variable, atomically. No race conditions invited to this party ๐Ÿ”ฅ
  • template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename _Selector > std::pair< _RAIter1, _RAIter2 > __find_template (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector) โ€” parallel std::find, switching between different algorithms depending on what you hand it ๐Ÿงš
  • template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename _Selector > std::pair< _RAIter1, _RAIter2 > __find_template (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, constant_size_blocks_tag) โ€” parallel std::find, the constant block size variant ๐ŸŽ€
  • template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename _Selector > std::pair< _RAIter1, _RAIter2 > __find_template (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, equal_split_tag) โ€” parallel std::find, the equal splitting variant ๐Ÿ’œ
  • template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename _Selector > std::pair< _RAIter1, _RAIter2 > __find_template (_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector, growing_blocks_tag) โ€” parallel std::find, the growing block size variant. Four flavours, all valid ๐ŸŒˆ
  • template<typename _IIter , typename _UserOp , typename _Functionality , typename _Red , typename _Result > _UserOp __for_each_template_random_access (_IIter __begin, _IIter __end, _UserOp __user_op, _Functionality &__functionality, _Red __reduction, _Result __reduction_start, _Result &__output, typename std::iterator_traits< _IIter >::difference_type __bound, _Parallelism __parallelism_tag) โ€” picks the algorithm you want by checking out __parallelism_tag ๐Ÿ‘‘
  • template<typename _RAIter , typename _Op , typename _Fu , typename _Red , typename _Result > _Op __for_each_template_random_access_ed (_RAIter __begin, _RAIter __end, _Op __o, _Fu &__f, _Red __r, _Result __base, _Result &__output, typename std::iterator_traits< _RAIter >::difference_type __bound) โ€” the embarrassingly parallel algorithm for random access iterators, using hand-crafted parallelization by equal splitting the work. Hand-crafted, bestie, artisanal parallelization ๐Ÿ’…
  • template<typename _RAIter , typename _Op , typename _Fu , typename _Red , typename _Result > _Op __for_each_template_random_access_omp_loop (_RAIter __begin, _RAIter __end, _Op __o, _Fu &__f, _Red __r, _Result __base, _Result &__output, typename std::iterator_traits< _RAIter >::difference_type __bound) โ€” the embarrassingly parallel algorithm for random access iterators, using an OpenMP for loop โœจ
  • template<typename _RAIter , typename _Op , typename _Fu , typename _Red , typename _Result > _Op __for_each_template_random_access_omp_loop_static (_RAIter __begin, _RAIter __end, _Op __o, _Fu &__f, _Red __r, _Result __base, _Result &__output, typename std::iterator_traits< _RAIter >::difference_type __bound) โ€” same embarrassingly parallel algorithm for random access iterators, but with an OpenMP for loop using static scheduling ๐Ÿฆ‹
  • template<typename _RAIter , typename _Op , typename _Fu , typename _Red , typename _Result > _Op __for_each_template_random_access_workstealing (_RAIter __begin, _RAIter __end, _Op __op, _Fu &__f, _Red __r, _Result __base, _Result &__output, typename std::iterator_traits< _RAIter >::difference_type __bound) โ€” the work stealing algorithm for random access iterators. Note it's __op here, not __o โ€” little details, we notice them ๐Ÿ™ˆ
  • _ThreadIndex __get_max_threads () โ€” signature only, no blurb, mysterious main character energy ๐Ÿ’€
  • bool __is_parallel (const _Parallelism __p) โ€” also just the signature. Giving nothing, serving everything ๐ŸŒธ
  • template<typename _IIter , typename _Compare > bool __is_sorted (_IIter __begin, _IIter __end, _Compare __comp) โ€” checks whether [__begin, __end) is sorted according to __comp. The vibe check of sequences โœ…
  • template<typename _RAIter , typename _Compare > _RAIter __median_of_three_iterators (_RAIter __a, _RAIter __b, _RAIter __c, _Compare __comp) โ€” computes the median of three referenced elements, according to __comp ๐ŸŽ€
  • template<typename _RAIter1 , typename _RAIter2 , typename _OutputIterator , typename _DifferenceTp , typename _Compare > _OutputIterator __merge_advance (_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) โ€” a merge routine that can only merge the __max_length smallest elements ๐Ÿ”ฅ
  • template<typename _RAIter1 , typename _RAIter2 , typename _OutputIterator , typename _DifferenceTp , typename _Compare > _OutputIterator __merge_advance_movc (_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) โ€” another merge routine that can only merge the __max_length smallest elements ๐Ÿงš
  • template<typename _RAIter1 , typename _RAIter2 , typename _OutputIterator , typename _DifferenceTp , typename _Compare > _OutputIterator __merge_advance_usual (_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp) โ€” and a third merge routine that can only merge the __max_length smallest elements. Three of them, all saying the same line, iconic behaviour honestly ๐ŸŒˆ
  • template<typename _RAIter1 , typename _RAIter3 , typename _Compare > _RAIter3 __parallel_merge_advance (_RAIter1 &__begin1, _RAIter1 __end1, _RAIter1 &__begin2, _RAIter1 __end2, _RAIter3 __target, typename std::iterator_traits< _RAIter1 >::difference_type __max_length, _Compare __comp) โ€” a parallel merge routine that can only merge the __max_length smallest elements ๐Ÿ‘‘
  • template<typename _RAIter1 , typename _RAIter2 , typename _RAIter3 , typename _Compare > _RAIter3 __parallel_merge_advance (_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _RAIter3 __target, typename std::iterator_traits< _RAIter1 >::difference_type __max_length, _Compare __comp) โ€” the merge routine that falls back to sequential in case the iterators of the two input sequences are of different type. Plan B, but make it cute ๐Ÿ’œ
  • template<typename _RAIter , typename _Compare > void __parallel_nth_element (_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp) โ€” parallel implementation of std::nth_element() โœจ
  • template<typename _RAIter , typename _Compare > void __parallel_partial_sort (_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp) โ€” parallel implementation of std::partial_sort() ๐Ÿ’…
  • template<typename _IIter , typename _OutputIterator , typename _BinaryOperation > _OutputIterator __parallel_partial_sum (_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op) โ€” parallel partial sum, front-__end. Yes the original says front-__end, we're keeping it ๐Ÿซถ
  • template<typename _IIter , typename _OutputIterator , typename _BinaryOperation > _OutputIterator __parallel_partial_sum_basecase (_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits< _IIter >::value_type __value) โ€” the base case prefix sum routine, the lil foundation of the whole thing ๐ŸŽ€
  • template<typename _IIter , typename _OutputIterator , typename _BinaryOperation > _OutputIterator __parallel_partial_sum_linear (_IIter __begin, _IIter __end, _OutputIterator __result, _BinaryOperation __bin_op, typename std::iterator_traits< _IIter >::difference_type __n) โ€” the parallel partial sum implementation: two-phase approach, and no recursion ๐ŸŒธ
  • template<typename _RAIter , typename _Predicate > std::iterator_traits< _RAIter >::difference_type __parallel_partition (_RAIter __begin, _RAIter __end, _Predicate __pred, _ThreadIndex __num_threads) โ€” parallel implementation of std::partition ๐Ÿ”ฅ
  • template<typename _RAIter , typename _RandomNumberGenerator > void __parallel_random_shuffle (_RAIter __begin, _RAIter __end, _RandomNumberGenerator __rng=_RandomNumber()) โ€” parallel random public call. Default arg is right there, __rng=_RandomNumber(), don't miss it ๐Ÿ‘€
  • template<typename _RAIter , typename _RandomNumberGenerator > void __parallel_random_shuffle_drs (_RAIter __begin, _RAIter __end, typename std::iterator_traits< _RAIter >::difference_type __n, _ThreadIndex __num_threads, _RandomNumberGenerator &__rng) โ€” the main parallel random shuffle step, the big one ๐Ÿงš
  • template<typename _RAIter , typename _RandomNumberGenerator > void __parallel_random_shuffle_drs_pu (_DRSSorterPU< _RAIter, _RandomNumberGenerator > *__pus) โ€” the random shuffle code that each thread actually executes. Teamwork, but make it shuffling ๐Ÿ’œ
  • template<typename _IIter , typename _OutputIterator , typename _Compare > _OutputIterator __parallel_set_difference (_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) โ€” signature only, no blurb attached, we take it ๐Ÿ’€
  • template<typename _IIter , typename _OutputIterator , typename _Compare > _OutputIterator __parallel_set_intersection (_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) โ€” same deal, no description, just vibes ๐ŸŒˆ
  • template<typename _IIter , typename _OutputIterator , typename _Operation > _OutputIterator __parallel_set_operation (_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, โ€” this one's signature trails right off the edge of the page ๐Ÿ˜ญ hold that thought, it keeps going in a sec.
  • template<typename _IIter , typename _OutputIterator , typename _Compare > _OutputIterator __parallel_set_symmetric_difference (_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) โ€” the symmetric-difference set op, parallel-flavored. The page gives it no blurb, so that's all we've got, bestie โœจ
  • template<typename _IIter , typename _OutputIterator , typename _Compare > _OutputIterator __parallel_set_union (_IIter __begin1, _IIter __end1, _IIter __begin2, _IIter __end2, _OutputIterator __result, _Compare __comp) โ€” and the union one, same deal. No description in the source, no cap ๐Ÿซถ

the __parallel_sort glow-up squad ๐Ÿ‘‘

Okay so there's one generic __parallel_sort and then a whole little clique of overloads that each pick a different algorithm for you based on the tag you hand over. It's giving "choose your fighter."

  • template<bool __stable, typename _RAIter , typename _Compare , typename _Parallelism > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, _Parallelism __parallelism) โ€” the generic one, takes whatever _Parallelism you throw at it.
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, balanced_quicksort_tag __parallelism) โ€” choose balanced quicksort for parallel sorting ๐Ÿ’…
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, default_parallel_tag __parallelism) โ€” choose multiway mergesort with exact splitting, for parallel sorting.
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_exact_tag __parallelism) โ€” choose multiway mergesort with exact splitting, for parallel sorting (yes, same wording as the default one โ€” that's genuinely what the page says ๐Ÿซ ).
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_sampling_tag __parallelism) โ€” choose multiway mergesort with splitting by sampling, for parallel sorting.
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, multiway_mergesort_tag __parallelism) โ€” choose multiway mergesort, splitting variant decided at run-time, for parallel sorting.
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, parallel_tag __parallelism) โ€” choose a parallel sorting algorithm. Vague on purpose, iconic behavior.
  • template<bool __stable, typename _RAIter , typename _Compare > void __parallel_sort (_RAIter __begin, _RAIter __end, _Compare __comp, quicksort_tag __parallelism) โ€” choose quicksort for parallel sorting.

the quicksort internals ๐ŸŒ€

These are the machinery behind the quicksort tags โ€” lowkey the main characters of the sort implementation, highkey not something you call yourself.

  • template<typename _RAIter , typename _Compare > void __parallel_sort_qs (_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) โ€” unbalanced quicksort main call.
  • template<typename _RAIter , typename _Compare > void __parallel_sort_qs_conquer (_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) โ€” unbalanced quicksort conquer step.
  • template<typename _RAIter , typename _Compare > std::iterator_traits< _RAIter >::difference_type __parallel_sort_qs_divide (_RAIter __begin, _RAIter __end, _Compare __comp, typename std::iterator_traits< _RAIter >::difference_type __pivot_rank, typename std::iterator_traits< _RAIter >::difference_type __num_samples, _ThreadIndex __num_threads) โ€” unbalanced quicksort divide step.
  • template<typename _RAIter , typename _Compare > void __parallel_sort_qsb (_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) โ€” top-level quicksort routine โœจ
  • template<typename _RAIter , typename _Compare > void __qsb_conquer (_QSBThreadLocal< _RAIter > **__tls, _RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __iam, _ThreadIndex __num_threads, bool __parent_wait) โ€” quicksort conquer step (the qsb branch this time).
  • template<typename _RAIter , typename _Compare > std::iterator_traits< _RAIter >::difference_type __qsb_divide (_RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __num_threads) โ€” balanced quicksort divide step.
  • template<typename _RAIter , typename _Compare > void __qsb_local_sort_with_helping (_QSBThreadLocal< _RAIter > **__tls, _Compare &__comp, _ThreadIndex __iam, bool __wait) โ€” quicksort step doing load-balanced local sort. Helping hands fr fr ๐Ÿซถ

tiny math + random helpers ๐ŸŽ€

  • template<typename _RandomNumberGenerator > int __random_number_pow2 (int __logp, _RandomNumberGenerator &__rng) โ€” generate a random number in [0,2^__logp).
  • template<typename _Size > _Size __rd_log2 (_Size __n) โ€” calculates the rounded-down logarithm of __n for base 2.
  • template<typename _Tp > _Tp __round_up_to_pow2 (_Tp __x) โ€” round up to the next greater power of 2 โญ

search, merge-ish, and shuffle-adjacent ๐ŸŒˆ

  • template<typename __RAIter1 , typename __RAIter2 , typename _Pred > __RAIter1 __search_template (__RAIter1 __begin1, __RAIter1 __end1, __RAIter2 __begin2, __RAIter2 __end2, _Pred __pred) โ€” parallel std::search.
  • template<bool __stable, bool __sentinels, typename _RAIterIterator , typename _RAIter3 , typename _DifferenceTp , typename _Compare > _RAIter3 __sequential_multiway_merge (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const typename std::iterator_traits< typename std::iterator_traits< _RAIterIterator >::value_type::first_type >::value_type &__sentinel, _DifferenceTp __length, _Compare __comp) โ€” the sequential multi-way merging switch (the one that decides the strategy).
  • template<typename _RAIter , typename _RandomNumberGenerator > void __sequential_random_shuffle (_RAIter __begin, _RAIter __end, _RandomNumberGenerator &__rng) โ€” sequential, cache-efficient random shuffle. Yes bestie, cache-efficient and random ๐Ÿ’…

range-shrinking era ๐Ÿฆ‹

  • template<typename _IIter > void __shrink (std::vector< _IIter > &__os_starts, size_t &__count_to_two, size_t &__range_length) โ€” combines two ranges into one, and thus halves the number of ranges.
  • template<typename _IIter > void __shrink_and_double (std::vector< _IIter > &__os_starts, size_t &__count_to_two, size_t &__range_length, const bool __make_twice) โ€” shrinks and doubles the ranges. Growth mindset, honestly.

odds and ends ๐Ÿ“

  • void __yield () โ€” yield control to another thread, without waiting for the end of the time slice. Politely stepping aside, no waiting around.
  • template<typename _IIter , typename _FunctorType > size_t list_partition (const _IIter __begin, const _IIter __end, _IIter *__starts, size_t *__lengths, const int __num_parts, _FunctorType &__f, int __oversampling=0) โ€” splits a sequence given by input iterators into parts of almost equal size. Note the default: __oversampling=0.
  • template<typename _Tp > const _Tp & max (const _Tp &__a, const _Tp &__b) โ€” equivalent to std::max.
  • template<typename _Tp > const _Tp & min (const _Tp &__a, const _Tp &__b) โ€” equivalent to std::min.
  • template<typename _RanSeqs , typename _RankType , typename _RankIterator , typename _Compare > void multiseq_partition (_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator __begin_offsets, _Compare __comp=std::less< typename std::iterator_traits< typename std::iterator_traits< _RanSeqs >::value_type::first_type >::value_type >()) โ€” splits several sorted sequences at a certain global __rank, resulting in a splitting point for each sequence. The sequences are passed via a sequence of random-access iterator pairs, and none of the sequences may be empty โš ๏ธ โ€” that's a hard requirement, not a vibe suggestion. If there are several equal elements across the split, the ones on the __left side will be chosen from sequences with smaller number.
  • template<typename _Tp , typename _RanSeqs , typename _RankType , typename _Compare > _Tp multiseq_selection (_RanSeqs __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankType &__offset, _Compare __comp=std::less< _Tp >()) โ€” selects the element at a certain global __rank from several sorted sequences.

multiway_merge frontends ๐Ÿ‘‘

So multiway_merge is one name with a million tag-based personalities. The page only labels the sequential_tag one; the rest are just overloads sitting there looking pretty:

  • template<typename _RAIterPairIterator , typename _RAIterOut , typename _DifferenceTp , typename _Compare > _RAIterOut multiway_merge (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::exact_tag __tag)
  • template<typename _RAIterPairIterator , typename _RAIterOut , typename _DifferenceTp , typename _Compare > _RAIterOut multiway_merge (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sampling_tag __tag)
  • template<typename _RAIterPairIterator , typename _RAIterOut , typename _DifferenceTp , typename _Compare > _RAIterOut multiway_merge (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag) โ€” multiway merge frontend. That's the whole blurb, and honestly, respect for the brevity ๐ŸŽ€
  • template<typename _RAIterPairIterator , typename _RAIterOut , typename _DifferenceTp , typename _Compare > _RAIterOut multiway_merge (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, default_parallel_tag __tag)
  • template<typename _RAIterPairIterator , typename _RAIterOut , typename _DifferenceTp , typename _Compare > _RAIterOut multiway_merge (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp __length, _Compare __comp, parallel_tag __tag=parallel_tag(0))
heads up, the source page really does end that last signature with parallel_tag(0)) โ€” the extra paren is copy-pasted straight from the manpage, iykyk ๐Ÿ™ˆ

the variant algorithms โœจ

  • template<template< typename _RAI, typename _Cp > class iterator, typename _RAIterIterator , typename _RAIter3 , typename _DifferenceTp , typename _Compare > _RAIter3 multiway_merge_3_variant (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) โ€” highly efficient 3-way merging procedure ๐Ÿ”ฅ
  • template<template< typename _RAI, typename _Cp > class iterator, typename _RAIterIterator , typename _RAIter3 , typename _DifferenceTp , typename _Compare > _RAIter3 multiway_merge_4_variant (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length, _Compare __comp) โ€” highly efficient 4-way merging procedure ๐Ÿ”ฅ
  • template<bool __stable, typename _RAIterIterator , typename _Compare , typename _DifferenceType > void multiway_merge_exact_splitting (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, โ€” and the page justโ€ฆ stops there mid-signature ๐Ÿ˜ญ that's literally where this chunk ends, bestie, so we pick it up next part.
  • that one whose signature got cut off mid-argument (the manpage does that, not me, don't @ me ๐Ÿ™ˆ) โ€”
_DifferenceType __length, _DifferenceType __total_length, _Compare
__comp, std::vector< std::pair< _DifferenceType, _DifferenceType > >
*__pieces)

Exact splitting for parallel multiway-merge routine. okay so it's exact, no vibes-based guessing here ๐Ÿ’…

  • multiway_merge_loser_tree
template<typename _LT , typename _RAIterIterator , typename _RAIter3 ,
    typename _DifferenceTp , typename _Compare > _RAIter3
    multiway_merge_loser_tree (_RAIterIterator __seqs_begin,
    _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp
    __length, _Compare __comp)

Multi-way merging procedure for a high branching factor, guarded case. ๐Ÿ›ก๏ธ

  • multiway_merge_loser_tree_sentinel
template<typename _UnguardedLoserTree , typename _RAIterIterator ,
    typename _RAIter3 , typename _DifferenceTp , typename _Compare >
    _RAIter3 multiway_merge_loser_tree_sentinel (_RAIterIterator
    __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const
    typename std::iterator_traits< typename std::iterator_traits<
    _RAIterIterator >::value_type::first_type >::value_type &__sentinel,
    _DifferenceTp __length, _Compare __comp)

Multi-way merging procedure for a high branching factor, requiring sentinels to exist. sentinels are the little bodyguards fr fr ๐Ÿซถ

  • multiway_merge_loser_tree_unguarded
template<typename _LT , typename _RAIterIterator , typename _RAIter3 ,
    typename _DifferenceTp , typename _Compare > _RAIter3
    multiway_merge_loser_tree_unguarded (_RAIterIterator __seqs_begin,
    _RAIterIterator __seqs_end, _RAIter3 __target, const typename
    std::iterator_traits< typename std::iterator_traits< _RAIterIterator
    >::value_type::first_type >::value_type &__sentinel, _DifferenceTp
    __length, _Compare __comp)

Multi-way merging procedure for a high branching factor, unguarded case. living dangerously, no guard rails, no cap ๐Ÿ˜ญ

  • multiway_merge_sampling_splitting
template<bool __stable, typename _RAIterIterator , typename _Compare ,
    typename _DifferenceType > void multiway_merge_sampling_splitting
    (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end,
    _DifferenceType __length, _DifferenceType __total_length, _Compare
    __comp, std::vector< std::pair< _DifferenceType, _DifferenceType > >
    *__pieces)

Sampling based splitting for parallel multiway-merge routine. it's giving "just take a lil sample, bestie" โœจ

  • multiway_merge_sentinels (the __gnu_parallel::exact_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, __gnu_parallel::exact_tag __tag)
  • multiway_merge_sentinels (the __gnu_parallel::sequential_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, __gnu_parallel::sequential_tag)

Multiway Merge Frontend. this is the main character entry point ๐Ÿ‘‘

  • multiway_merge_sentinels (the default_parallel_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, default_parallel_tag __tag)
  • multiway_merge_sentinels (the parallel_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, parallel_tag __tag=parallel_tag(0))
  • multiway_merge_sentinels (the sampling_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, sampling_tag __tag)
yes bestie, that's five overloads of the same name โ€” it's the tag-dispatch buffet, pick your flavor ๐Ÿ“
  • parallel_multiway_merge
template<bool __stable, bool __sentinels, typename _RAIterIterator ,
    typename _RAIter3 , typename _DifferenceTp , typename _Splitter ,
    typename _Compare > _RAIter3 parallel_multiway_merge
    (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3
    __target, _Splitter __splitter, _DifferenceTp __length, _Compare
    __comp, _ThreadIndex __num_threads)

Parallel multi-way merge routine. the whole point of the function tbh ๐Ÿ”ฅ

  • parallel_sort_mwms
template<bool __stable, bool __exact, typename _RAIter , typename
    _Compare > void parallel_sort_mwms (_RAIter __begin, _RAIter __end,
    _Compare __comp, _ThreadIndex __num_threads)

PMWMS main call. that acronym will live in my head rent free ๐Ÿง โœจ

  • parallel_sort_mwms_pu
template<bool __stable, bool __exact, typename _RAIter , typename
    _Compare > void parallel_sort_mwms_pu (_PMWMSSortingData< _RAIter >
    *__sd, _Compare &__comp)

PMWMS code executed by each thread. every thread gets a lil job, teamwork makes the dream work ๐Ÿซถ

  • stable_multiway_merge (the __gnu_parallel::exact_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut stable_multiway_merge
    (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end,
    _RAIterOut __target, _DifferenceTp __length, _Compare __comp,
    __gnu_parallel::exact_tag __tag)
  • stable_multiway_merge (the __gnu_parallel::sequential_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut stable_multiway_merge
    (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end,
    _RAIterOut __target, _DifferenceTp __length, _Compare __comp,
    __gnu_parallel::sequential_tag)
  • stable_multiway_merge (the default_parallel_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut stable_multiway_merge
    (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end,
    _RAIterOut __target, _DifferenceTp __length, _Compare __comp,
    default_parallel_tag __tag)
  • stable_multiway_merge (the parallel_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut stable_multiway_merge
    (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end,
    _RAIterOut __target, _DifferenceTp __length, _Compare __comp,
    parallel_tag __tag=parallel_tag(0))
  • stable_multiway_merge (the sampling_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut stable_multiway_merge
    (_RAIterPairIterator __seqs_begin, _RAIterPairIterator __seqs_end,
    _RAIterOut __target, _DifferenceTp __length, _Compare __comp,
    sampling_tag __tag)
  • stable_multiway_merge_sentinels (the __gnu_parallel::exact_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    stable_multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, __gnu_parallel::exact_tag __tag)
  • stable_multiway_merge_sentinels (the __gnu_parallel::sequential_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    stable_multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, __gnu_parallel::sequential_tag)
  • stable_multiway_merge_sentinels (the default_parallel_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    stable_multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, default_parallel_tag __tag)
  • stable_multiway_merge_sentinels (the parallel_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    stable_multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, parallel_tag __tag=parallel_tag(0))
  • stable_multiway_merge_sentinels (the sampling_tag one)
template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    stable_multiway_merge_sentinels (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, sampling_tag __tag)

๐Ÿงฎ Variables

  • static const int _CASable_bits โ€” Number of bits of _CASable. bestie, it's literally just counting bits ๐Ÿ’…
  • static const _CASable _CASable_mask โ€” _CASable with the right half of bits set to 1. mask era ๐ŸŽญ

๐ŸŒธ Detailed Description

GNU parallel code for public use. that's it, that's the whole vibe check โ€” this is the public-facing surface of the GNU parallel machinery โœจ


๐ŸŽ€ Typedef Documentation

typedef unsigned short __gnu_parallel::_BinIndex

Type to hold the index of a bin. Since many variables of this type are allocated, it should be chosen as small as possible. tiny type, big responsibility โ€” it's giving efficiency queen ๐Ÿ‘‘

typedef int64_t __gnu_parallel::_CASable

Longest compare-and-swappable integer type on this platform. as long as it can legally get on this machine, no cap ๐Ÿซถ

typedef uint64_t __gnu_parallel::_SequenceIndex

Unsigned integer to index __elements. The total number of elements for each algorithm must fit into this type. so like, mind the capacity, bestie ๐Ÿ˜ญ

typedef uint16_t __gnu_parallel::_ThreadIndex

Unsigned integer to index a thread number. The maximum thread number (for each processor) must fit into this type. ๐Ÿงต


๐ŸŒˆ Enumeration Type Documentation

enum __gnu_parallel::_AlgorithmStrategy

Strategies for run-time algorithm selection:

enum __gnu_parallel::_FindAlgorithm

Find algorithms:

enum __gnu_parallel::_MultiwayMergeAlgorithm

Merging algorithms:

enum __gnu_parallel::_Parallelism

Run-time equivalents for the compile-time tags. this is how you say "compile-time vibe" at runtime ๐Ÿ’€

Enumerator

  • sequential โ€” Not parallel. just you and the algorithm, alone together ๐Ÿ™ˆ
  • parallel_unbalanced โ€” Parallel unbalanced (equal-sized chunks). everyone gets the same size plate, even if some are starving ๐Ÿฝ๏ธ
  • parallel_balanced โ€” Parallel balanced (work-stealing). stealing work but make it a feature โœจ
  • parallel_omp_loop โ€” Parallel with OpenMP dynamic load-balancing. ๐Ÿ”„
  • parallel_omp_loop_static โ€” Parallel with OpenMP static load-balancing.
  • parallel_taskqueue โ€” Parallel with OpenMP taskqueue construct. the queue is queuing ๐Ÿ’…

enum __gnu_parallel::_PartialSumAlgorithm

Partial sum algorithms: recursive, linear.

enum __gnu_parallel::_SortAlgorithm

Sorting algorithms:

enum __gnu_parallel::_SplittingAlgorithm

Sorting/merging algorithms: sampling, __exact. two flavors, pick your fighter ๐ŸฅŠ


โญ Function Documentation

template<typename _RAIter , typename _DifferenceTp > void __gnu_parallel::__calc_borders (_RAIter __elements, _DifferenceTp __length, _DifferenceTp * __off)

Precalculate __advances for Knuth-Morris-Pratt algorithm. yes THE Knuth-Morris-Pratt, we love a legendary string-searching moment ๐Ÿ‘‘

Parameters

  • __elements โ€” Begin iterator of sequence to search for.
  • __length โ€” Length of sequence to search for.
  • __off โ€” Returned __offsets.

Referenced by __search_template().


template<typename _Tp > bool __gnu_parallel::__compare_and_swap (volatile _Tp * __ptr, _Tp __comparand, _Tp __replacement) [inline]

Compare-and-swap. Compare *__ptr and __comparand. If equal, let *__ptr=__replacement and return true, return false otherwise. literally the "are we the same? then swap, slay" of atomic operations ๐Ÿ’…

Parameters

  • __ptr โ€” Pointer to signed integer.
  • __comparand โ€” Compare value.
  • __replacement โ€” Replacement value.

Referenced by __parallel_partition(), __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::pop_back(), and __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::pop_front().


void __gnu_parallel::__decode2 (_CASable __x, int & __a, int & __b) [inline]

Decode two integers from one gnu_parallel::_CASable. two-for-one, we love a bundle deal ๐ŸŽ€

Okay so the parameter deets for that decode one, bestie โ€” here's what goes where ๐Ÿ’…

Parameters:

  • __x โ€” the __gnu_parallel::_CASable you're pulling integers out of. It's giving "the source of truth" โœจ
  • __a โ€” first integer, decoded from the most-significant _CASable_bits/2 bits of __x
  • __b โ€” second integer, encoded in the least-significant _CASable_bits/2 bits of __x

See also: __encode2 (its whole mirror-image moment ๐Ÿชž)

References: _CASable_bits, and _CASable_mask.

Referenced by: __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::pop_back(), __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::pop_front(), and __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::push_front().


๐ŸŽ€ __determine_samples โ€” picking the samples, lowkey iconic

template<typename _RAIter , typename _DifferenceTp > void
__gnu_parallel::__determine_samples (_PMWMSSortingData< _RAIter > *
__sd, _DifferenceTp __num_samples)

Literally just: select _M_samples from a sequence. That's the whole vibe check โœ…

Parameters:

  • __sd โ€” pointer to the algorithm data. The _Result gets placed in __sd->_M_samples, no cap ๐Ÿซถ
  • __num_samples โ€” how many _M_samples you want to select

References: __equally_split(), __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_samples, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_source, and __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_starts.


๐ŸŒˆ __encode2 โ€” squish two ints into one, [inline]

_CASable __gnu_parallel::__encode2 (int __a, int __b) [inline]

Encode two integers into one gnu_parallel::_CASable. Two besties, one slot โ€” it's giving compression ๐Ÿ’–

Parameters:

  • __a โ€” first integer, encoded in the most-significant _CASable_bits/2 bits
  • __b โ€” second integer, encoded in the least-significant _CASable_bits/2 bits

Returns: the value encoding __a and __b โœจ

See also: __decode2 (the un-squisher)

References: _CASable_bits.

Referenced by: __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::_RestrictedBoundedConcurrentQueue(), __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::pop_back(), __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::pop_front(), and __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::push_front().


๐Ÿฆ‹ __equally_split โ€” slice it into (almost) equal parts, periodt

template<typename _DifferenceType , typename _OutputIterator >
_OutputIterator __gnu_parallel::__equally_split (_DifferenceType __n,
_ThreadIndex __num_threads, _OutputIterator __s)

So this is the function that splits a sequence into parts of almost equal size. The resulting sequence __s of length __num_threads+1 contains the splitting positions when splitting the range [0,__n) into parts of almost equal size (plus minus 1). The first entry is 0, the last one is n. Heads up though โ€” there may result empty parts, and that's just a thing that happens ๐Ÿ™ˆ

Parameters:

  • __n โ€” number of elements
  • __num_threads โ€” number of parts
  • __s โ€” splitters

Returns: end of __splitter sequence, i.e. __s+__num_threads+1

Referenced by: __determine_samples(), __find_template(), __parallel_partial_sum_linear(), __parallel_unique_copy(), __search_template(), and multiway_merge_exact_splitting().


โญ __equally_split_point โ€” the single split point you asked for

template<typename _DifferenceType > _DifferenceType
__gnu_parallel::__equally_split_point (_DifferenceType __n, _ThreadIndex
__num_threads, _ThreadIndex __thread_no)

Same splitting-a-sequence-into-parts-of-almost-equal-size energy, but this one hands you back the position of the splitting point between thread number __thread_no (included) and thread number __thread_no+1 (excluded). One number, zero drama ๐Ÿ’…

Parameters:

  • __n โ€” number of elements
  • __num_threads โ€” number of parts
  • __thread_no โ€” number of threads

Returns: the splitting point ๐ŸŽฏ

Referenced by: __for_each_template_random_access_ed().


๐Ÿ”ฅ __fetch_and_add โ€” atomic add, [inline]

template<typename _Tp > _Tp __gnu_parallel::__fetch_and_add (volatile _Tp *
__ptr, _Tp __addend) [inline]

Add a value to a variable, atomically. Like, nobody can sneak in and ruin the math mid-update. Main character energy for real ๐Ÿ‘‘

Parameters:

  • __ptr โ€” pointer to a signed integer
  • __addend โ€” value to add

Referenced by: __parallel_partition(), and __gnu_parallel::_RestrictedBoundedConcurrentQueue< _Tp >::push_front().


๐Ÿงš __find_template โ€” parallel std::find, the switchboard edition, [inline]

template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename
_Selector > std::pair< _RAIter1, _RAIter2 >
__gnu_parallel::__find_template (_RAIter1 __begin1, _RAIter1 __end1,
_RAIter2 __begin2, _Pred __pred, _Selector __selector) [inline]

Parallel std::find, and it's the switch for different algorithms. She picks the strategy, babes โœจ

Parameters:

  • __begin1 โ€” begin iterator of first sequence
  • __end1 โ€” end iterator of first sequence
  • __begin2 โ€” begin iterator of second sequence. Must have same length as first sequence โš ๏ธ
  • __pred โ€” find predicate
  • __selector โ€” _Functionality (e. g. std::find_if(), std::equal(),...)

Returns: place of finding in both sequences ๐Ÿซถ

References: __find_template(), and __gnu_parallel::_Settings::get().

Referenced by: __find_template().


๐Ÿ“ __find_template โ€” constant size blocks variant

template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename
_Selector > std::pair< _RAIter1, _RAIter2 >
__gnu_parallel::__find_template (_RAIter1 __begin1, _RAIter1 __end1,
_RAIter2 __begin2, _Pred __pred, _Selector __selector,
constant_size_blocks_tag)

Parallel std::find, constant block size variant. Same search, different chunking strategy ๐Ÿ’–

Parameters:

  • __begin1 โ€” begin iterator of first sequence
  • __end1 โ€” end iterator of first sequence
  • __begin2 โ€” begin iterator of second sequence. Second __sequence must have same length as first sequence
  • __pred โ€” find predicate
  • __selector โ€” _Functionality (e. g. std::find_if(), std::equal(),...)

Returns: place of finding in both sequences

See also: __gnu_parallel::_Settings::find_sequential_search_size

__gnu_parallel::_Settings::find_block_size

There are two main differences between the growing blocks and the constant-size blocks variants, and yes you need both of them in your head:

  1. For GB, the block size grows; for CSB, the block size is fixed.
  2. For GB, the blocks are allocated dynamically; for CSB, the blocks are allocated in a predetermined manner, namely spacial round-robin.

References: _GLIBCXX_CALL, __gnu_parallel::_Settings::find_initial_block_size, __gnu_parallel::_Settings::find_sequential_search_size, std::pair< _T1, _T2 >::first, and __gnu_parallel::_Settings::get().


๐ŸŒธ __find_template โ€” equal splitting variant

template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename
_Selector > std::pair< _RAIter1, _RAIter2 >
__gnu_parallel::__find_template (_RAIter1 __begin1, _RAIter1 __end1,
_RAIter2 __begin2, _Pred __pred, _Selector __selector, equal_split_tag)

Parallel std::find, equal splitting variant. Everyone gets the same slice, fair and square ๐Ÿค

Parameters:

  • __begin1 โ€” begin iterator of first sequence
  • __end1 โ€” end iterator of first sequence
  • __begin2 โ€” begin iterator of second sequence. Second __sequence must have same length as first sequence
  • __pred โ€” find predicate
  • __selector โ€” _Functionality (e. g. std::find_if(), std::equal(),...)

Returns: place of finding in both sequences

References: __equally_split(), and _GLIBCXX_CALL.


๐ŸŽ€ __find_template โ€” growing blocks variant

template<typename _RAIter1 , typename _RAIter2 , typename _Pred , typename
_Selector > std::pair< _RAIter1, _RAIter2 >
__gnu_parallel::__find_template (_RAIter1 __begin1, _RAIter1 __end1,
_RAIter2 __begin2, _Pred __pred, _Selector __selector,
growing_blocks_tag)

Parallel std::find, growing block size variant. The blocks start small and justโ€ฆ grow up ๐Ÿ˜ญ๐Ÿ’•

Parameters:

  • __begin1 โ€” begin iterator of first sequence
  • __end1 โ€” end iterator of first sequence
  • __begin2 โ€” begin iterator of second sequence. Second __sequence must have same length as first sequence
  • __pred โ€” find predicate
  • __selector โ€” _Functionality (e. g. std::find_if(), std::equal(),...)

Returns: place of finding in both sequences

See also: __gnu_parallel::_Settings::find_sequential_search_size

__gnu_parallel::_Settings::find_scale_factor

The same two main differences between growing blocks and constant-size blocks, once more for the people in the back:

  1. For GB, the block size grows; for CSB, the block size is fixed.
  2. For GB, the blocks are allocated dynamically; for CSB, the blocks are allocated in a predetermined manner, namely spacial round-robin.

References: _GLIBCXX_CALL, __gnu_parallel::_Settings::find_scale_factor, __gnu_parallel::_Settings::find_sequential_search_size, std::pair< _T1, _T2 >::first, and __gnu_parallel::_Settings::get().


๐Ÿ‘‘ __for_each_template_random_access โ€” pick your algorithm by tag

template<typename _IIter , typename _UserOp , typename _Functionality ,
typename _Red , typename _Result > _UserOp
__gnu_parallel::__for_each_template_random_access (_IIter __begin,
_IIter __end, _UserOp __user_op, _Functionality & __functionality, _Red
__reduction, _Result __reduction_start, _Result & __output, typename
std::iterator_traits< _IIter >::difference_type __bound, _Parallelism
__parallelism_tag)

Choose the desired algorithm by evaluating __parallelism_tag. She reads the tag, she picks the whole strategy โ€” it's giving "I contain multitudes" ๐ŸŒˆ

Parameters:

  • __begin โ€” begin iterator of input sequence
  • __end โ€” end iterator of input sequence
  • __user_op โ€” a user-specified functor (comparator, predicate, associative operator,...)
  • __functionality โ€” functor to process an element with __user_op (depends on desired functionality, e. g. accumulate, for_each,...
  • __reduction โ€” reduction functor
  • __reduction_start โ€” initial value for reduction
  • __output โ€” output iterator
  • __bound โ€” maximum number of elements processed
  • __parallelism_tag โ€” parallelization method

References: __for_each_template_random_access_ed(), __for_each_template_random_access_omp_loop(), __for_each_template_random_access_workstealing(), parallel_omp_loop, parallel_omp_loop_static, and parallel_unbalanced.


๐Ÿ’œ __for_each_template_random_access_ed โ€” embarrassingly parallel, hand-crafted

template<typename _RAIter , typename _Op , typename _Fu , typename _Red ,
typename _Result > _Op
__gnu_parallel::__for_each_template_random_access_ed (_RAIter __begin,
_RAIter __end, _Op __o, _Fu & __f, _Red __r, _Result __base, _Result &
__output, typename std::iterator_traits< _RAIter >::difference_type
__bound)

Embarrassingly parallel algorithm for random access iterators, using hand-crafted parallelization by equal splitting the work. Hand-crafted!! Like a lil artisanal parallel algorithm, we love her ๐Ÿงšโœจ

Parameters:

  • __begin โ€” begin iterator of element sequence
  • __end โ€” end iterator of element sequence
  • __o โ€” user-supplied functor (comparator, predicate, adding functor, ...)
  • __f โ€” functor to 'process' an element with __op (depends on desired functionality, e. g. for std::for_each(), ...)
  • __r โ€” functor to 'add' a single __result to the already processed elements (depends on functionality)
  • __base โ€” base value for reduction
  • __output โ€” pointer to position where final result is written to
  • __bound โ€” maximum number of elements processed (e. g. for std::count_n())

Returns: user-supplied functor (that may contain a part of the result) ๐Ÿ’–

References: __equally_split_point().

Referenced by: __for_each_template_random_access().


๐ŸŒˆ __for_each_template_random_access_omp_loop

template<typename _RAIter , typename _Op , typename _Fu , typename _Red ,
    typename _Result > _Op
    __gnu_parallel::__for_each_template_random_access_omp_loop (_RAIter
    __begin, _RAIter __end, _Op __o, _Fu & __f, _Red __r, _Result __base,
    _Result & __output, typename std::iterator_traits< _RAIter
    >::difference_type __bound)

Okay bestie, this one is the embarrassingly parallel algorithm for random access iterators, and it does the whole thing with an OpenMP for loop. It's giving "I have never known struggle" energy honestly ๐Ÿ’…

Parameters โ€” let's go through them, no skips:

  • __begin โ€” begin iterator of element sequence.
  • __end โ€” end iterator of element sequence.
  • __o โ€” your user-supplied functor (comparator, predicate, adding functor, etc.).
  • __f โ€” functor to process an element with __op (depends on what functionality you want, e.g. for std::for_each(), ...).
  • __r โ€” functor to add a single __result to the already processed elements (depends on functionality).
  • __base โ€” base value for reduction.
  • __output โ€” pointer to the position where the final result is written to.
  • __bound โ€” maximum number of elements processed (e.g. for std::count_n()).

Returns โ€” your user-supplied functor, which may contain a part of the result. โœจ

Referenced by __for_each_template_random_access().


๐Ÿฆ‹ __for_each_template_random_access_omp_loop_static

template<typename _RAIter , typename _Op , typename _Fu , typename _Red ,
    typename _Result > _Op
    __gnu_parallel::__for_each_template_random_access_omp_loop_static
    (_RAIter __begin, _RAIter __end, _Op __o, _Fu & __f, _Red __r, _Result
    __base, _Result & __output, typename std::iterator_traits< _RAIter
    >::difference_type __bound)

Same embarrassingly parallel algorithm for random access iterators, except it's an OpenMP for loop with static scheduling. Same vibes, more predictable, iykyk ๐ŸŽ€

Parameters:

  • __begin โ€” begin iterator of element sequence.
  • __end โ€” end iterator of element sequence.
  • __o โ€” user-supplied functor (comparator, predicate, adding functor, ...).
  • __f โ€” functor to process an element with __op (depends on desired functionality, e.g. for std::for_each(), ...).
  • __r โ€” functor to add a single __result to the already processed __elements (depends on functionality).
  • __base โ€” base value for reduction.
  • __output โ€” pointer to position where final result is written to.
  • __bound โ€” maximum number of elements processed (e.g. for std::count_n()).

Returns โ€” the user-supplied functor, may contain a part of the result ๐Ÿ’–


๐Ÿ”ฅ __for_each_template_random_access_workstealing

template<typename _RAIter , typename _Op , typename _Fu , typename _Red ,
    typename _Result > _Op
    __gnu_parallel::__for_each_template_random_access_workstealing (_RAIter
    __begin, _RAIter __end, _Op __op, _Fu & __f, _Red __r, _Result __base,
    _Result & __output, typename std::iterator_traits< _RAIter
    >::difference_type __bound)

The work stealing algorithm for random access iterators, and she is so efficient it hurts โ€” uses O(1) additional memory, no cap. Synchronization at job lists is done with atomic operations, which is basically the flex of the century ๐Ÿ‘‘

Parameters:

  • __begin โ€” begin iterator of element sequence.
  • __end โ€” end iterator of element sequence.
  • __op โ€” user-supplied functor (comparator, predicate, adding functor, ...).
  • __f โ€” functor to process an element with __op (depends on desired functionality, e.g. for std::for_each(), ...).
  • __r โ€” functor to add a single __result to the already processed elements (depends on functionality).
  • __base โ€” base value for reduction.
  • __output โ€” pointer to position where final result is written to.
  • __bound โ€” maximum number of elements processed (e.g. for std::count_n()).

Returns โ€” the user-supplied functor (may contain a part of the result).

References: __yield(), _GLIBCXX_CALL, __gnu_parallel::_Job< _DifferenceTp >::_M_first, __gnu_parallel::_Job< _DifferenceTp >::_M_last, __gnu_parallel::_Job< _DifferenceTp >::_M_load, __gnu_parallel::_Settings::cache_line_size, __gnu_parallel::_Settings::get(), and min().

Referenced by __for_each_template_random_access().


โญ __is_sorted

template<typename _IIter , typename _Compare > bool
    __gnu_parallel::__is_sorted (_IIter __begin, _IIter __end, _Compare
    __comp)

A little vibe check: is [__begin, __end) sorted according to __comp? That's literally it, that's the whole job ๐Ÿซถ

Parameters:

  • __begin โ€” begin iterator of sequence.
  • __end โ€” end iterator of sequence.
  • __comp โ€” comparator.

Returns โ€” true if sorted, false otherwise.

Referenced by __sequential_multiway_merge(), multiway_merge_loser_tree_sentinel(), and parallel_multiway_merge().


๐Ÿงš __median_of_three_iterators

template<typename _RAIter , typename _Compare > _RAIter
    __gnu_parallel::__median_of_three_iterators (_RAIter __a, _RAIter __b,
    _RAIter __c, _Compare __comp)

Computes the median of three referenced elements, according to __comp. Three candidates walk in, one middle child walks out ๐Ÿ˜ญ

Parameters:

  • __a โ€” first iterator.
  • __b โ€” second iterator.
  • __c โ€” third iterator.
  • __comp โ€” comparator.

Referenced by __qsb_divide().


๐Ÿ’œ __merge_advance

template<typename _RAIter1 , typename _RAIter2 , typename _OutputIterator ,
    typename _DifferenceTp , typename _Compare > _OutputIterator
    __gnu_parallel::__merge_advance (_RAIter1 & __begin1, _RAIter1 __end1,
    _RAIter2 & __begin2, _RAIter2 __end2, _OutputIterator __target,
    _DifferenceTp __max_length, _Compare __comp) [inline]

A merge routine that can only merge the __max_length smallest elements. The __begin iterators get advanced accordingly, so heads up: they might not reach __end, in contrast to the usual variant. It also does a static switch on whether to use the conditional-move variant. She contains multitudes โœจ

Parameters:

  • __begin1 โ€” begin iterator of first sequence.
  • __end1 โ€” end iterator of first sequence.
  • __begin2 โ€” begin iterator of second sequence.
  • __end2 โ€” end iterator of second sequence.
  • __target โ€” target begin iterator.
  • __max_length โ€” maximum number of elements to merge.
  • __comp โ€” comparator.

Returns โ€” output end iterator.

References __merge_advance_movc(), and _GLIBCXX_CALL.

Referenced by __parallel_merge_advance(), and __sequential_multiway_merge().


๐ŸŒธ __merge_advance_movc

template<typename _RAIter1 , typename _RAIter2 , typename _OutputIterator ,
    typename _DifferenceTp , typename _Compare > _OutputIterator
    __gnu_parallel::__merge_advance_movc (_RAIter1 & __begin1, _RAIter1
    __end1, _RAIter2 & __begin2, _RAIter2 __end2, _OutputIterator __target,
    _DifferenceTp __max_length, _Compare __comp)

Another merge-only-the-__max_length-smallest-elements routine, and the __begin iterators advance the same way โ€” again, they might not reach __end, unlike the usual variant. The difference? The code is specially designed so the compiler can generate conditional moves instead of branches. It's giving "I was built different on purpose" ๐Ÿ’…

Parameters:

  • __begin1 โ€” begin iterator of first sequence.
  • __end1 โ€” end iterator of first sequence.
  • __begin2 โ€” begin iterator of second sequence.
  • __end2 โ€” end iterator of second sequence.
  • __target โ€” target begin iterator.
  • __max_length โ€” maximum number of elements to merge.
  • __comp โ€” comparator.

Returns โ€” output end iterator.

Referenced by __merge_advance().


๐ŸŽ€ __merge_advance_usual

template<typename _RAIter1 , typename _RAIter2 , typename _OutputIterator ,
    typename _DifferenceTp , typename _Compare > _OutputIterator
    __gnu_parallel::__merge_advance_usual (_RAIter1 & __begin1, _RAIter1
    __end1, _RAIter2 & __begin2, _RAIter2 __end2, _OutputIterator __target,
    _DifferenceTp __max_length, _Compare __comp)

The plain-jane one: merges only the __max_length smallest elements, the __begin iterators get advanced accordingly and might not reach __end, in contrast to the usual variant. (Yes, the description says "in contrast to the usual variant" and this is the usual variant, don't come for me, I'm just the messenger ๐Ÿ™ˆ)

Parameters:

  • __begin1 โ€” begin iterator of first sequence.
  • __end1 โ€” end iterator of first sequence.
  • __begin2 โ€” begin iterator of second sequence.
  • __end2 โ€” end iterator of second sequence.
  • __target โ€” target begin iterator.
  • __max_length โ€” maximum number of elements to merge.
  • __comp โ€” comparator.

Returns โ€” output end iterator.


๐ŸŒˆ __parallel_merge_advance (first overload)

template<typename _RAIter1 , typename _RAIter3 , typename _Compare >
    _RAIter3 __gnu_parallel::__parallel_merge_advance (_RAIter1 & __begin1,
    _RAIter1 __end1, _RAIter1 & __begin2, _RAIter1 __end2, _RAIter3
    __target, typename std::iterator_traits< _RAIter1 >::difference_type
    __max_length, _Compare __comp) [inline]

The parallel merge routine, merging only the __max_length smallest elements. The __begin iterators are advanced accordingly and might not reach __end, in contrast to the usual variant โ€” and the whole functionality is projected onto parallel_multiway_merge. Fancy, honestly ๐Ÿ”ฅ

Parameters:

  • __begin1 โ€” begin iterator of first sequence.
  • __end1 โ€” end iterator of first sequence.
  • __begin2 โ€” begin iterator of second sequence.
  • __end2 โ€” end iterator of second sequence.
  • __target โ€” target begin iterator.
  • __max_length โ€” maximum number of elements to merge.
  • __comp โ€” comparator.

Returns โ€” output end iterator.

References multiway_merge_exact_splitting(), and parallel_multiway_merge().


๐Ÿซถ __parallel_merge_advance (second overload)

template<typename _RAIter1 , typename _RAIter2 , typename _RAIter3 ,
    typename _Compare > _RAIter3 __gnu_parallel::__parallel_merge_advance
    (_RAIter1 & __begin1, _RAIter1 __end1, _RAIter2 & __begin2, _RAIter2
    __end2, _RAIter3 __target, typename std::iterator_traits< _RAIter1
    >::difference_type __max_length, _Compare __comp) [inline]

Samesies name, different template params โ€” and this one is the fallback to sequential in case the iterators of the two input sequences are of different types. Like, it tried parallelism, saw a type mismatch, and said "bestie I got you, we're doing this the chill way" ๐Ÿ˜Œ

Parameters:

  • __begin1 โ€” begin iterator of first sequence.
  • __end1 โ€” end iterator of first sequence.
  • __begin2 โ€” begin iterator of second sequence.
  • __end2 โ€” end iterator of second sequence.
  • __target โ€” target begin iterator.
  • __max_length โ€” maximum number of elements to merge.
  • __comp โ€” comparator.

Returns โ€” output end iterator.

References __merge_advance().


๐Ÿ‘‘ __parallel_nth_element

template<typename _RAIter , typename _Compare > void
    __gnu_parallel::__parallel_nth_element (_RAIter __begin, _RAIter __nth,
    _RAIter __end, _Compare __comp)

The parallel implementation of std::nth_element(). She finds the one โœจiconicโœจ element that has to be in a specific position and makes it happen.

Parameters:

  • __begin โ€” begin iterator of input sequence.
  • __nth โ€” Iterator of element that must be in position afterwards.
  • __end โ€” end iterator of input sequence.
  • __comp โ€” comparator.

References __parallel_partition(), _GLIBCXX_CALL, __gnu_parallel::_Settings::get(), std::max(), __gnu_parallel::_Settings::nth_element_minimal_n, and __gnu_parallel::_Settings::partition_minimal_n.

Referenced by __parallel_partial_sort().


๐Ÿ’– __parallel_partial_sort

template<typename _RAIter , typename _Compare > void
    __gnu_parallel::__parallel_partial_sort (_RAIter __begin, _RAIter
    __middle, _RAIter __end, _Compare __comp)

The parallel implementation of std::partial_sort() โ€” sort everything up to __middle and then just vibe ๐ŸŒธ

Parameters:

  • __begin โ€” begin iterator of input sequence.
  • __middle โ€” sort until this position.
  • __end โ€” end iterator of input sequence.
  • __comp โ€” comparator.

References __parallel_nth_element().

๐ŸŒŠ __parallel_partial_sum

template<typename _IIter, typename _OutputIterator, typename _BinaryOperation>
_OutputIterator
__gnu_parallel::__parallel_partial_sum(_IIter __begin, _IIter __end,
                                       _OutputIterator __result,
                                       _BinaryOperation __bin_op)

okay so bestie, this is the parallel partial sum โ€” front to __end, and it's giving "prefix sums but make it multithreaded" โœจ

Parameters

  • __begin โ€” begin iterator of input sequence ๐Ÿ’–
  • __end โ€” end iterator of input sequence
  • __result โ€” begin iterator of output sequence
  • __bin_op โ€” associative binary function (yes it gotta be associative, no cap)

Returns End iterator of output sequence ๐ŸŽ€

References: __parallel_partial_sum_linear(), _GLIBCXX_CALL, and __gnu_parallel::_Settings::get().


๐Ÿงš __parallel_partial_sum_basecase

template<typename _IIter, typename _OutputIterator, typename _BinaryOperation>
_OutputIterator
__gnu_parallel::__parallel_partial_sum_basecase(_IIter __begin, _IIter __end,
                                                _OutputIterator __result,
                                                _BinaryOperation __bin_op,
                                                typename std::iterator_traits<_IIter>::value_type __value)

the base case prefix sum routine, lowkey the little worker bee of the whole thing ๐Ÿ

Parameters

  • __begin โ€” begin iterator of input sequence
  • __end โ€” end iterator of input sequence
  • __result โ€” begin iterator of output sequence
  • __bin_op โ€” associative binary function
  • __value โ€” start value. Must be passed since the neutral element is unknown in general ๐Ÿ™ˆ (like, we literally can't guess it for you)

Returns End iterator of output sequence ๐Ÿ’ซ

Referenced by __parallel_partial_sum_linear().


๐ŸŒธ __parallel_partial_sum_linear

template<typename _IIter, typename _OutputIterator, typename _BinaryOperation>
_OutputIterator
__gnu_parallel::__parallel_partial_sum_linear(_IIter __begin, _IIter __end,
                                              _OutputIterator __result,
                                              _BinaryOperation __bin_op,
                                              typename std::iterator_traits<_IIter>::difference_type __n)

the parallel partial sum implementation โ€” two-phase approach, no recursion ๐Ÿ‘‘ it's giving "we do it in two passes and we don't call ourselves, periodt"

Parameters

  • __begin โ€” begin iterator of input sequence
  • __end โ€” end iterator of input sequence
  • __result โ€” begin iterator of output sequence
  • __bin_op โ€” associative binary function
  • __n โ€” length of sequence ๐Ÿ“

Returns End iterator of output sequence โญ

References: __equally_split(), __parallel_partial_sum_basecase(), __gnu_parallel::_Settings::get(), and __gnu_parallel::_Settings::partial_sum_dilation.

Referenced by __parallel_partial_sum().


๐Ÿฆ‹ __parallel_partition

template<typename _RAIter, typename _Predicate>
std::iterator_traits<_RAIter>::difference_type
__gnu_parallel::__parallel_partition(_RAIter __begin, _RAIter __end,
                                     _Predicate __pred,
                                     _ThreadIndex __num_threads)

the parallel implementation of std::partition โ€” splitting the crowd into "yass" and "nah" ๐Ÿ’…

Parameters

  • __begin โ€” begin iterator of input sequence to split
  • __end โ€” end iterator of input sequence to split
  • __pred โ€” partition predicate, possibly including some kind of pivot ๐ŸŽฏ
  • __num_threads โ€” maximum number of threads to use for this task

Returns Number of elements not fulfilling the predicate (so like, count of the leftovers) ๐Ÿ’€

References: __compare_and_swap(), __fetch_and_add(), _GLIBCXX_CALL, _GLIBCXX_VOLATILE, __gnu_parallel::_Settings::get(), __gnu_parallel::_Settings::partition_chunk_share, and __gnu_parallel::_Settings::partition_chunk_size.

Referenced by __parallel_nth_element(), __parallel_sort_qs_divide(), and __qsb_divide().


๐ŸŽ€ __parallel_random_shuffle

template<typename _RAIter, typename _RandomNumberGenerator>
void
__gnu_parallel::__parallel_random_shuffle(_RAIter __begin, _RAIter __end,
                                          _RandomNumberGenerator __rng = _RandomNumber())  // [inline]

the parallel random public call โ€” this is the one you actually call, bestie, it's the front door ๐Ÿšชโœจ

Parameters

  • __begin โ€” begin iterator of sequence
  • __end โ€” end iterator of sequence
  • __rng โ€” random number generator to use (defaults to _RandomNumber())

References: __parallel_random_shuffle_drs().


๐Ÿ”ฅ __parallel_random_shuffle_drs

template<typename _RAIter, typename _RandomNumberGenerator>
void
__gnu_parallel::__parallel_random_shuffle_drs(_RAIter __begin, _RAIter __end,
                                              typename std::iterator_traits<_RAIter>::difference_type __n,
                                              _ThreadIndex __num_threads,
                                              _RandomNumberGenerator &__rng)

the main parallel random shuffle step โ€” the real main-character energy of this shuffle situation ๐Ÿ‘‘

Parameters

  • __begin โ€” begin iterator of sequence
  • __end โ€” end iterator of sequence
  • __n โ€” length of sequence
  • __num_threads โ€” number of threads to use
  • __rng โ€” random number generator to use

References:

  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::__bins_end
  • __parallel_random_shuffle_drs_pu()
  • __rd_log2()
  • __round_up_to_pow2()
  • __sequential_random_shuffle()
  • _GLIBCXX_CALL
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_bin_proc
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_bins_begin
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_dist
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_num_bins
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_num_bits
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_num_threads
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_sd
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_seed
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_starts
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_temporaries
  • __gnu_parallel::_Settings::get()
  • __gnu_parallel::_Settings::L2_cache_size
  • std::min()
  • __gnu_parallel::_Settings::TLB_size

Referenced by __parallel_random_shuffle().


๐Ÿ’œ __parallel_random_shuffle_drs_pu

template<typename _RAIter, typename _RandomNumberGenerator>
void
__gnu_parallel::__parallel_random_shuffle_drs_pu(_DRSSorterPU<_RAIter, _RandomNumberGenerator> *__pus)

the random shuffle code executed by each thread โ€” like, every thread grabs its own lil to-do list and vibes ๐Ÿงš

Parameters

  • __pus โ€” array of thread-local data records

References:

  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::__bins_end
  • __random_number_pow2()
  • __sequential_random_shuffle()
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_bin_proc
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_bins_begin
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_dist
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_num_bins
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_num_bits
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_num_threads
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_sd
  • __gnu_parallel::_DRSSorterPU<_RAIter, _RandomNumberGenerator>::_M_seed
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_source
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_starts
  • __gnu_parallel::_DRandomShufflingGlobalData<_RAIter>::_M_temporaries
  • std::partial_sum()

Referenced by __parallel_random_shuffle_drs().


๐ŸŒˆ __parallel_sort โ€” the overload era

bestie, there are seven overloads of this and they're all just picking a different sorting algorithm based on the tag you hand them. same params, same template param, different vibe check on __parallelism ๐Ÿซถ

Every single one of them takes:

  • __begin โ€” begin iterator of input sequence
  • __end โ€” end iterator of input sequence
  • __comp โ€” comparator

and has the template parameter:

  • __stable โ€” sort stable

__parallel_sort with balanced_quicksort_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                balanced_quicksort_tag __parallelism)  // [inline]

Choose balanced quicksort for parallel sorting. ๐Ÿ”ฅ balanced = the responsible quicksort, fr fr.

References: __gnu_parallel::parallel_tag::__get_num_threads(), __parallel_sort_qsb(), and _GLIBCXX_CALL.


__parallel_sort with default_parallel_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                default_parallel_tag __parallelism)  // [inline]

Choose multiway mergesort with exact splitting, for parallel sorting. the default default, iconic โœจ

References: __gnu_parallel::parallel_tag::__get_num_threads(), and _GLIBCXX_CALL.


__parallel_sort with multiway_mergesort_exact_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                multiway_mergesort_exact_tag __parallelism)  // [inline]

Choose multiway mergesort with exact splitting, for parallel sorting. yes it's the same description as above, that's literally what the page says, don't come for me ๐Ÿ’€

References: __gnu_parallel::parallel_tag::__get_num_threads(), and _GLIBCXX_CALL.


__parallel_sort with multiway_mergesort_sampling_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                multiway_mergesort_sampling_tag __parallelism)  // [inline]

Choose multiway mergesort with splitting by sampling, for parallel sorting. sampling the data first, very "let me get a feel for the crowd" ๐ŸŽ€

References: __gnu_parallel::parallel_tag::__get_num_threads(), and _GLIBCXX_CALL.


__parallel_sort with multiway_mergesort_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                multiway_mergesort_tag __parallelism)  // [inline]

Choose multiway mergesort, splitting variant at run-time, for parallel sorting. so it decides the splitting situation live โ€” main character improvisation ๐Ÿ’…

References: __gnu_parallel::parallel_tag::__get_num_threads(), _GLIBCXX_CALL, and __gnu_parallel::_Settings::get().


__parallel_sort with parallel_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                parallel_tag __parallelism)  // [inline]

Choose a parallel sorting algorithm. just, like, one of them. the algorithm chooses its own destiny ๐Ÿฆ‹

References: __gnu_parallel::parallel_tag::__get_num_threads(), __parallel_sort_qs(), __parallel_sort_qsb(), _GLIBCXX_CALL, and __gnu_parallel::_Settings::get().


__parallel_sort with quicksort_tag

template<bool __stable, typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort(_RAIter __begin, _RAIter __end,
                                _Compare __comp,
                                quicksort_tag __parallelism)  // [inline]

Choose quicksort for parallel sorting. the classic, the legend, the one everybody knows โญ

References: __gnu_parallel::parallel_tag::__get_num_threads(), __parallel_sort_qs(), and _GLIBCXX_CALL.


โšก __parallel_sort_qs

template<typename _RAIter, typename _Compare>
void
__gnu_parallel::__parallel_sort_qs(_RAIter __begin, _RAIter __end,
                                   _Compare __comp,
                                   _ThreadIndex __num_threads)

the unbalanced quicksort main call โ€” no balancing, all chaos, still slaps ๐Ÿ”ฅ

Parameters

  • __begin โ€” begin iterator of input sequence
  • __end โ€” end iterator input sequence, ignored ๐Ÿ™ˆ (yes, literally ignored, that's what it says)
  • __comp โ€” comparator
  • __num_threads โ€” number of threads that are allowed to work on this part

References: __parallel_sort_qs_conquer(), and _GLIBCXX_CALL.

๐ŸŒ€ __parallel_sort_qs_conquer

template<typename _RAIter , typename _Compare > void
__gnu_parallel::__parallel_sort_qs_conquer (_RAIter __begin, _RAIter __end,
    _Compare __comp, _ThreadIndex __num_threads)

Unbalanced quicksort conquer step โœจ โ€” literally the part where it goes and actually sorts the pieces.

Parameters

  • __begin โ€” begin iterator of subsequence.
  • __end โ€” end iterator of subsequence.
  • __comp โ€” comparator.
  • __num_threads โ€” number of threads that are allowed to work on this part.

References: __parallel_sort_qs_conquer(), __parallel_sort_qs_divide(), and __gnu_parallel::_Settings::get().

Referenced by: __parallel_sort_qs(), and __parallel_sort_qs_conquer().


๐ŸŒ€ __parallel_sort_qs_divide

template<typename _RAIter , typename _Compare > std::iterator_traits<
    _RAIter >::difference_type __gnu_parallel::__parallel_sort_qs_divide
    (_RAIter __begin, _RAIter __end, _Compare __comp,
     typename std::iterator_traits< _RAIter >::difference_type __pivot_rank,
     typename std::iterator_traits< _RAIter >::difference_type __num_samples,
     _ThreadIndex __num_threads)

Unbalanced quicksort divide step ๐Ÿ’… the part that picks the pivot and splits everything up.

Parameters

  • __begin โ€” begin iterator of subsequence.
  • __end โ€” end iterator of subsequence.
  • __comp โ€” comparator.
  • __pivot_rank โ€” desired __rank of the pivot.
  • __num_samples โ€” choose pivot from that many samples.
  • __num_threads โ€” number of threads that are allowed to work on this part.

References: __parallel_partition(), and std::min().

Referenced by: __parallel_sort_qs_conquer().


๐ŸŒ€ __parallel_sort_qsb

template<typename _RAIter , typename _Compare > void
__gnu_parallel::__parallel_sort_qsb (_RAIter __begin, _RAIter __end,
    _Compare __comp, _ThreadIndex __num_threads)

Top-level quicksort routine ๐Ÿ‘‘ the main character of the quicksort situation, no cap.

Parameters

  • __begin โ€” begin iterator of sequence.
  • __end โ€” end iterator of sequence.
  • __comp โ€” comparator.
  • __num_threads โ€” number of threads that are allowed to work on this part.

References: __qsb_conquer(), __rd_log2(), _GLIBCXX_CALL, and __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_elements_leftover.

Referenced by: __parallel_sort(), and __parallel_sort().


๐Ÿฆ‹ __parallel_unique_copy (the no-predicate one)

template<typename _IIter , class _OutputIterator > _OutputIterator
__gnu_parallel::__parallel_unique_copy (_IIter __first, _IIter __last,
    _OutputIterator __result) [inline]

Parallel std::unique_copy(), without explicit equality predicate ๐ŸŒธ โ€” like, it just assumes == and vibes.

Parameters

  • __first โ€” begin iterator of input sequence.
  • __last โ€” end iterator of input sequence.
  • __result โ€” begin iterator of result __sequence.

Returns: end iterator of result __sequence.

References: __parallel_unique_copy().


๐Ÿฆ‹ __parallel_unique_copy (the one with a predicate)

template<typename _IIter , class _OutputIterator , class _BinaryPredicate >
_OutputIterator __gnu_parallel::__parallel_unique_copy (_IIter __first,
    _IIter __last, _OutputIterator __result, _BinaryPredicate __binary_pred)

Parallel std::unique_copy(), w/__o explicit equality predicate ๐Ÿ’– โ€” yes bestie, you get to bring your own "are these the same" rules. (That w/__o is exactly how the original spells it, iconic typo energy, we keep it fr.)

Parameters

  • __first โ€” begin iterator of input sequence.
  • __last โ€” end iterator of input sequence.
  • __result โ€” begin iterator of result __sequence.
  • __binary_pred โ€” equality predicate.

Returns: end iterator of result __sequence.

References: __equally_split(), and _GLIBCXX_CALL.

Referenced by: __parallel_unique_copy().


๐ŸŽ€ __qsb_conquer

template<typename _RAIter , typename _Compare > void
__gnu_parallel::__qsb_conquer (_QSBThreadLocal< _RAIter > ** __tls,
    _RAIter __begin, _RAIter __end, _Compare __comp, _ThreadIndex __iam,
    _ThreadIndex __num_threads, bool __parent_wait)

Quicksort conquer step โญ the balanced-quicksort version, doing its little recursion thing.

Parameters

  • __tls โ€” array of thread-local storages.
  • __begin โ€” begin iterator of subsequence.
  • __end โ€” end iterator of subsequence.
  • __comp โ€” comparator.
  • __iam โ€” number of the thread processing this function.
  • __num_threads โ€” number of threads that are allowed to work on this part.

References: __qsb_conquer(), __qsb_divide(), __qsb_local_sort_with_helping(), __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_elements_leftover, and __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_initial.

Referenced by: __parallel_sort_qsb(), and __qsb_conquer().


๐ŸŽ€ __qsb_divide

template<typename _RAIter , typename _Compare > std::iterator_traits<
    _RAIter >::difference_type __gnu_parallel::__qsb_divide (_RAIter __begin,
    _RAIter __end, _Compare __comp, _ThreadIndex __num_threads)

Balanced quicksort divide step ๐Ÿงš the split-up bit, but make it balanced.

Parameters

  • __begin โ€” begin iterator of subsequence.
  • __end โ€” end iterator of subsequence.
  • __comp โ€” comparator.
  • __num_threads โ€” number of threads that are allowed to work on this part.

Precondition: (__end-__begin)>=1 โš ๏ธ โ€” like, there has to be at least one element in there, bestie, don't play.

References: __median_of_three_iterators(), and __parallel_partition().

Referenced by: __qsb_conquer().


๐ŸŽ€ __qsb_local_sort_with_helping

template<typename _RAIter , typename _Compare > void
__gnu_parallel::__qsb_local_sort_with_helping (_QSBThreadLocal< _RAIter >
    ** __tls, _Compare & __comp, _ThreadIndex __iam, bool __wait)

Quicksort step doing load-balanced local sort ๐Ÿ”ฅ โ€” the name literally says "with helping", it's giving teamwork, it's giving community.

Parameters

  • __tls โ€” array of thread-local storages.
  • __comp โ€” comparator.
  • __iam โ€” number of the thread processing this function.

References: __yield(), _GLIBCXX_PARALLEL_ASSERTIONS, __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_elements_leftover, __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_initial, __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_leftover_parts, __gnu_parallel::_QSBThreadLocal< _RAIter >::_M_num_threads, __gnu_parallel::_Settings::get(), and __gnu_parallel::_Settings::sort_qsb_base_case_maximal_n.

Referenced by: __qsb_conquer().


๐ŸŒˆ __random_number_pow2

template<typename _RandomNumberGenerator > int
__gnu_parallel::__random_number_pow2 (int __logp, _RandomNumberGenerator &
    __rng) [inline]

Generate a random number in [0,2^__logp) ๐ŸŽฒ โ€” cute little power-of-two-bounded random, so tidy.

Parameters

  • __logp โ€” logarithm (basis 2) of the upper range __bound.
  • __rng โ€” random number generator to use.

Referenced by: __parallel_random_shuffle_drs_pu(), and __sequential_random_shuffle().


๐ŸŒˆ __rd_log2

template<typename _Size > _Size __gnu_parallel::__rd_log2 (_Size __n)
    [inline]

Calculates the rounded-down logarithm of __n for base 2 โœจ โ€” floor energy only, we don't round up around here.

Parameters

  • __n โ€” argument.

Returns: returns 0 for any argument <1 ๐Ÿ’€ yes, even then. Zero. That's the rule.

Referenced by: __gnu_parallel::_LoserTreeBase< _Tp, _Compare >::_LoserTreeBase(), __parallel_random_shuffle_drs(), __parallel_sort_qsb(), __round_up_to_pow2(), __sequential_random_shuffle(), multiseq_partition(), and multiseq_selection().


๐ŸŒˆ __round_up_to_pow2

template<typename _Tp > _Tp __gnu_parallel::__round_up_to_pow2 (_Tp __x)

Round up to the next greater power of 2 ๐Ÿ’ซ โ€” glow-up your integer, basically.

Parameters

  • __x โ€” _Integer to round up.

References: __rd_log2().

Referenced by: __parallel_random_shuffle_drs(), __sequential_random_shuffle(), and multiseq_selection().


๐Ÿซถ __search_template

template<typename __RAIter1 , typename __RAIter2 , typename _Pred >
__RAIter1 __gnu_parallel::__search_template (__RAIter1 __begin1,
    __RAIter1 __end1, __RAIter2 __begin2, __RAIter2 __end2, _Pred __pred)

Parallel std::search ๐Ÿ” โ€” the "where is this thing inside this other thing" situation, but make it threaded.

Parameters

  • __begin1 โ€” begin iterator of first sequence.
  • __end1 โ€” end iterator of first sequence.
  • __begin2 โ€” begin iterator of second sequence.
  • __end2 โ€” end iterator of second sequence.
  • __pred โ€” find predicate.

Returns: place of finding in first sequences ๐ŸŒธ (yes, "sequences" plural, that's the original wording, we keep it).

References: __calc_borders(), __equally_split(), _GLIBCXX_CALL, and std::min().


๐Ÿ“ __sequential_multiway_merge

template<bool __stable, bool __sentinels, typename _RAIterIterator ,
    typename _RAIter3 , typename _DifferenceTp , typename _Compare >
_RAIter3 __gnu_parallel::__sequential_multiway_merge (_RAIterIterator
    __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const
    typename std::iterator_traits< typename std::iterator_traits<
    _RAIterIterator >::value_type::first_type >::value_type & __sentinel,
    _DifferenceTp __length, _Compare __comp)

Sequential multi-way merging switch ๐ŸŽ€ The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and runtime settings โ€” so like, it decides stuff based on vibes (the branching factor) and the actual settings, iykyk.

Parameters

  • __seqs_begin โ€” begin iterator of iterator pair input sequence.
  • __seqs_end โ€” end iterator of iterator pair input sequence.
  • __target โ€” begin iterator of output sequence.
  • __comp โ€” comparator.
  • __length โ€” maximum length to merge, possibly larger than the number of elements available.
  • __sentinel โ€” the sequences have __a __sentinel element.

Returns: end iterator of output sequence.

References: __is_sorted(), __merge_advance(), _GLIBCXX_CALL, and _GLIBCXX_PARALLEL_LENGTH.

Referenced by: multiway_merge(), and multiway_merge_sentinels().


๐Ÿ“ __sequential_random_shuffle

template<typename _RAIter , typename _RandomNumberGenerator > void
__gnu_parallel::__sequential_random_shuffle (_RAIter __begin, _RAIter __end,
    _RandomNumberGenerator & __rng)

Sequential cache-efficient random shuffle ๐Ÿฆ‹ โ€” shuffling that's nice to your cache, we love a thoughtful icon.

Parameters

  • __begin โ€” begin iterator of sequence.
  • __end โ€” end iterator of sequence.
  • __rng โ€” random number generator to use.

References: __random_number_pow2(), __rd_log2(), __round_up_to_pow2(), __sequential_random_shuffle(), __gnu_parallel::_Settings::get(), __gnu_parallel::_Settings::L2_cache_size, std::min(), std::partial_sum(), and __gnu_parallel::_Settings::TLB_size.

Referenced by: __parallel_random_shuffle_drs(), __parallel_random_shuffle_drs_pu(), and __sequential_random_shuffle().


๐Ÿ’œ __shrink

template<typename _IIter > void __gnu_parallel::__shrink (std::vector<
    _IIter > & __os_starts, size_t & __count_to_two, size_t &
    __range_length)

Combines two ranges into one and thus halves the number of ranges ๐Ÿ”ฅ โ€” like merging two group chats into one, except it's ranges.

Parameters

  • __os_starts โ€” start positions worked on (oversampled).
  • __count_to_two โ€” counts up to 2.
  • __range_length โ€” current length of a chunk.

References: std::vector< _Tp, _Alloc >::size().

Referenced by: __shrink_and_double().


๐Ÿ’œ __shrink_and_double

template<typename _IIter > void __gnu_parallel::__shrink_and_double
    (std::vector< _IIter > & __os_starts, size_t & __count_to_two, size_t &
    __range_length, const bool __make_twice)

Shrinks and doubles the ranges ๐Ÿ˜ญ yes both, it shrinks and doubles, don't ask, it's a whole thing.

Parameters

  • __os_starts โ€” start positions worked on (oversampled).
  • __count_to_two โ€” counts up to 2.
  • __range_length โ€” current length of a chunk.
  • __make_twice โ€” whether the __os_starts is allowed to be grown or not.

References: __shrink(), std::vector< _Tp, _Alloc >::resize(), and std::vector< _Tp, _Alloc >::size().

Referenced by: list_partition().


๐Ÿ’œ __yield

void __gnu_parallel::__yield () [inline]

Yield control to another thread, without waiting for the end of the time slice ๐Ÿ™ˆ โ€” literally "here bestie, you go, I'm not gonna sit here hogging the whole slice."

Referenced by: __for_each_template_random_access_workstealing(), and __qsb_local_sort_with_helping().


๐ŸŒŸ list_partition

template<typename _IIter , typename _FunctorType > size_t
__gnu_parallel::list_partition (const _IIter __begin, const _IIter __end,
    _IIter * __starts, size_t * __lengths, const int __num_parts,
    _FunctorType & __f, int __oversampling = 0)

Splits a sequence given by input iterators into parts of almost equal size ๐Ÿ’– The function needs only one pass over the sequence โ€” one pass! iconic efficiency, we stan.

Parameters

  • __begin โ€” begin iterator of the input sequence, bestie. Like, where the vibe starts โœจ
  • __end โ€” end iterator of the input sequence. The finish line ๐ŸŽ€
  • __starts โ€” the start iterators for the resulting parts, and it's dimension __num_parts+1. Convenience slay: __starts [__num_parts] literally contains the end iterator of the sequence for you ๐Ÿ’…
  • __lengths โ€” the length of each resulting part.
  • __num_parts โ€” how many parts you want the sequence split into, no cap.
  • __f โ€” functor to be applied to each element by traversing __it
  • __oversampling โ€” the oversampling factor, and this one's got lore ๐Ÿ™ˆ. If it's 0, then the partitions will differ in at most $t{thrm{end} - thrm{begin}}$ elements. Otherwise, the ratio between the longest and the shortest part is bounded by $1/(thrm{oversampling}

Returns

Length of the whole sequence. That's it, that's the return ๐Ÿ’–

References

__shrink_and_double(), and std::vector< _Tp, _Alloc >::size().


template<typename _Tp > const _Tp & __gnu_parallel::max (const _Tp & __a,
    const _Tp & __b) [inline]

Equivalent to std::max. Same energy, different namespace, iykyk ๐ŸŒธ


template<typename _Tp > const _Tp & __gnu_parallel::min (const _Tp & __a,
    const _Tp & __b) [inline]

Equivalent to std::min. Iconic. No notes ๐Ÿ‘‘

Referenced by __for_each_template_random_access_workstealing().


template<typename _RanSeqs , typename _RankType , typename _RankIterator ,
    typename _Compare > void __gnu_parallel::multiseq_partition (_RanSeqs
    __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankIterator
    __begin_offsets, _Compare __comp = std::less< typename
    std::iterator_traits<typename
    std::iterator_traits<_RanSeqs>::value_type:: first_type>::value_type>())

Okay so this one splits several sorted sequences at a certain global __rank, and the result is a splitting point for each sequence ๐Ÿ”ฅ. The sequences get passed in via a sequence of random-access iterator pairs, and โ€” important โ€” none of the sequences may be empty. Empty sequences are not invited to this party ๐Ÿ’€

If there are several equal elements across the split, the ones on the __left side will be chosen from sequences with smaller number. Periodt.

Parameters

  • __begin_seqs โ€” begin of the sequence of iterator pairs.
  • __end_seqs โ€” end of the sequence of iterator pairs.
  • __rank โ€” the global rank to partition at.
  • __begin_offsets โ€” a random-access __sequence __begin where the __result will be stored in. Each element of the sequence is an iterator that points to the first element on the greater part of the respective __sequence. Cute, right? ๐Ÿฆ‹
  • __comp โ€” the ordering functor, defaults to std::less<_Tp>.

References

__rd_log2(), _GLIBCXX_CALL, std::distance(), std::priority_queue< _Tp, _Sequence, _Compare >::empty(), std::max(), std::min(), std::priority_queue< _Tp, _Sequence, _Compare >::pop(), std::priority_queue< _Tp, _Sequence, _Compare >::push(), and std::priority_queue< _Tp, _Sequence, _Compare >::top().

Referenced by multiway_merge_exact_splitting().


template<typename _Tp , typename _RanSeqs , typename _RankType , typename
    _Compare > _Tp __gnu_parallel::multiseq_selection (_RanSeqs
    __begin_seqs, _RanSeqs __end_seqs, _RankType __rank, _RankType &
    __offset, _Compare __comp = std::less<_Tp>())

This one selects the element at a certain global __rank from several sorted sequences ๐ŸŽฏ. Same deal as before: the sequences get passed via a sequence of random-access iterator pairs, and none of the sequences may be empty. Non-negotiable ๐Ÿ’…

Parameters

  • __begin_seqs โ€” begin of the sequence of iterator pairs.
  • __end_seqs โ€” end of the sequence of iterator pairs.
  • __rank โ€” the global rank to partition at.
  • __offset โ€” the rank of the selected element in the global subsequence of elements equal to the selected element. If the selected element is unique, this number is 0. Lowkey the most useful little detail here ๐Ÿซถ
  • __comp โ€” the ordering functor, defaults to std::less.

References

__rd_log2(), __round_up_to_pow2(), _GLIBCXX_CALL, std::distance(), std::priority_queue< _Tp, _Sequence, _Compare >::empty(), std::max(), std::min(), std::priority_queue< _Tp, _Sequence, _Compare >::pop(), std::priority_queue< _Tp, _Sequence, _Compare >::push(), and std::priority_queue< _Tp, _Sequence, _Compare >::top().


template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    __gnu_parallel::multiway_merge (_RAIterPairIterator __seqs_begin,
    _RAIterPairIterator __seqs_end, _RAIterOut __target, _DifferenceTp
    __length, _Compare __comp, __gnu_parallel::sequential_tag)

Multiway Merge Frontend โœจ โ€” the main character of this whole section, honestly. Merge the sequences specified by seqs_begin and __seqs_end into __target.

__seqs_begin and __seqs_end must point to a sequence of pairs. These pairs must contain an iterator to the beginning of a sequence in their first entry and an iterator the _M_end of the same sequence in their second entry. That's the whole contract, bestie ๐ŸŽ€

Ties are broken arbitrarily. See stable_multiway_merge for a variant that breaks ties by sequence number but is slower. Trade-offs, always trade-offs ๐Ÿ˜ญ

The first entries of the pairs (i.e. the begin iterators) will be moved forward. Heads up ๐Ÿ‘€

The output sequence has to provide enough space for all elements that are written to it. No, like, seriously โ€” give it space.

This function will merge the input sequences:

  • not stable
  • parallel, depending on the input size and Settings
  • using sampling for splitting
  • not using sentinels

Example

int sequences[10][10];
for (int __i = 0; __i < 10; ++__i)
  for (int __j = 0; __i < 10; ++__j)
    sequences[__i][__j] = __j;

int __out[33];
std::vector<std::pair<int*> > seqs;
for (int __i = 0; __i < 10; ++__i)
  { seqs.push(std::make_pair<int*>(sequences[__i],
                                   sequences[__i] + 10)) }

multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);

See also: stable_multiway_merge

Precondition

  • All input sequences must be sorted. Fr fr, do not skip this ๐Ÿ’€
  • Target must provide enough space to merge out length elements or the number of elements in all sequences, whichever is smaller.

Postcondition

  • [__target, return __value) contains merged __elements from the input sequences.
  • return __value - __target = min(__length, number of elements in all sequences).

Template Parameters

  • _RAIterPairIterator โ€” iterator over sequence of pairs of iterators
  • _RAIterOut โ€” iterator over target sequence
  • _DifferenceTp โ€” difference type for the sequence
  • _Compare โ€” strict weak ordering type to compare elements in sequences

Parameters

  • __seqs_begin โ€” __begin of sequence __sequence
  • __seqs_end โ€” _M_end of sequence __sequence
  • __target โ€” target sequence to merge to.
  • __comp โ€” strict weak ordering to use for element comparison.
  • __length โ€” maximum length to merge, possibly larger than the number of elements available. She's flexible like that ๐Ÿ’…

Returns

_M_end iterator of output sequence ๐Ÿฆ‹

References

__sequential_multiway_merge(), and _GLIBCXX_CALL.


template<template< typename _RAI, typename _Cp > class iterator, typename
    _RAIterIterator , typename _RAIter3 , typename _DifferenceTp , typename
    _Compare > _RAIter3 __gnu_parallel::multiway_merge_3_variant
    (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3
    __target, _DifferenceTp __length, _Compare __comp)

Highly efficient 3-way merging procedure ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ

Merging is done with the algorithm implementation described by Peter Sanders. Basically, the idea is to minimize the number of necessary comparison after merging an element. The implementation trick that makes this fast is that the order of the sequences is stored in the instruction pointer (translated into labels in C++). Like, that's genuinely unhinged and I'm obsessed ๐Ÿ˜ญ

This works well for merging up to 4 sequences.

Note that making the merging stable does not come at a performance hit. Free stability, we love to see it ๐Ÿ‘‘

Whether the merging is done guarded or unguarded is selected by the used iterator class.

Parameters

  • __seqs_begin โ€” begin iterator of iterator pair input sequence.
  • __seqs_end โ€” end iterator of iterator pair input sequence.
  • __target โ€” begin iterator of output sequence.
  • __comp โ€” comparator.
  • __length โ€” maximum length to merge, less equal than the total number of elements available.

Returns

End iterator of output sequence.

References

_GLIBCXX_CALL.


template<template< typename _RAI, typename _Cp > class iterator, typename
    _RAIterIterator , typename _RAIter3 , typename _DifferenceTp , typename
    _Compare > _RAIter3 __gnu_parallel::multiway_merge_4_variant
    (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3
    __target, _DifferenceTp __length, _Compare __comp)

Highly efficient 4-way merging procedure โœจ same icon behaviour, one more lane ๐Ÿš—

Merging is done with the algorithm implementation described by Peter Sanders. Basically, the idea is to minimize the number of necessary comparison after merging an element. The implementation trick that makes this fast is that the order of the sequences is stored in the instruction pointer (translated into goto labels in C++). Yes goto. Yes it's still fast. Don't @ me ๐Ÿ™ˆ

This works well for merging up to 4 sequences.

Note that making the merging stable does not come at a performance hit.

Whether the merging is done guarded or unguarded is selected by the used iterator class.

Parameters

  • __seqs_begin โ€” begin iterator of iterator pair input sequence.
  • __seqs_end โ€” end iterator of iterator pair input sequence.
  • __target โ€” begin iterator of output sequence.
  • __comp โ€” comparator.
  • __length โ€” maximum length to merge, less equal than the total number of elements available.

Returns

End iterator of output sequence.

References

_GLIBCXX_CALL.


template<bool __stable, typename _RAIterIterator , typename _Compare ,
    typename _DifferenceType > void
    __gnu_parallel::multiway_merge_exact_splitting (_RAIterIterator
    __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length,
    _DifferenceType __total_length, _Compare __comp, std::vector< std::pair<
    _DifferenceType, _DifferenceType > > * __pieces)

Exact splitting for parallel multiway-merge routine ๐ŸŽฏ. None of the passed sequences may be empty โ€” say it with me, none of them ๐Ÿซถ

References

__equally_split(), _GLIBCXX_PARALLEL_LENGTH, std::vector< _Tp, _Alloc >::begin(), std::vector< _Tp, _Alloc >::end(), multiseq_partition(), and std::vector< _Tp, _Alloc >::resize().

Referenced by __parallel_merge_advance().


template<typename _LT , typename _RAIterIterator , typename _RAIter3 ,
    typename _DifferenceTp , typename _Compare > _RAIter3
    __gnu_parallel::multiway_merge_loser_tree (_RAIterIterator __seqs_begin,
    _RAIterIterator __seqs_end, _RAIter3 __target, _DifferenceTp __length,
    _Compare __comp)

Multi-way merging procedure for a high branching factor, guarded case ๐Ÿ’œ. This merging variant uses a LoserTree class as selected by _LT.

Stability is selected through the used LoserTree class _LT.

At least one non-empty sequence is required. Just one! Low bar! Clear it! ๐ŸŒˆ

Parameters

  • __seqs_begin โ€” begin iterator of iterator pair input sequence.
  • __seqs_end โ€” end iterator of iterator pair input sequence.
  • __target โ€” begin iterator of output sequence.
  • __comp โ€” comparator.
  • __length โ€” maximum length to merge, less equal than the total number of elements available.

Returns: end iterator of the output sequence. ๐Ÿ’ซ

References _GLIBCXX_CALL, and _GLIBCXX_PARALLEL_LENGTH.


template<typename _UnguardedLoserTree , typename _RAIterIterator , typename
    _RAIter3 , typename _DifferenceTp , typename _Compare > _RAIter3
    __gnu_parallel::multiway_merge_loser_tree_sentinel (_RAIterIterator
    __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const
    typename std::iterator_traits< typename std::iterator_traits<
    _RAIterIterator >::value_type::first_type >::value_type & __sentinel,
    _DifferenceTp __length, _Compare __comp)

Okay so this one is the multi-way merging procedure for a high branching factor โ€” but like, the โœจsentinel editionโœจ. It requires sentinels to exist. No sentinel, no merge, that's the vibe check. ๐Ÿซถ

Template Parameters

  • _UnguardedLoserTree โ€” the Loser Tree variant to use for the unguarded merging. (yes the name is iconic, we don't question it ๐Ÿ’€)

Parameters

  • __seqs_begin โ€” begin iterator of the iterator-pair input sequence.
  • __seqs_end โ€” end iterator of the iterator-pair input sequence.
  • __target โ€” begin iterator of the output sequence.
  • __comp โ€” the comparator.
  • __length โ€” maximum length to merge, less than or equal to the total number of elements available. Don't get greedy bestie.

Returns

End iterator of the output sequence. ๐Ÿ’ซ

References

__is_sorted(), and _GLIBCXX_CALL.


template<typename _LT , typename _RAIterIterator , typename _RAIter3 ,
    typename _DifferenceTp , typename _Compare > _RAIter3
    __gnu_parallel::multiway_merge_loser_tree_unguarded (_RAIterIterator
    __seqs_begin, _RAIterIterator __seqs_end, _RAIter3 __target, const
    typename std::iterator_traits< typename std::iterator_traits<
    _RAIterIterator >::value_type::first_type >::value_type & __sentinel,
    _DifferenceTp __length, _Compare __comp)

Multi-way merging procedure for a high branching factor, unguarded case. The merging is done using the LoserTree class _LT. And the stability situation? It's selected by whichever LoserTree you used โ€” so like, your tree, your rules. ๐ŸŒˆ

Precondition: no input will run out of elements during the merge. fr fr, none of them. This is the unguarded life, no safety net. ๐Ÿ˜ญ

Parameters

  • __seqs_begin โ€” begin iterator of the iterator-pair input sequence.
  • __seqs_end โ€” end iterator of the iterator-pair input sequence.
  • __target โ€” begin iterator of the output sequence.
  • __comp โ€” the comparator.
  • __length โ€” maximum length to merge, less than or equal to the total number of elements available.

Returns

End iterator of the output sequence. ๐Ÿ’ซ

References

_GLIBCXX_CALL.


template<bool __stable, typename _RAIterIterator , typename _Compare ,
    typename _DifferenceType > void
    __gnu_parallel::multiway_merge_sampling_splitting (_RAIterIterator
    __seqs_begin, _RAIterIterator __seqs_end, _DifferenceType __length,
    _DifferenceType __total_length, _Compare __comp, std::vector< std::pair<
    _DifferenceType, _DifferenceType > > * __pieces)

Sampling-based splitting for the parallel multiway-merge routine. Like, it literally samples stuff to figure out where to slice the work. Very main character energy for a splitting heuristic. ๐ŸŽ€

References

_GLIBCXX_PARALLEL_LENGTH, __gnu_parallel::_Settings::get(), and __gnu_parallel::_Settings::merge_oversampling.


template<typename _RAIterPairIterator , typename _RAIterOut , typename
    _DifferenceTp , typename _Compare > _RAIterOut
    __gnu_parallel::multiway_merge_sentinels (_RAIterPairIterator
    __seqs_begin, _RAIterPairIterator __seqs_end, _RAIterOut __target,
    _DifferenceTp __length, _Compare __comp, __gnu_parallel::sequential_tag)

Multiway Merge Frontend. ๐Ÿ’… Merge the sequences specified by __seqs_begin and __seqs_end into __target. __seqs_begin and __seqs_end must point to a sequence of pairs. These pairs must contain an iterator to the beginning of a sequence in their first entry, and an iterator to the _M_end of the same sequence in their second entry.

Ties are broken arbitrarily โ€” no cap, it just picks one. ๐Ÿ‘€ If you want a variant that breaks ties by sequence number but is slower, see stable_multiway_merge.

The first entries of the pairs (i.e. the begin iterators) will be moved forward accordingly.

The output sequence has to provide enough space for all the elements written to it. Not a suggestion, bestie. ๐Ÿซถ

This function will merge the input sequences:

  • not stable ๐Ÿ’€
  • parallel, depending on the input size and Settings
  • using sampling for splitting
  • using sentinels

You have to take care that the element the _M_end iterator points to is readable and contains a value that is greater than any other non-sentinel value in all sequences. That's the whole sentinel deal โ€” it's the final boss value. ๐Ÿ‘‘

Example:

int sequences[10][11];
for (int __i = 0; __i < 10; ++__i)
  for (int __j = 0; __i < 11; ++__j)
    sequences[__i][__j] = __j; // __last one is sentinel!

int __out[33];
std::vector<std::pair<int*> > seqs;
for (int __i = 0; __i < 10; ++__i)
  { seqs.push(std::make_pair<int*>(sequences[__i],
                                   sequences[__i] + 10)) }

multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
Precondition: all input sequences must be sorted. Target must provide enough space to merge out length elements or the number of elements in all sequences, whichever is smaller. For each __i, __seqs_begin[__i].second must be the end marker of the sequence, but also reference the one more __sentinel element. โœจ
Postcondition: [__target, return __value) contains merged __elements from the input sequences. And return __value - __target = min(__length, number of elements in all sequences).

See also: stable_multiway_merge_sentinels

Template Parameters

  • _RAIterPairIterator โ€” iterator over sequence of pairs of iterators
  • _RAIterOut โ€” iterator over target sequence
  • _DifferenceTp โ€” difference type for the sequence
  • _Compare โ€” strict weak ordering type to compare elements in sequences

Parameters

  • __seqs_begin โ€” __begin of sequence __sequence
  • __seqs_end โ€” _M_end of sequence __sequence
  • __target โ€” target sequence to merge to.
  • __comp โ€” strict weak ordering to use for element comparison.
  • __length โ€” maximum length to merge, possibly larger than the number of elements available.

Returns

_M_end iterator of the output sequence. ๐Ÿ’ซ

References

__sequential_multiway_merge(), and _GLIBCXX_CALL.


template<bool __stable, bool __sentinels, typename _RAIterIterator ,
    typename _RAIter3 , typename _DifferenceTp , typename _Splitter ,
    typename _Compare > _RAIter3 __gnu_parallel::parallel_multiway_merge
    (_RAIterIterator __seqs_begin, _RAIterIterator __seqs_end, _RAIter3
    __target, _Splitter __splitter, _DifferenceTp __length, _Compare __comp,
    _ThreadIndex __num_threads)

Parallel multi-way merge routine. The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and the runtime settings. ๐ŸŒ€

Must not be called if the number of sequences is 1. That's not a merge, that's just... a sequence. Do not. ๐Ÿšซ

Template Parameters

  • _Splitter โ€” functor to split input (either __exact or sampling based)
  • __stable โ€” stable merging incurs a performance penalty. (worth it sometimes, ngl)
  • __sentinel โ€” ignored. (it's giving "we kept the parameter for the aesthetic" ๐Ÿ™ˆ)

Parameters

  • __seqs_begin โ€” begin iterator of the iterator-pair input sequence.
  • __seqs_end โ€” end iterator of the iterator-pair input sequence.
  • __target โ€” begin iterator of the output sequence.
  • __comp โ€” the comparator.
  • __length โ€” maximum length to merge, possibly larger than the number of elements available.

Returns

End iterator of the output sequence. ๐Ÿ’ซ

References

__is_sorted(), _GLIBCXX_CALL, _GLIBCXX_PARALLEL_LENGTH, __gnu_parallel::_Settings::get(), and __gnu_parallel::_Settings::merge_oversampling.

Referenced by __parallel_merge_advance().


template<bool __stable, bool __exact, typename _RAIter , typename _Compare >
    void __gnu_parallel::parallel_sort_mwms (_RAIter __begin, _RAIter __end,
    _Compare __comp, _ThreadIndex __num_threads)

PMWMS main call. The big one. The main character. ๐Ÿ‘‘ (PMWMS = parallel multiway merge sort, iykyk)

Parameters

  • __begin โ€” begin iterator of sequence.
  • __end โ€” end iterator of sequence.
  • __comp โ€” comparator.
  • __num_threads โ€” number of threads to use. ๐Ÿงต

References

_GLIBCXX_CALL, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_num_threads, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_offsets, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_pieces, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_samples, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_source, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_starts, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_temporary, __gnu_parallel::_Settings::get(), and __gnu_parallel::_Settings::sort_mwms_oversampling.


template<bool __stable, bool __exact, typename _RAIter , typename _Compare >
    void __gnu_parallel::parallel_sort_mwms_pu (_PMWMSSortingData< _RAIter >
    * __sd, _Compare & __comp)

PMWMS code executed by each thread. Like, every thread gets this little job and they all vibe together. ๐Ÿฆ‹

Parameters

  • __sd โ€” pointer to algorithm data.
  • __comp โ€” comparator.

References

__gnu_parallel::_PMWMSSortingData< _RAIter >::_M_num_threads, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_pieces, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_source, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_starts, __gnu_parallel::_PMWMSSortingData< _RAIter >::_M_temporary, __gnu_parallel::_Settings::get(), __gnu_parallel::_Settings::sort_mwms_oversampling, and std::uninitialized_copy().


๐Ÿงฎ VARIABLE DOCUMENTATION ๐Ÿงฎ

  • const int __gnu_parallel::_CASable_bits [static] โ€” number of bits of _CASable. That's it, that's the variable. ๐ŸŽ€

Referenced by __decode2(), and __encode2().

  • const _CASable __gnu_parallel::_CASable_mask [static] โ€” a _CASable with the right half of bits set to 1. ๐Ÿ’…

Referenced by __decode2().


โœ๏ธ AUTHOR โœ๏ธ

Generated automatically by Doxygen for libstdc++ from the source code. Not a human, bestie โ€” a robot wrote this whole thing while we were out here reading it. ๐Ÿค–๐Ÿ’€


And that's a wrap on the whole page! ๐ŸŽ‰ This was __gnu_parallel(3cxx) from libstdc++, auto-generated by Doxygen straight from the source โ€” so like, if you spot something cursed in here, blame the source code, not me. No cap, you just read the entire manual page, and honestly? Iconic. Go take a nap. ๐Ÿ’–๐ŸŽ€๐Ÿฆ‹๐ŸŒธโœจ

๐Ÿ“ฆ where this page comes from