Home | History | Annotate | Download | only in parallel
      1 // -*- C++ -*-
      2 
      3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the terms
      7 // of the GNU General Public License as published by the Free Software
      8 // Foundation; either version 3, or (at your option) any later
      9 // version.
     10 
     11 // This library is distributed in the hope that it will be useful, but
     12 // WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 // General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file parallel/multiway_merge.h
     26 *  @brief Implementation of sequential and parallel multiway merge.
     27 *
     28 *  Explanations on the high-speed merging routines in the appendix of
     29 *
     30 *  P. Sanders.
     31 *  Fast priority queues for cached memory.
     32 *  ACM Journal of Experimental Algorithmics, 5, 2000.
     33 *
     34 *  This file is a GNU parallel extension to the Standard C++ Library.
     35 */
     36 
     37 // Written by Johannes Singler and Manuel Holtgrewe.
     38 
     39 #ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
     40 #define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
     41 
     42 #include <vector>
     43 
     44 #include <bits/stl_algo.h>
     45 #include <parallel/features.h>
     46 #include <parallel/parallel.h>
     47 #include <parallel/losertree.h>
     48 #if _GLIBCXX_ASSERTIONS
     49 #include <parallel/checkers.h>
     50 #endif
     51 
     52 /** @brief Length of a sequence described by a pair of iterators. */
     53 #define _GLIBCXX_PARALLEL_LENGTH(s) ((s).second - (s).first)
     54 
     55 namespace __gnu_parallel
     56 {
     57 
     58 // Announce guarded and unguarded iterator.
     59 
     60 template<typename RandomAccessIterator, typename Comparator>
     61   class guarded_iterator;
     62 
     63 // Making the arguments const references seems to dangerous,
     64 // the user-defined comparator might not be const.
     65 template<typename RandomAccessIterator, typename Comparator>
     66   inline bool
     67   operator<(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
     68              guarded_iterator<RandomAccessIterator, Comparator>& bi2);
     69 
     70 template<typename RandomAccessIterator, typename Comparator>
     71   inline bool
     72   operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
     73               guarded_iterator<RandomAccessIterator, Comparator>& bi2);
     74 
     75 /** @brief Iterator wrapper supporting an implicit supremum at the end
     76  *         of the sequence, dominating all comparisons.
     77  *
     78  * The implicit supremum comes with a performance cost.
     79  *
     80  * Deriving from RandomAccessIterator is not possible since
     81  * RandomAccessIterator need not be a class.
     82  */
     83 template<typename RandomAccessIterator, typename Comparator>
     84   class guarded_iterator
     85   {
     86   private:
     87     /** @brief Current iterator position. */
     88     RandomAccessIterator current;
     89 
     90     /** @brief End iterator of the sequence. */
     91     RandomAccessIterator end;
     92 
     93     /** @brief Comparator. */
     94     Comparator& comp;
     95 
     96   public:
     97     /** @brief Constructor. Sets iterator to beginning of sequence.
     98     *  @param begin Begin iterator of sequence.
     99     *  @param end End iterator of sequence.
    100     *  @param comp Comparator provided for associated overloaded
    101     *  compare operators. */
    102     guarded_iterator(RandomAccessIterator begin,
    103                      RandomAccessIterator end, Comparator& comp)
    104     : current(begin), end(end), comp(comp)
    105     { }
    106 
    107     /** @brief Pre-increment operator.
    108     *  @return This. */
    109     guarded_iterator<RandomAccessIterator, Comparator>&
    110     operator++()
    111     {
    112       ++current;
    113       return *this;
    114     }
    115 
    116     /** @brief Dereference operator.
    117     *  @return Referenced element. */
    118     typename std::iterator_traits<RandomAccessIterator>::value_type&
    119     operator*()
    120     { return *current; }
    121 
    122     /** @brief Convert to wrapped iterator.
    123     *  @return Wrapped iterator. */
    124     operator RandomAccessIterator()
    125     { return current; }
    126 
    127     friend bool
    128     operator< <RandomAccessIterator, Comparator>(
    129       guarded_iterator<RandomAccessIterator, Comparator>& bi1,
    130       guarded_iterator<RandomAccessIterator, Comparator>& bi2);
    131 
    132     friend bool
    133     operator<= <RandomAccessIterator, Comparator>(
    134       guarded_iterator<RandomAccessIterator, Comparator>& bi1,
    135       guarded_iterator<RandomAccessIterator, Comparator>& bi2);
    136   };
    137 
    138 /** @brief Compare two elements referenced by guarded iterators.
    139  *  @param bi1 First iterator.
    140  *  @param bi2 Second iterator.
    141  *  @return @c True if less. */
    142 template<typename RandomAccessIterator, typename Comparator>
    143   inline bool
    144   operator<(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
    145             guarded_iterator<RandomAccessIterator, Comparator>& bi2)
    146   {
    147     if (bi1.current == bi1.end)	//bi1 is sup
    148       return bi2.current == bi2.end;	//bi2 is not sup
    149     if (bi2.current == bi2.end)	//bi2 is sup
    150       return true;
    151     return (bi1.comp)(*bi1, *bi2);	//normal compare
    152   }
    153 
    154 /** @brief Compare two elements referenced by guarded iterators.
    155  *  @param bi1 First iterator.
    156  *  @param bi2 Second iterator.
    157  *  @return @c True if less equal. */
    158 template<typename RandomAccessIterator, typename Comparator>
    159   inline bool
    160   operator<=(guarded_iterator<RandomAccessIterator, Comparator>& bi1,
    161                guarded_iterator<RandomAccessIterator, Comparator>& bi2)
    162   {
    163     if (bi2.current == bi2.end)	//bi1 is sup
    164       return bi1.current != bi1.end;	//bi2 is not sup
    165     if (bi1.current == bi1.end)	//bi2 is sup
    166       return false;
    167     return !(bi1.comp)(*bi2, *bi1);	//normal compare
    168   }
    169 
    170 template<typename RandomAccessIterator, typename Comparator>
    171   class unguarded_iterator;
    172 
    173 template<typename RandomAccessIterator, typename Comparator>
    174   inline bool
    175   operator<(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
    176             unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
    177 
    178 template<typename RandomAccessIterator, typename Comparator>
    179   inline bool
    180   operator<=(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
    181              unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
    182 
    183 template<typename RandomAccessIterator, typename Comparator>
    184   class unguarded_iterator
    185   {
    186   private:
    187     /** @brief Current iterator position. */
    188     RandomAccessIterator current;
    189     /** @brief Comparator. */
    190     mutable Comparator& comp;
    191 
    192   public:
    193     /** @brief Constructor. Sets iterator to beginning of sequence.
    194     *  @param begin Begin iterator of sequence.
    195     *  @param end Unused, only for compatibility.
    196     *  @param comp Unused, only for compatibility. */
    197     unguarded_iterator(RandomAccessIterator begin,
    198                        RandomAccessIterator end, Comparator& comp)
    199     : current(begin), comp(comp)
    200     { }
    201 
    202     /** @brief Pre-increment operator.
    203     *  @return This. */
    204     unguarded_iterator<RandomAccessIterator, Comparator>&
    205     operator++()
    206     {
    207       ++current;
    208       return *this;
    209     }
    210 
    211     /** @brief Dereference operator.
    212     *  @return Referenced element. */
    213     typename std::iterator_traits<RandomAccessIterator>::value_type&
    214     operator*()
    215     { return *current; }
    216 
    217     /** @brief Convert to wrapped iterator.
    218     *  @return Wrapped iterator. */
    219     operator RandomAccessIterator()
    220     { return current; }
    221 
    222     friend bool
    223     operator< <RandomAccessIterator, Comparator>(
    224       unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
    225       unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
    226 
    227     friend bool
    228     operator<= <RandomAccessIterator, Comparator>(
    229       unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
    230       unguarded_iterator<RandomAccessIterator, Comparator>& bi2);
    231   };
    232 
    233 /** @brief Compare two elements referenced by unguarded iterators.
    234  *  @param bi1 First iterator.
    235  *  @param bi2 Second iterator.
    236  *  @return @c True if less. */
    237 template<typename RandomAccessIterator, typename Comparator>
    238   inline bool
    239   operator<(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
    240             unguarded_iterator<RandomAccessIterator, Comparator>& bi2)
    241   {
    242     // Normal compare.
    243     return (bi1.comp)(*bi1, *bi2);
    244   }
    245 
    246 /** @brief Compare two elements referenced by unguarded iterators.
    247  *  @param bi1 First iterator.
    248  *  @param bi2 Second iterator.
    249  *  @return @c True if less equal. */
    250 template<typename RandomAccessIterator, typename Comparator>
    251   inline bool
    252   operator<=(unguarded_iterator<RandomAccessIterator, Comparator>& bi1,
    253             unguarded_iterator<RandomAccessIterator, Comparator>& bi2)
    254   {
    255     // Normal compare.
    256     return !(bi1.comp)(*bi2, *bi1);
    257   }
    258 
    259 /** @brief Highly efficient 3-way merging procedure.
    260  *
    261  * Merging is done with the algorithm implementation described by Peter
    262  * Sanders.  Basically, the idea is to minimize the number of necessary
    263  * comparison after merging out an element.  The implementation trick
    264  * that makes this fast is that the order of the sequences is stored
    265  * in the instruction pointer (translated into labels in C++).
    266  *
    267  * This works well for merging up to 4 sequences.
    268  *
    269  * Note that making the merging stable does <em>not</em> come at a
    270  * performance hit.
    271  *
    272  * Whether the merging is done guarded or unguarded is selected by the
    273  * used iterator class.
    274  *
    275  * @param seqs_begin Begin iterator of iterator pair input sequence.
    276  * @param seqs_end End iterator of iterator pair input sequence.
    277  * @param target Begin iterator out output sequence.
    278  * @param comp Comparator.
    279  * @param length Maximum length to merge, less equal than the
    280  * total number of elements available.
    281  *
    282  * @return End iterator of output sequence.
    283  */
    284 template<template<typename RAI, typename C> class iterator,
    285 	 typename RandomAccessIteratorIterator,
    286 	 typename RandomAccessIterator3,
    287 	 typename _DifferenceTp,
    288 	 typename Comparator>
    289   RandomAccessIterator3
    290   multiway_merge_3_variant(
    291       RandomAccessIteratorIterator seqs_begin,
    292       RandomAccessIteratorIterator seqs_end,
    293       RandomAccessIterator3 target,
    294       _DifferenceTp length, Comparator comp)
    295   {
    296     _GLIBCXX_CALL(length);
    297 
    298     typedef _DifferenceTp difference_type;
    299 
    300     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    301       ::value_type::first_type
    302       RandomAccessIterator1;
    303     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    304       value_type;
    305 
    306     if (length == 0)
    307       return target;
    308 
    309 #if _GLIBCXX_ASSERTIONS
    310     _DifferenceTp orig_length = length;
    311 #endif
    312 
    313     iterator<RandomAccessIterator1, Comparator>
    314       seq0(seqs_begin[0].first, seqs_begin[0].second, comp),
    315       seq1(seqs_begin[1].first, seqs_begin[1].second, comp),
    316       seq2(seqs_begin[2].first, seqs_begin[2].second, comp);
    317 
    318     if (seq0 <= seq1)
    319       {
    320         if (seq1 <= seq2)
    321           goto s012;
    322         else
    323           if (seq2 <  seq0)
    324             goto s201;
    325           else
    326             goto s021;
    327       }
    328     else
    329       {
    330         if (seq1 <= seq2)
    331           {
    332             if (seq0 <= seq2)
    333               goto s102;
    334             else
    335               goto s120;
    336           }
    337         else
    338           goto s210;
    339       }
    340 #define _GLIBCXX_PARALLEL_MERGE_3_CASE(a,b,c,c0,c1)     \
    341     s ## a ## b ## c :                                  \
    342       *target = *seq ## a;                              \
    343       ++target;                                         \
    344       --length;                                         \
    345       ++seq ## a;                                       \
    346       if (length == 0) goto finish;                     \
    347       if (seq ## a c0 seq ## b) goto s ## a ## b ## c;  \
    348       if (seq ## a c1 seq ## c) goto s ## b ## a ## c;  \
    349       goto s ## b ## c ## a;
    350 
    351     _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
    352     _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
    353     _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
    354     _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
    355     _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
    356     _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );
    357 
    358 #undef _GLIBCXX_PARALLEL_MERGE_3_CASE
    359 
    360   finish:
    361     ;
    362 
    363 #if _GLIBCXX_ASSERTIONS
    364   _GLIBCXX_PARALLEL_ASSERT(
    365       ((RandomAccessIterator1)seq0 - seqs_begin[0].first) +
    366       ((RandomAccessIterator1)seq1 - seqs_begin[1].first) +
    367       ((RandomAccessIterator1)seq2 - seqs_begin[2].first)
    368       == orig_length);
    369 #endif
    370 
    371     seqs_begin[0].first = seq0;
    372     seqs_begin[1].first = seq1;
    373     seqs_begin[2].first = seq2;
    374 
    375     return target;
    376   }
    377 
    378 /**
    379  * @brief Highly efficient 4-way merging procedure.
    380  *
    381  * Merging is done with the algorithm implementation described by Peter
    382  * Sanders. Basically, the idea is to minimize the number of necessary
    383  * comparison after merging out an element.  The implementation trick
    384  * that makes this fast is that the order of the sequences is stored
    385  * in the instruction pointer (translated into goto labels in C++).
    386  *
    387  * This works well for merging up to 4 sequences.
    388  *
    389  * Note that making the merging stable does <em>not</em> come at a
    390  * performance hit.
    391  *
    392  * Whether the merging is done guarded or unguarded is selected by the
    393  * used iterator class.
    394  *
    395  * @param seqs_begin Begin iterator of iterator pair input sequence.
    396  * @param seqs_end End iterator of iterator pair input sequence.
    397  * @param target Begin iterator out output sequence.
    398  * @param comp Comparator.
    399  * @param length Maximum length to merge, less equal than the
    400  * total number of elements available.
    401  *
    402  * @return End iterator of output sequence.
    403  */
    404 template<template<typename RAI, typename C> class iterator,
    405 	 typename RandomAccessIteratorIterator,
    406 	 typename RandomAccessIterator3,
    407 	 typename _DifferenceTp,
    408 	 typename Comparator>
    409   RandomAccessIterator3
    410   multiway_merge_4_variant(RandomAccessIteratorIterator seqs_begin,
    411                            RandomAccessIteratorIterator seqs_end,
    412                            RandomAccessIterator3 target,
    413                            _DifferenceTp length, Comparator comp)
    414   {
    415     _GLIBCXX_CALL(length);
    416     typedef _DifferenceTp difference_type;
    417 
    418     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    419       ::value_type::first_type
    420       RandomAccessIterator1;
    421     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    422       value_type;
    423 
    424     iterator<RandomAccessIterator1, Comparator>
    425       seq0(seqs_begin[0].first, seqs_begin[0].second, comp),
    426       seq1(seqs_begin[1].first, seqs_begin[1].second, comp),
    427       seq2(seqs_begin[2].first, seqs_begin[2].second, comp),
    428       seq3(seqs_begin[3].first, seqs_begin[3].second, comp);
    429 
    430 #define _GLIBCXX_PARALLEL_DECISION(a,b,c,d) {                   \
    431       if (seq ## d < seq ## a) goto s ## d ## a ## b ## c;	\
    432       if (seq ## d < seq ## b) goto s ## a ## d ## b ## c;	\
    433       if (seq ## d < seq ## c) goto s ## a ## b ## d ## c;	\
    434       goto s ## a ## b ## c ## d;  }
    435 
    436     if (seq0 <= seq1)
    437       {
    438         if (seq1 <= seq2)
    439           _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
    440           else
    441             if (seq2 < seq0)
    442               _GLIBCXX_PARALLEL_DECISION(2,0,1,3)
    443               else
    444                 _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
    445                   }
    446     else
    447       {
    448         if (seq1 <= seq2)
    449           {
    450             if (seq0 <= seq2)
    451               _GLIBCXX_PARALLEL_DECISION(1,0,2,3)
    452               else
    453                 _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
    454                   }
    455         else
    456           _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
    457             }
    458 
    459 #define _GLIBCXX_PARALLEL_MERGE_4_CASE(a,b,c,d,c0,c1,c2)        \
    460     s ## a ## b ## c ## d:                                      \
    461       if (length == 0) goto finish;                             \
    462     *target = *seq ## a;                                        \
    463     ++target;                                                   \
    464     --length;                                                   \
    465     ++seq ## a;                                                 \
    466     if (seq ## a c0 seq ## b) goto s ## a ## b ## c ## d;       \
    467     if (seq ## a c1 seq ## c) goto s ## b ## a ## c ## d;       \
    468     if (seq ## a c2 seq ## d) goto s ## b ## c ## a ## d;       \
    469     goto s ## b ## c ## d ## a;
    470 
    471     _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
    472     _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
    473     _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
    474     _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
    475     _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
    476     _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
    477     _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
    478     _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
    479     _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
    480     _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
    481     _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
    482     _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
    483     _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
    484     _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
    485     _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
    486     _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
    487     _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
    488     _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
    489     _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
    490     _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
    491     _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
    492     _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
    493     _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
    494     _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );
    495 
    496 #undef _GLIBCXX_PARALLEL_MERGE_4_CASE
    497 #undef _GLIBCXX_PARALLEL_DECISION
    498 
    499   finish:
    500     ;
    501 
    502     seqs_begin[0].first = seq0;
    503     seqs_begin[1].first = seq1;
    504     seqs_begin[2].first = seq2;
    505     seqs_begin[3].first = seq3;
    506 
    507     return target;
    508   }
    509 
    510 /** @brief Multi-way merging procedure for a high branching factor,
    511  *         guarded case.
    512  *
    513  * This merging variant uses a LoserTree class as selected by <tt>LT</tt>.
    514  *
    515  * Stability is selected through the used LoserTree class <tt>LT</tt>.
    516  *
    517  * At least one non-empty sequence is required.
    518  *
    519  * @param seqs_begin Begin iterator of iterator pair input sequence.
    520  * @param seqs_end End iterator of iterator pair input sequence.
    521  * @param target Begin iterator out output sequence.
    522  * @param comp Comparator.
    523  * @param length Maximum length to merge, less equal than the
    524  * total number of elements available.
    525  *
    526  * @return End iterator of output sequence.
    527  */
    528 template<typename LT,
    529 	 typename RandomAccessIteratorIterator,
    530 	 typename RandomAccessIterator3,
    531 	 typename _DifferenceTp,
    532 	 typename Comparator>
    533   RandomAccessIterator3
    534   multiway_merge_loser_tree(RandomAccessIteratorIterator seqs_begin,
    535                             RandomAccessIteratorIterator seqs_end,
    536                             RandomAccessIterator3 target,
    537                             _DifferenceTp length, Comparator comp)
    538   {
    539     _GLIBCXX_CALL(length)
    540 
    541     typedef _DifferenceTp difference_type;
    542     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    543       ::value_type::first_type
    544       RandomAccessIterator1;
    545     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    546       value_type;
    547 
    548     int k = static_cast<int>(seqs_end - seqs_begin);
    549 
    550     LT lt(k, comp);
    551 
    552     // Default value for potentially non-default-constructible types.
    553     value_type* arbitrary_element = NULL;
    554 
    555     for (int t = 0; t < k; ++t)
    556       {
    557         if(arbitrary_element == NULL
    558             && _GLIBCXX_PARALLEL_LENGTH(seqs_begin[t]) > 0)
    559           arbitrary_element = &(*seqs_begin[t].first);
    560       }
    561 
    562     for (int t = 0; t < k; ++t)
    563       {
    564         if (seqs_begin[t].first == seqs_begin[t].second)
    565           lt.insert_start(*arbitrary_element, t, true);
    566         else
    567           lt.insert_start(*seqs_begin[t].first, t, false);
    568       }
    569 
    570     lt.init();
    571 
    572     int source;
    573 
    574     for (difference_type i = 0; i < length; ++i)
    575       {
    576         //take out
    577         source = lt.get_min_source();
    578 
    579         *(target++) = *(seqs_begin[source].first++);
    580 
    581         // Feed.
    582         if (seqs_begin[source].first == seqs_begin[source].second)
    583           lt.delete_min_insert(*arbitrary_element, true);
    584         else
    585           // Replace from same source.
    586           lt.delete_min_insert(*seqs_begin[source].first, false);
    587       }
    588 
    589     return target;
    590   }
    591 
    592 /** @brief Multi-way merging procedure for a high branching factor,
    593  *         unguarded case.
    594  *
    595  * Merging is done using the LoserTree class <tt>LT</tt>.
    596  *
    597  * Stability is selected by the used LoserTrees.
    598  *
    599  * @pre No input will run out of elements during the merge.
    600  *
    601  * @param seqs_begin Begin iterator of iterator pair input sequence.
    602  * @param seqs_end End iterator of iterator pair input sequence.
    603  * @param target Begin iterator out output sequence.
    604  * @param comp Comparator.
    605  * @param length Maximum length to merge, less equal than the
    606  * total number of elements available.
    607  *
    608  * @return End iterator of output sequence.
    609  */
    610 template<typename LT,
    611     typename RandomAccessIteratorIterator,
    612     typename RandomAccessIterator3,
    613     typename _DifferenceTp, typename Comparator>
    614   RandomAccessIterator3
    615   multiway_merge_loser_tree_unguarded(
    616     RandomAccessIteratorIterator seqs_begin,
    617     RandomAccessIteratorIterator seqs_end,
    618     RandomAccessIterator3 target,
    619     const typename std::iterator_traits<typename std::iterator_traits<
    620       RandomAccessIteratorIterator>::value_type::first_type>::value_type&
    621         sentinel,
    622     _DifferenceTp length,
    623     Comparator comp)
    624   {
    625     _GLIBCXX_CALL(length)
    626     typedef _DifferenceTp difference_type;
    627 
    628     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    629       ::value_type::first_type
    630       RandomAccessIterator1;
    631     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    632       value_type;
    633 
    634     int k = seqs_end - seqs_begin;
    635 
    636     LT lt(k, sentinel, comp);
    637 
    638     for (int t = 0; t < k; ++t)
    639       {
    640 #if _GLIBCXX_ASSERTIONS
    641         _GLIBCXX_PARALLEL_ASSERT(seqs_begin[t].first != seqs_begin[t].second);
    642 #endif
    643         lt.insert_start(*seqs_begin[t].first, t, false);
    644       }
    645 
    646     lt.init();
    647 
    648     int source;
    649 
    650 #if _GLIBCXX_ASSERTIONS
    651     difference_type i = 0;
    652 #endif
    653 
    654     RandomAccessIterator3 target_end = target + length;
    655     while (target < target_end)
    656       {
    657         // Take out.
    658         source = lt.get_min_source();
    659 
    660 #if _GLIBCXX_ASSERTIONS
    661         _GLIBCXX_PARALLEL_ASSERT(0 <= source && source < k);
    662         _GLIBCXX_PARALLEL_ASSERT(i == 0
    663             || !comp(*(seqs_begin[source].first), *(target - 1)));
    664 #endif
    665 
    666         // Feed.
    667         *(target++) = *(seqs_begin[source].first++);
    668 
    669 #if _GLIBCXX_ASSERTIONS
    670         ++i;
    671 #endif
    672         // Replace from same source.
    673         lt.delete_min_insert(*seqs_begin[source].first, false);
    674       }
    675 
    676     return target;
    677   }
    678 
    679 
    680 /** @brief Multi-way merging procedure for a high branching factor,
    681  *         requiring sentinels to exist.
    682  *
    683  * @param stable The value must the same as for the used LoserTrees.
    684  * @param UnguardedLoserTree Loser Tree variant to use for the unguarded
    685  *   merging.
    686  * @param GuardedLoserTree Loser Tree variant to use for the guarded
    687  *   merging.
    688  *
    689  * @param seqs_begin Begin iterator of iterator pair input sequence.
    690  * @param seqs_end End iterator of iterator pair input sequence.
    691  * @param target Begin iterator out output sequence.
    692  * @param comp Comparator.
    693  * @param length Maximum length to merge, less equal than the
    694  * total number of elements available.
    695  *
    696  * @return End iterator of output sequence.
    697  */
    698 template<
    699     typename UnguardedLoserTree,
    700     typename RandomAccessIteratorIterator,
    701     typename RandomAccessIterator3,
    702     typename _DifferenceTp,
    703     typename Comparator>
    704   RandomAccessIterator3
    705   multiway_merge_loser_tree_sentinel(
    706     RandomAccessIteratorIterator seqs_begin,
    707     RandomAccessIteratorIterator seqs_end,
    708     RandomAccessIterator3 target,
    709     const typename std::iterator_traits<typename std::iterator_traits<
    710       RandomAccessIteratorIterator>::value_type::first_type>::value_type&
    711         sentinel,
    712     _DifferenceTp length,
    713     Comparator comp)
    714   {
    715     _GLIBCXX_CALL(length)
    716 
    717     typedef _DifferenceTp difference_type;
    718     typedef std::iterator_traits<RandomAccessIteratorIterator> traits_type;
    719     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    720       ::value_type::first_type
    721       RandomAccessIterator1;
    722     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    723       value_type;
    724 
    725     RandomAccessIterator3 target_end;
    726 
    727     for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
    728       // Move the sequends end behind the sentinel spots.  This has the
    729       // effect that the sentinel appears to be within the sequence. Then,
    730       // we can use the unguarded variant if we merge out as many
    731       // non-sentinel elements as we have.
    732       ++((*s).second);
    733 
    734     target_end = multiway_merge_loser_tree_unguarded
    735         <UnguardedLoserTree>
    736       (seqs_begin, seqs_end, target, sentinel, length, comp);
    737 
    738 #if _GLIBCXX_ASSERTIONS
    739     _GLIBCXX_PARALLEL_ASSERT(target_end == target + length);
    740     _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target_end, comp));
    741 #endif
    742 
    743     // Restore the sequence ends so the sentinels are not contained in the
    744     // sequence any more (see comment in loop above).
    745     for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
    746       --((*s).second);
    747 
    748     return target_end;
    749   }
    750 
    751 /**
    752  * @brief Traits for determining whether the loser tree should
    753  *   use pointers or copies.
    754  *
    755  * The field "use_pointer" is used to determine whether to use pointers in
    756  * the loser trees or whether to copy the values into the loser tree.
    757  *
    758  * The default behavior is to use pointers if the data type is 4 times as
    759  * big as the pointer to it.
    760  *
    761  * Specialize for your data type to customize the behavior.
    762  *
    763  * Example:
    764  *
    765  *   template<>
    766  *   struct loser_tree_traits<int>
    767  *   { static const bool use_pointer = false; };
    768  *
    769  *   template<>
    770  *   struct loser_tree_traits<heavyweight_type>
    771  *   { static const bool use_pointer = true; };
    772  *
    773  * @param T type to give the loser tree traits for.
    774  */
    775 template <typename T>
    776 struct loser_tree_traits
    777 {
    778   /**
    779    * @brief True iff to use pointers instead of values in loser trees.
    780    *
    781    * The default behavior is to use pointers if the data type is four
    782    * times as big as the pointer to it.
    783    */
    784   static const bool use_pointer = (sizeof(T) > 4 * sizeof(T*));
    785 };
    786 
    787 /**
    788  * @brief Switch for 3-way merging with sentinels turned off.
    789  *
    790  * Note that 3-way merging is always stable!
    791  */
    792 template<
    793   bool sentinels /*default == false*/,
    794   typename RandomAccessIteratorIterator,
    795   typename RandomAccessIterator3,
    796   typename _DifferenceTp,
    797   typename Comparator>
    798 struct multiway_merge_3_variant_sentinel_switch
    799 {
    800   RandomAccessIterator3 operator()(
    801       RandomAccessIteratorIterator seqs_begin,
    802       RandomAccessIteratorIterator seqs_end,
    803       RandomAccessIterator3 target,
    804       _DifferenceTp length, Comparator comp)
    805   {
    806     return multiway_merge_3_variant<guarded_iterator>(
    807         seqs_begin, seqs_end, target, length, comp);
    808   }
    809 };
    810 
    811 /**
    812  * @brief Switch for 3-way merging with sentinels turned on.
    813  *
    814  * Note that 3-way merging is always stable!
    815  */
    816 template<
    817   typename RandomAccessIteratorIterator,
    818   typename RandomAccessIterator3,
    819   typename _DifferenceTp,
    820   typename Comparator>
    821 struct multiway_merge_3_variant_sentinel_switch
    822     <true, RandomAccessIteratorIterator, RandomAccessIterator3,
    823      _DifferenceTp, Comparator>
    824 {
    825   RandomAccessIterator3 operator()(
    826       RandomAccessIteratorIterator seqs_begin,
    827       RandomAccessIteratorIterator seqs_end,
    828       RandomAccessIterator3 target,
    829       _DifferenceTp length, Comparator comp)
    830   {
    831     return multiway_merge_3_variant<unguarded_iterator>(
    832         seqs_begin, seqs_end, target, length, comp);
    833   }
    834 };
    835 
    836 /**
    837  * @brief Switch for 4-way merging with sentinels turned off.
    838  *
    839  * Note that 4-way merging is always stable!
    840  */
    841 template<
    842   bool sentinels /*default == false*/,
    843   typename RandomAccessIteratorIterator,
    844   typename RandomAccessIterator3,
    845   typename _DifferenceTp,
    846   typename Comparator>
    847 struct multiway_merge_4_variant_sentinel_switch
    848 {
    849   RandomAccessIterator3 operator()(
    850       RandomAccessIteratorIterator seqs_begin,
    851       RandomAccessIteratorIterator seqs_end,
    852       RandomAccessIterator3 target,
    853       _DifferenceTp length, Comparator comp)
    854   {
    855     return multiway_merge_4_variant<guarded_iterator>(
    856         seqs_begin, seqs_end, target, length, comp);
    857   }
    858 };
    859 
    860 /**
    861  * @brief Switch for 4-way merging with sentinels turned on.
    862  *
    863  * Note that 4-way merging is always stable!
    864  */
    865 template<
    866   typename RandomAccessIteratorIterator,
    867   typename RandomAccessIterator3,
    868   typename _DifferenceTp,
    869   typename Comparator>
    870 struct multiway_merge_4_variant_sentinel_switch
    871     <true, RandomAccessIteratorIterator, RandomAccessIterator3,
    872      _DifferenceTp, Comparator>
    873 {
    874   RandomAccessIterator3 operator()(
    875       RandomAccessIteratorIterator seqs_begin,
    876       RandomAccessIteratorIterator seqs_end,
    877       RandomAccessIterator3 target,
    878       _DifferenceTp length, Comparator comp)
    879   {
    880     return multiway_merge_4_variant<unguarded_iterator>(
    881         seqs_begin, seqs_end, target, length, comp);
    882   }
    883 };
    884 
    885 /**
    886  * @brief Switch for k-way merging with sentinels turned on.
    887  */
    888 template<
    889   bool sentinels,
    890   bool stable,
    891   typename RandomAccessIteratorIterator,
    892   typename RandomAccessIterator3,
    893   typename _DifferenceTp,
    894   typename Comparator>
    895 struct multiway_merge_k_variant_sentinel_switch
    896 {
    897   RandomAccessIterator3 operator()(
    898       RandomAccessIteratorIterator seqs_begin,
    899       RandomAccessIteratorIterator seqs_end,
    900       RandomAccessIterator3 target,
    901       const typename std::iterator_traits<typename std::iterator_traits<
    902         RandomAccessIteratorIterator>::value_type::first_type>::value_type&
    903           sentinel,
    904       _DifferenceTp length, Comparator comp)
    905   {
    906     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    907       ::value_type::first_type
    908       RandomAccessIterator1;
    909     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    910       value_type;
    911 
    912     return multiway_merge_loser_tree_sentinel<
    913         typename __gnu_cxx::__conditional_type<
    914             loser_tree_traits<value_type>::use_pointer
    915           , LoserTreePointerUnguarded<stable, value_type, Comparator>
    916           , LoserTreeUnguarded<stable, value_type, Comparator>
    917         >::__type>(seqs_begin, seqs_end, target, sentinel, length, comp);
    918   }
    919 };
    920 
    921 /**
    922  * @brief Switch for k-way merging with sentinels turned off.
    923  */
    924 template<
    925   bool stable,
    926   typename RandomAccessIteratorIterator,
    927   typename RandomAccessIterator3,
    928   typename _DifferenceTp,
    929   typename Comparator>
    930 struct multiway_merge_k_variant_sentinel_switch
    931     <false, stable, RandomAccessIteratorIterator, RandomAccessIterator3,
    932      _DifferenceTp, Comparator>
    933 {
    934   RandomAccessIterator3 operator()(
    935       RandomAccessIteratorIterator seqs_begin,
    936       RandomAccessIteratorIterator seqs_end,
    937       RandomAccessIterator3 target,
    938       const typename std::iterator_traits<typename std::iterator_traits<
    939         RandomAccessIteratorIterator>::value_type::first_type>::value_type&
    940           sentinel,
    941       _DifferenceTp length, Comparator comp)
    942   {
    943     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    944       ::value_type::first_type
    945       RandomAccessIterator1;
    946     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    947       value_type;
    948 
    949     return multiway_merge_loser_tree<
    950         typename __gnu_cxx::__conditional_type<
    951             loser_tree_traits<value_type>::use_pointer
    952           , LoserTreePointer<stable, value_type, Comparator>
    953           , LoserTree<stable, value_type, Comparator>
    954         >::__type >(seqs_begin, seqs_end, target, length, comp);
    955   }
    956 };
    957 
    958 /** @brief Sequential multi-way merging switch.
    959  *
    960  *  The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and
    961  *  runtime settings.
    962  *  @param seqs_begin Begin iterator of iterator pair input sequence.
    963  *  @param seqs_end End iterator of iterator pair input sequence.
    964  *  @param target Begin iterator out output sequence.
    965  *  @param comp Comparator.
    966  *  @param length Maximum length to merge, possibly larger than the
    967  *  number of elements available.
    968  *  @param stable Stable merging incurs a performance penalty.
    969  *  @param sentinel The sequences have a sentinel element.
    970  *  @return End iterator of output sequence. */
    971 template<
    972     bool stable,
    973     bool sentinels,
    974     typename RandomAccessIteratorIterator,
    975     typename RandomAccessIterator3,
    976     typename _DifferenceTp,
    977     typename Comparator>
    978   RandomAccessIterator3
    979   sequential_multiway_merge(
    980     RandomAccessIteratorIterator seqs_begin,
    981     RandomAccessIteratorIterator seqs_end,
    982     RandomAccessIterator3 target,
    983     const typename std::iterator_traits<typename std::iterator_traits<
    984       RandomAccessIteratorIterator>::value_type::first_type>::value_type&
    985         sentinel,
    986     _DifferenceTp length, Comparator comp)
    987   {
    988     _GLIBCXX_CALL(length)
    989 
    990     typedef _DifferenceTp difference_type;
    991     typedef typename std::iterator_traits<RandomAccessIteratorIterator>
    992       ::value_type::first_type
    993       RandomAccessIterator1;
    994     typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
    995       value_type;
    996 
    997 #if _GLIBCXX_ASSERTIONS
    998     for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
    999       {
   1000         _GLIBCXX_PARALLEL_ASSERT(is_sorted((*s).first, (*s).second, comp));
   1001       }
   1002 #endif
   1003 
   1004     _DifferenceTp total_length = 0;
   1005     for (RandomAccessIteratorIterator s = seqs_begin; s != seqs_end; ++s)
   1006       total_length += _GLIBCXX_PARALLEL_LENGTH(*s);
   1007 
   1008     length = std::min<_DifferenceTp>(length, total_length);
   1009 
   1010     if(length == 0)
   1011       return target;
   1012 
   1013     RandomAccessIterator3 return_target = target;
   1014     int k = static_cast<int>(seqs_end - seqs_begin);
   1015 
   1016     switch (k)
   1017       {
   1018       case 0:
   1019         break;
   1020       case 1:
   1021         return_target = std::copy(seqs_begin[0].first,
   1022                                   seqs_begin[0].first + length,
   1023                                   target);
   1024         seqs_begin[0].first += length;
   1025         break;
   1026       case 2:
   1027         return_target = merge_advance(seqs_begin[0].first,
   1028                                       seqs_begin[0].second,
   1029                                       seqs_begin[1].first,
   1030                                       seqs_begin[1].second,
   1031                                       target, length, comp);
   1032         break;
   1033       case 3:
   1034         return_target = multiway_merge_3_variant_sentinel_switch<
   1035             sentinels
   1036           , RandomAccessIteratorIterator
   1037           , RandomAccessIterator3
   1038           , _DifferenceTp
   1039           , Comparator>()(seqs_begin, seqs_end, target, length, comp);
   1040         break;
   1041       case 4:
   1042         return_target = multiway_merge_4_variant_sentinel_switch<
   1043             sentinels
   1044           , RandomAccessIteratorIterator
   1045           , RandomAccessIterator3
   1046           , _DifferenceTp
   1047           , Comparator>()(seqs_begin, seqs_end, target, length, comp);
   1048         break;
   1049       default:
   1050           return_target = multiway_merge_k_variant_sentinel_switch<
   1051               sentinels
   1052             , stable
   1053             , RandomAccessIteratorIterator
   1054             , RandomAccessIterator3
   1055             , _DifferenceTp
   1056             , Comparator>()(seqs_begin, seqs_end, target, sentinel, length, comp);
   1057           break;
   1058       }
   1059 #if _GLIBCXX_ASSERTIONS
   1060     _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp));
   1061 #endif
   1062 
   1063     return return_target;
   1064   }
   1065 
   1066 /**
   1067  * @brief Stable sorting functor.
   1068  *
   1069  * Used to reduce code instanciation in multiway_merge_sampling_splitting.
   1070  */
   1071 template<bool stable, class RandomAccessIterator, class StrictWeakOrdering>
   1072 struct sampling_sorter
   1073 {
   1074   void operator()(RandomAccessIterator first, RandomAccessIterator last,
   1075                   StrictWeakOrdering comp)
   1076   { __gnu_sequential::stable_sort(first, last, comp); }
   1077 };
   1078 
   1079 /**
   1080  * @brief Non-stable sorting functor.
   1081  *
   1082  * Used to reduce code instantiation in multiway_merge_sampling_splitting.
   1083  */
   1084 template<class RandomAccessIterator, class StrictWeakOrdering>
   1085 struct sampling_sorter<false, RandomAccessIterator, StrictWeakOrdering>
   1086 {
   1087   void operator()(RandomAccessIterator first, RandomAccessIterator last,
   1088                   StrictWeakOrdering comp)
   1089   { __gnu_sequential::sort(first, last, comp); }
   1090 };
   1091 
   1092 /**
   1093  * @brief Sampling based splitting for parallel multiway-merge routine.
   1094  */
   1095 template<
   1096     bool stable
   1097   , typename RandomAccessIteratorIterator
   1098   , typename Comparator
   1099   , typename difference_type>
   1100 void multiway_merge_sampling_splitting(
   1101     RandomAccessIteratorIterator seqs_begin,
   1102     RandomAccessIteratorIterator seqs_end,
   1103     difference_type length, difference_type total_length, Comparator comp,
   1104     std::vector<std::pair<difference_type, difference_type> > *pieces)
   1105 {
   1106   typedef typename std::iterator_traits<RandomAccessIteratorIterator>
   1107     ::value_type::first_type
   1108     RandomAccessIterator1;
   1109   typedef typename std::iterator_traits<RandomAccessIterator1>::value_type
   1110     value_type;
   1111 
   1112   // k sequences.
   1113   int k = static_cast<int>(seqs_end - seqs_begin);
   1114 
   1115   int num_threads = omp_get_num_threads();
   1116 
   1117   difference_type num_samples =
   1118       __gnu_parallel::_Settings::get().merge_oversampling * num_threads;
   1119 
   1120   value_type* samples = static_cast<value_type*>(
   1121     ::operator new(sizeof(value_type) * k * num_samples));
   1122   // Sample.
   1123   for (int s = 0; s < k; ++s)
   1124     for (difference_type i = 0; i < num_samples; ++i)
   1125       {
   1126         difference_type sample_index =
   1127             static_cast<difference_type>(
   1128                 _GLIBCXX_PARALLEL_LENGTH(seqs_begin[s])
   1129                     * (double(i + 1) / (num_samples + 1))
   1130                     * (double(length) / total_length));
   1131         new(&(samples[s * num_samples + i]))
   1132             value_type(seqs_begin[s].first[sample_index]);
   1133       }
   1134 
   1135   // Sort stable or non-stable, depending on value of template parameter
   1136   // "stable".
   1137   sampling_sorter<stable, value_type*, Comparator>()(
   1138       samples, samples + (num_samples * k), comp);
   1139 
   1140   for (int slab = 0; slab < num_threads; ++slab)
   1141     // For each slab / processor.
   1142     for (int seq = 0; seq < k; ++seq)
   1143       {
   1144         // For each sequence.
   1145         if (slab > 0)
   1146           pieces[slab][seq].first =
   1147               std::upper_bound(
   1148                 seqs_begin[seq].first,
   1149                 seqs_begin[seq].second,
   1150                 samples[num_samples * k * slab / num_threads],
   1151                   comp)
   1152               - seqs_begin[seq].first;
   1153         else
   1154           // Absolute beginning.
   1155           pieces[slab][seq].first = 0;
   1156         if ((slab + 1) < num_threads)
   1157           pieces[slab][seq].second =
   1158               std::upper_bound(
   1159                   seqs_begin[seq].first,
   1160                   seqs_begin[seq].second,
   1161                   samples[num_samples * k * (slab + 1) /
   1162                       num_threads], comp)
   1163               - seqs_begin[seq].first;
   1164         else
   1165             // Absolute end.
   1166           pieces[slab][seq].second = _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
   1167       }
   1168     ::operator delete(samples);
   1169 }
   1170 
   1171 /**
   1172  * @brief Exact splitting for parallel multiway-merge routine.
   1173  *
   1174  * None of the passed sequences may be empty.
   1175  */
   1176 template<
   1177     bool stable
   1178   , typename RandomAccessIteratorIterator
   1179   , typename Comparator
   1180   , typename difference_type>
   1181 void multiway_merge_exact_splitting(
   1182     RandomAccessIteratorIterator seqs_begin,
   1183     RandomAccessIteratorIterator seqs_end,
   1184     difference_type length, difference_type total_length, Comparator comp,
   1185     std::vector<std::pair<difference_type, difference_type> > *pieces)
   1186 {
   1187   typedef typename std::iterator_traits<RandomAccessIteratorIterator>
   1188     ::value_type::first_type
   1189     RandomAccessIterator1;
   1190 
   1191   const bool tight = (total_length == length);
   1192 
   1193   // k sequences.
   1194   const int k = static_cast<int>(seqs_end - seqs_begin);
   1195 
   1196   const int num_threads = omp_get_num_threads();
   1197 
   1198   // (Settings::multiway_merge_splitting == __gnu_parallel::_Settings::EXACT).
   1199   std::vector<RandomAccessIterator1>* offsets =
   1200       new std::vector<RandomAccessIterator1>[num_threads];
   1201   std::vector<
   1202       std::pair<RandomAccessIterator1, RandomAccessIterator1>
   1203       > se(k);
   1204 
   1205   copy(seqs_begin, seqs_end, se.begin());
   1206 
   1207   difference_type* borders =
   1208       new difference_type[num_threads + 1];
   1209   equally_split(length, num_threads, borders);
   1210 
   1211   for (int s = 0; s < (num_threads - 1); ++s)
   1212     {
   1213       offsets[s].resize(k);
   1214       multiseq_partition(
   1215           se.begin(), se.end(), borders[s + 1],
   1216           offsets[s].begin(), comp);
   1217 
   1218       // Last one also needed and available.
   1219       if (!tight)
   1220         {
   1221           offsets[num_threads - 1].resize(k);
   1222           multiseq_partition(se.begin(), se.end(),
   1223                 difference_type(length),
   1224                 offsets[num_threads - 1].begin(),  comp);
   1225         }
   1226     }
   1227   delete[] borders;
   1228 
   1229   for (int slab = 0; slab < num_threads; ++slab)
   1230     {
   1231       // For each slab / processor.
   1232       for (int seq = 0; seq < k; ++seq)
   1233         {
   1234           // For each sequence.
   1235           if (slab == 0)
   1236             {
   1237               // Absolute beginning.
   1238               pieces[slab][seq].first = 0;
   1239             }
   1240           else
   1241             pieces[slab][seq].first =
   1242                 pieces[slab - 1][seq].second;
   1243           if (!tight || slab < (num_threads - 1))
   1244             pieces[slab][seq].second =
   1245                 offsets[slab][seq] - seqs_begin[seq].first;
   1246           else
   1247             {
   1248               // slab == num_threads - 1
   1249               pieces[slab][seq].second =
   1250                   _GLIBCXX_PARALLEL_LENGTH(seqs_begin[seq]);
   1251             }
   1252         }
   1253     }
   1254   delete[] offsets;
   1255 }
   1256 
   1257 /** @brief Parallel multi-way merge routine.
   1258  *
   1259  * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor
   1260  * and runtime settings.
   1261  *
   1262  * Must not be called if the number of sequences is 1.
   1263  *
   1264  * @param Splitter functor to split input (either exact or sampling based)
   1265  *
   1266  * @param seqs_begin Begin iterator of iterator pair input sequence.
   1267  * @param seqs_end End iterator of iterator pair input sequence.
   1268  * @param target Begin iterator out output sequence.
   1269  * @param comp Comparator.
   1270  * @param length Maximum length to merge, possibly larger than the
   1271  * number of elements available.
   1272  * @param stable Stable merging incurs a performance penalty.
   1273  * @param sentinel Ignored.
   1274  * @return End iterator of output sequence.
   1275  */
   1276 template<
   1277     bool stable,
   1278     bool sentinels,
   1279     typename RandomAccessIteratorIterator,
   1280     typename RandomAccessIterator3,
   1281     typename _DifferenceTp,
   1282     typename Splitter,
   1283     typename Comparator
   1284     >
   1285   RandomAccessIterator3
   1286   parallel_multiway_merge(RandomAccessIteratorIterator seqs_begin,
   1287                           RandomAccessIteratorIterator seqs_end,
   1288                           RandomAccessIterator3 target,
   1289                           Splitter splitter,
   1290                           _DifferenceTp length,
   1291                           Comparator comp,
   1292                           thread_index_t num_threads)
   1293     {
   1294 #if _GLIBCXX_ASSERTIONS
   1295       _GLIBCXX_PARALLEL_ASSERT(seqs_end - seqs_begin > 1);
   1296 #endif
   1297 
   1298       _GLIBCXX_CALL(length)
   1299 
   1300       typedef _DifferenceTp difference_type;
   1301       typedef typename std::iterator_traits<RandomAccessIteratorIterator>
   1302         ::value_type::first_type
   1303         RandomAccessIterator1;
   1304       typedef typename
   1305         std::iterator_traits<RandomAccessIterator1>::value_type value_type;
   1306 
   1307       // Leave only non-empty sequences.
   1308       typedef std::pair<RandomAccessIterator1, RandomAccessIterator1> seq_type;
   1309       seq_type* ne_seqs = new seq_type[seqs_end - seqs_begin];
   1310       int k = 0;
   1311       difference_type total_length = 0;
   1312       for (RandomAccessIteratorIterator raii = seqs_begin;
   1313            raii != seqs_end; ++raii)
   1314         {
   1315           _DifferenceTp seq_length = _GLIBCXX_PARALLEL_LENGTH(*raii);
   1316           if(seq_length > 0)
   1317             {
   1318               total_length += seq_length;
   1319               ne_seqs[k++] = *raii;
   1320             }
   1321         }
   1322 
   1323       _GLIBCXX_CALL(total_length)
   1324 
   1325       length = std::min<_DifferenceTp>(length, total_length);
   1326 
   1327       if (total_length == 0 || k == 0)
   1328       {
   1329         delete[] ne_seqs;
   1330         return target;
   1331       }
   1332 
   1333       std::vector<std::pair<difference_type, difference_type> >* pieces;
   1334 
   1335       num_threads = static_cast<thread_index_t>
   1336         (std::min<difference_type>(num_threads, total_length));
   1337 
   1338 #     pragma omp parallel num_threads (num_threads)
   1339         {
   1340 #         pragma omp single
   1341             {
   1342               num_threads = omp_get_num_threads();
   1343               // Thread t will have to merge pieces[iam][0..k - 1]
   1344               pieces = new std::vector<
   1345                   std::pair<difference_type, difference_type> >[num_threads];
   1346               for (int s = 0; s < num_threads; ++s)
   1347                 pieces[s].resize(k);
   1348 
   1349               difference_type num_samples =
   1350                   __gnu_parallel::_Settings::get().merge_oversampling *
   1351                     num_threads;
   1352 
   1353               splitter(ne_seqs, ne_seqs + k, length, total_length,
   1354                        comp, pieces);
   1355             } //single
   1356 
   1357           thread_index_t iam = omp_get_thread_num();
   1358 
   1359           difference_type target_position = 0;
   1360 
   1361           for (int c = 0; c < k; ++c)
   1362             target_position += pieces[iam][c].first;
   1363 
   1364           seq_type* chunks = new seq_type[k];
   1365 
   1366           for (int s = 0; s < k; ++s)
   1367             {
   1368               chunks[s] = std::make_pair(
   1369                 ne_seqs[s].first + pieces[iam][s].first,
   1370                 ne_seqs[s].first + pieces[iam][s].second);
   1371             }
   1372 
   1373           if(length > target_position)
   1374             sequential_multiway_merge<stable, sentinels>(
   1375               chunks, chunks + k, target + target_position,
   1376                *(seqs_begin->second), length - target_position, comp);
   1377 
   1378           delete[] chunks;
   1379         } // parallel
   1380 
   1381 #if _GLIBCXX_ASSERTIONS
   1382       _GLIBCXX_PARALLEL_ASSERT(is_sorted(target, target + length, comp));
   1383 #endif
   1384 
   1385       k = 0;
   1386       // Update ends of sequences.
   1387       for (RandomAccessIteratorIterator raii = seqs_begin;
   1388            raii != seqs_end; ++raii)
   1389         {
   1390           _DifferenceTp length = _GLIBCXX_PARALLEL_LENGTH(*raii);
   1391           if(length > 0)
   1392             (*raii).first += pieces[num_threads - 1][k++].second;
   1393         }
   1394 
   1395       delete[] pieces;
   1396       delete[] ne_seqs;
   1397 
   1398       return target + length;
   1399     }
   1400 
   1401 /**
   1402  * @brief Multiway Merge Frontend.
   1403  *
   1404  * Merge the sequences specified by seqs_begin and seqs_end into
   1405  * target.  seqs_begin and seqs_end must point to a sequence of
   1406  * pairs.  These pairs must contain an iterator to the beginning
   1407  * of a sequence in their first entry and an iterator the end of
   1408  * the same sequence in their second entry.
   1409  *
   1410  * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
   1411  * that breaks ties by sequence number but is slower.
   1412  *
   1413  * The first entries of the pairs (i.e. the begin iterators) will be moved
   1414  * forward.
   1415  *
   1416  * The output sequence has to provide enough space for all elements
   1417  * that are written to it.
   1418  *
   1419  * This function will merge the input sequences:
   1420  *
   1421  * - not stable
   1422  * - parallel, depending on the input size and Settings
   1423  * - using sampling for splitting
   1424  * - not using sentinels
   1425  *
   1426  * Example:
   1427  *
   1428  * <pre>
   1429  *   int sequences[10][10];
   1430  *   for (int i = 0; i < 10; ++i)
   1431  *     for (int j = 0; i < 10; ++j)
   1432  *       sequences[i][j] = j;
   1433  *
   1434  *   int out[33];
   1435  *   std::vector<std::pair<int*> > seqs;
   1436  *   for (int i = 0; i < 10; ++i)
   1437  *     { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) }
   1438  *
   1439  *   multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33);
   1440  * </pre>
   1441  *
   1442  * @see stable_multiway_merge
   1443  *
   1444  * @pre All input sequences must be sorted.
   1445  * @pre Target must provide enough space to merge out length elements or
   1446  *    the number of elements in all sequences, whichever is smaller.
   1447  *
   1448  * @post [target, return value) contains merged elements from the
   1449  *    input sequences.
   1450  * @post return value - target = min(length, number of elements in all
   1451  *    sequences).
   1452  *
   1453  * @param RandomAccessIteratorPairIterator iterator over sequence
   1454  *    of pairs of iterators
   1455  * @param RandomAccessIteratorOut iterator over target sequence
   1456  * @param _DifferenceTp difference type for the sequence
   1457  * @param Comparator strict weak ordering type to compare elements
   1458  *    in sequences
   1459  *
   1460  * @param seqs_begin  begin of sequence sequence
   1461  * @param seqs_end    end of sequence sequence
   1462  * @param target      target sequence to merge to.
   1463  * @param comp        strict weak ordering to use for element comparison.
   1464  * @param length Maximum length to merge, possibly larger than the
   1465  * number of elements available.
   1466  *
   1467  * @return end iterator of output sequence
   1468  */
   1469 // multiway_merge
   1470 // public interface
   1471 template<
   1472     typename RandomAccessIteratorPairIterator
   1473   , typename RandomAccessIteratorOut
   1474   , typename _DifferenceTp
   1475   , typename Comparator>
   1476 RandomAccessIteratorOut
   1477 multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1478     , RandomAccessIteratorPairIterator seqs_end
   1479     , RandomAccessIteratorOut target
   1480     , _DifferenceTp length, Comparator comp
   1481     , __gnu_parallel::sequential_tag)
   1482 {
   1483   typedef _DifferenceTp difference_type;
   1484   _GLIBCXX_CALL(seqs_end - seqs_begin)
   1485 
   1486   // catch special case: no sequences
   1487   if (seqs_begin == seqs_end)
   1488     return target;
   1489 
   1490   // Execute multiway merge *sequentially*.
   1491   return sequential_multiway_merge
   1492     </* stable = */ false, /* sentinels = */ false>
   1493       (seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
   1494 }
   1495 
   1496 // public interface
   1497 template<
   1498     typename RandomAccessIteratorPairIterator
   1499   , typename RandomAccessIteratorOut
   1500   , typename _DifferenceTp
   1501   , typename Comparator>
   1502 RandomAccessIteratorOut
   1503 multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1504     , RandomAccessIteratorPairIterator seqs_end
   1505     , RandomAccessIteratorOut target
   1506     , _DifferenceTp length, Comparator comp
   1507     , __gnu_parallel::exact_tag tag)
   1508 {
   1509     typedef _DifferenceTp difference_type;
   1510     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1511 
   1512     // catch special case: no sequences
   1513     if (seqs_begin == seqs_end)
   1514       return target;
   1515 
   1516     // Execute merge; maybe parallel, depending on the number of merged
   1517     // elements and the number of sequences and global thresholds in
   1518     // Settings.
   1519     if ((seqs_end - seqs_begin > 1) &&
   1520           _GLIBCXX_PARALLEL_CONDITION(
   1521           ((seqs_end - seqs_begin) >=
   1522              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   1523           && ((sequence_index_t)length >=
   1524             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   1525       return parallel_multiway_merge
   1526                     </* stable = */ false, /* sentinels = */ false>(
   1527           seqs_begin, seqs_end, target,
   1528           multiway_merge_exact_splitting</* stable = */ false,
   1529             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   1530               ::value_type*, Comparator, _DifferenceTp>,
   1531           static_cast<difference_type>(length), comp, tag.get_num_threads());
   1532     else
   1533       return sequential_multiway_merge
   1534                       </* stable = */ false, /* sentinels = */ false>(
   1535           seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
   1536 }
   1537 
   1538 // public interface
   1539 template<
   1540     typename RandomAccessIteratorPairIterator
   1541   , typename RandomAccessIteratorOut
   1542   , typename _DifferenceTp
   1543   , typename Comparator>
   1544 RandomAccessIteratorOut
   1545 multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1546     , RandomAccessIteratorPairIterator seqs_end
   1547     , RandomAccessIteratorOut target
   1548     , _DifferenceTp length, Comparator comp
   1549     , __gnu_parallel::sampling_tag tag)
   1550 {
   1551     typedef _DifferenceTp difference_type;
   1552     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1553 
   1554     // catch special case: no sequences
   1555     if (seqs_begin == seqs_end)
   1556       return target;
   1557 
   1558     // Execute merge; maybe parallel, depending on the number of merged
   1559     // elements and the number of sequences and global thresholds in
   1560     // Settings.
   1561     if ((seqs_end - seqs_begin > 1) &&
   1562           _GLIBCXX_PARALLEL_CONDITION(
   1563           ((seqs_end - seqs_begin) >=
   1564              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   1565           && ((sequence_index_t)length >=
   1566             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   1567       return parallel_multiway_merge
   1568                     </* stable = */ false, /* sentinels = */ false>(
   1569           seqs_begin, seqs_end,
   1570           target,
   1571           multiway_merge_exact_splitting</* stable = */ false,
   1572             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   1573               ::value_type*, Comparator, _DifferenceTp>,
   1574           static_cast<difference_type>(length), comp, tag.get_num_threads());
   1575     else
   1576       return sequential_multiway_merge
   1577                       </* stable = */ false, /* sentinels = */ false>(
   1578           seqs_begin, seqs_end,
   1579           target, *(seqs_begin->second), length, comp);
   1580 }
   1581 
   1582 // public interface
   1583 template<
   1584     typename RandomAccessIteratorPairIterator
   1585   , typename RandomAccessIteratorOut
   1586   , typename _DifferenceTp
   1587   , typename Comparator>
   1588 RandomAccessIteratorOut
   1589 multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1590     , RandomAccessIteratorPairIterator seqs_end
   1591     , RandomAccessIteratorOut target
   1592     , _DifferenceTp length, Comparator comp
   1593     , parallel_tag tag = parallel_tag(0))
   1594 {
   1595   return multiway_merge(seqs_begin, seqs_end, target, length, comp,
   1596                          exact_tag(tag.get_num_threads()));
   1597 }
   1598 
   1599 // public interface
   1600 template<
   1601     typename RandomAccessIteratorPairIterator
   1602   , typename RandomAccessIteratorOut
   1603   , typename _DifferenceTp
   1604   , typename Comparator>
   1605 RandomAccessIteratorOut
   1606 multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1607     , RandomAccessIteratorPairIterator seqs_end
   1608     , RandomAccessIteratorOut target
   1609     , _DifferenceTp length, Comparator comp
   1610     , default_parallel_tag tag)
   1611 {
   1612   return multiway_merge(seqs_begin, seqs_end, target, length, comp,
   1613                          exact_tag(tag.get_num_threads()));
   1614 }
   1615 
   1616 // stable_multiway_merge
   1617 // public interface
   1618 template<
   1619     typename RandomAccessIteratorPairIterator
   1620   , typename RandomAccessIteratorOut
   1621   , typename _DifferenceTp
   1622   , typename Comparator>
   1623 RandomAccessIteratorOut
   1624 stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1625     , RandomAccessIteratorPairIterator seqs_end
   1626     , RandomAccessIteratorOut target
   1627     , _DifferenceTp length, Comparator comp
   1628     , __gnu_parallel::sequential_tag)
   1629 {
   1630     typedef _DifferenceTp difference_type;
   1631     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1632 
   1633     // catch special case: no sequences
   1634     if (seqs_begin == seqs_end)
   1635       return target;
   1636 
   1637     // Execute multiway merge *sequentially*.
   1638     return sequential_multiway_merge
   1639       </* stable = */ true, /* sentinels = */ false>
   1640         (seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
   1641 }
   1642 
   1643 // public interface
   1644 template<
   1645     typename RandomAccessIteratorPairIterator
   1646   , typename RandomAccessIteratorOut
   1647   , typename _DifferenceTp
   1648   , typename Comparator>
   1649 RandomAccessIteratorOut
   1650 stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1651     , RandomAccessIteratorPairIterator seqs_end
   1652     , RandomAccessIteratorOut target
   1653     , _DifferenceTp length, Comparator comp
   1654     , __gnu_parallel::exact_tag tag)
   1655 {
   1656     typedef _DifferenceTp difference_type;
   1657     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1658 
   1659     // catch special case: no sequences
   1660     if (seqs_begin == seqs_end)
   1661       return target;
   1662 
   1663     // Execute merge; maybe parallel, depending on the number of merged
   1664     // elements and the number of sequences and global thresholds in
   1665     // Settings.
   1666     if ((seqs_end - seqs_begin > 1) &&
   1667           _GLIBCXX_PARALLEL_CONDITION(
   1668           ((seqs_end - seqs_begin) >=
   1669             __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   1670           && ((sequence_index_t)length >=
   1671             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   1672       return parallel_multiway_merge
   1673         </* stable = */ true, /* sentinels = */ false>(
   1674           seqs_begin, seqs_end,
   1675           target,
   1676           multiway_merge_exact_splitting</* stable = */ true,
   1677             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   1678               ::value_type*, Comparator, _DifferenceTp>,
   1679           static_cast<difference_type>(length), comp, tag.get_num_threads());
   1680     else
   1681       return sequential_multiway_merge</* stable = */ true,
   1682         /* sentinels = */ false>(
   1683           seqs_begin, seqs_end,
   1684           target, *(seqs_begin->second), length, comp);
   1685 }
   1686 
   1687 // public interface
   1688 template<
   1689     typename RandomAccessIteratorPairIterator
   1690   , typename RandomAccessIteratorOut
   1691   , typename _DifferenceTp
   1692   , typename Comparator>
   1693 RandomAccessIteratorOut
   1694 stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1695     , RandomAccessIteratorPairIterator seqs_end
   1696     , RandomAccessIteratorOut target
   1697     , _DifferenceTp length, Comparator comp
   1698     , sampling_tag tag)
   1699 {
   1700     typedef _DifferenceTp difference_type;
   1701     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1702 
   1703     // catch special case: no sequences
   1704     if (seqs_begin == seqs_end)
   1705       return target;
   1706 
   1707     // Execute merge; maybe parallel, depending on the number of merged
   1708     // elements and the number of sequences and global thresholds in
   1709     // Settings.
   1710     if ((seqs_end - seqs_begin > 1) &&
   1711           _GLIBCXX_PARALLEL_CONDITION(
   1712           ((seqs_end - seqs_begin) >=
   1713             __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   1714           && ((sequence_index_t)length >=
   1715             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   1716       return parallel_multiway_merge
   1717         </* stable = */ true, /* sentinels = */ false>(
   1718           seqs_begin, seqs_end,
   1719           target,
   1720           multiway_merge_sampling_splitting</* stable = */ true,
   1721             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   1722               ::value_type*, Comparator, _DifferenceTp>,
   1723           static_cast<difference_type>(length), comp, tag.get_num_threads());
   1724     else
   1725       return sequential_multiway_merge
   1726         </* stable = */ true, /* sentinels = */ false>(
   1727           seqs_begin, seqs_end,
   1728           target, *(seqs_begin->second), length, comp);
   1729 }
   1730 
   1731 
   1732 // public interface
   1733 template<
   1734     typename RandomAccessIteratorPairIterator
   1735   , typename RandomAccessIteratorOut
   1736   , typename _DifferenceTp
   1737   , typename Comparator>
   1738 RandomAccessIteratorOut
   1739 stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1740     , RandomAccessIteratorPairIterator seqs_end
   1741     , RandomAccessIteratorOut target
   1742     , _DifferenceTp length, Comparator comp
   1743     , parallel_tag tag = parallel_tag(0))
   1744 {
   1745   return stable_multiway_merge(seqs_begin, seqs_end, target, length, comp,
   1746                          exact_tag(tag.get_num_threads()));
   1747 }
   1748 
   1749 // public interface
   1750 template<
   1751     typename RandomAccessIteratorPairIterator
   1752   , typename RandomAccessIteratorOut
   1753   , typename _DifferenceTp
   1754   , typename Comparator>
   1755 RandomAccessIteratorOut
   1756 stable_multiway_merge(RandomAccessIteratorPairIterator seqs_begin
   1757     , RandomAccessIteratorPairIterator seqs_end
   1758     , RandomAccessIteratorOut target
   1759     , _DifferenceTp length, Comparator comp
   1760     , default_parallel_tag tag)
   1761 {
   1762   return stable_multiway_merge(seqs_begin, seqs_end, target, length, comp,
   1763                          exact_tag(tag.get_num_threads()));
   1764 }
   1765 
   1766 /**
   1767  * @brief Multiway Merge Frontend.
   1768  *
   1769  * Merge the sequences specified by seqs_begin and seqs_end into
   1770  * target.  seqs_begin and seqs_end must point to a sequence of
   1771  * pairs.  These pairs must contain an iterator to the beginning
   1772  * of a sequence in their first entry and an iterator the end of
   1773  * the same sequence in their second entry.
   1774  *
   1775  * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
   1776  * that breaks ties by sequence number but is slower.
   1777  *
   1778  * The first entries of the pairs (i.e. the begin iterators) will be moved
   1779  * forward accordingly.
   1780  *
   1781  * The output sequence has to provide enough space for all elements
   1782  * that are written to it.
   1783  *
   1784  * This function will merge the input sequences:
   1785  *
   1786  * - not stable
   1787  * - parallel, depending on the input size and Settings
   1788  * - using sampling for splitting
   1789  * - using sentinels
   1790  *
   1791  * You have to take care that the element the end iterator points to is
   1792  * readable and contains a value that is greater than any other non-sentinel
   1793  * value in all sequences.
   1794  *
   1795  * Example:
   1796  *
   1797  * <pre>
   1798  *   int sequences[10][11];
   1799  *   for (int i = 0; i < 10; ++i)
   1800  *     for (int j = 0; i < 11; ++j)
   1801  *       sequences[i][j] = j; // last one is sentinel!
   1802  *
   1803  *   int out[33];
   1804  *   std::vector<std::pair<int*> > seqs;
   1805  *   for (int i = 0; i < 10; ++i)
   1806  *     { seqs.push(std::make_pair<int*>(sequences[i], sequences[i] + 10)) }
   1807  *
   1808  *   multiway_merge(seqs.begin(), seqs.end(), target, std::less<int>(), 33);
   1809  * </pre>
   1810  *
   1811  * @pre All input sequences must be sorted.
   1812  * @pre Target must provide enough space to merge out length elements or
   1813  *    the number of elements in all sequences, whichever is smaller.
   1814  * @pre For each @c i, @c seqs_begin[i].second must be the end
   1815  *    marker of the sequence, but also reference the one more sentinel
   1816  *    element.
   1817  *
   1818  * @post [target, return value) contains merged elements from the
   1819  *    input sequences.
   1820  * @post return value - target = min(length, number of elements in all
   1821  *    sequences).
   1822  *
   1823  * @see stable_multiway_merge_sentinels
   1824  *
   1825  * @param RandomAccessIteratorPairIterator iterator over sequence
   1826  *    of pairs of iterators
   1827  * @param RandomAccessIteratorOut iterator over target sequence
   1828  * @param _DifferenceTp difference type for the sequence
   1829  * @param Comparator strict weak ordering type to compare elements
   1830  *    in sequences
   1831  *
   1832  * @param seqs_begin  begin of sequence sequence
   1833  * @param seqs_end    end of sequence sequence
   1834  * @param target      target sequence to merge to.
   1835  * @param comp        strict weak ordering to use for element comparison.
   1836  * @param length Maximum length to merge, possibly larger than the
   1837  * number of elements available.
   1838  *
   1839  * @return end iterator of output sequence
   1840  */
   1841 // multiway_merge_sentinels
   1842 // public interface
   1843 template<
   1844     typename RandomAccessIteratorPairIterator
   1845   , typename RandomAccessIteratorOut
   1846   , typename _DifferenceTp
   1847   , typename Comparator>
   1848 RandomAccessIteratorOut
   1849 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   1850     , RandomAccessIteratorPairIterator seqs_end
   1851     , RandomAccessIteratorOut target
   1852     , _DifferenceTp length, Comparator comp
   1853     , __gnu_parallel::sequential_tag)
   1854 {
   1855     typedef _DifferenceTp difference_type;
   1856     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1857 
   1858     // catch special case: no sequences
   1859     if (seqs_begin == seqs_end)
   1860       return target;
   1861 
   1862     // Execute multiway merge *sequentially*.
   1863     return sequential_multiway_merge
   1864       </* stable = */ false, /* sentinels = */ true>
   1865         (seqs_begin, seqs_end,
   1866          target, *(seqs_begin->second), length, comp);
   1867 }
   1868 
   1869 // public interface
   1870 template<
   1871     typename RandomAccessIteratorPairIterator
   1872   , typename RandomAccessIteratorOut
   1873   , typename _DifferenceTp
   1874   , typename Comparator>
   1875 RandomAccessIteratorOut
   1876 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   1877     , RandomAccessIteratorPairIterator seqs_end
   1878     , RandomAccessIteratorOut target
   1879     , _DifferenceTp length, Comparator comp
   1880     , __gnu_parallel::exact_tag tag)
   1881 {
   1882     typedef _DifferenceTp difference_type;
   1883     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1884 
   1885     // catch special case: no sequences
   1886     if (seqs_begin == seqs_end)
   1887       return target;
   1888 
   1889     // Execute merge; maybe parallel, depending on the number of merged
   1890     // elements and the number of sequences and global thresholds in
   1891     // Settings.
   1892     if ((seqs_end - seqs_begin > 1) &&
   1893           _GLIBCXX_PARALLEL_CONDITION(
   1894           ((seqs_end - seqs_begin) >=
   1895             __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   1896           && ((sequence_index_t)length >=
   1897             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   1898       return parallel_multiway_merge
   1899         </* stable = */ false, /* sentinels = */ true>(
   1900           seqs_begin, seqs_end,
   1901           target,
   1902           multiway_merge_exact_splitting</* stable = */ false,
   1903             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   1904               ::value_type*, Comparator, _DifferenceTp>,
   1905           static_cast<difference_type>(length), comp, tag.get_num_threads());
   1906     else
   1907       return sequential_multiway_merge
   1908         </* stable = */ false, /* sentinels = */ true>(
   1909           seqs_begin, seqs_end,
   1910           target, *(seqs_begin->second), length, comp);
   1911 }
   1912 
   1913 // public interface
   1914 template<
   1915     typename RandomAccessIteratorPairIterator
   1916   , typename RandomAccessIteratorOut
   1917   , typename _DifferenceTp
   1918   , typename Comparator>
   1919 RandomAccessIteratorOut
   1920 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   1921     , RandomAccessIteratorPairIterator seqs_end
   1922     , RandomAccessIteratorOut target
   1923     , _DifferenceTp length, Comparator comp
   1924     , sampling_tag tag)
   1925 {
   1926     typedef _DifferenceTp difference_type;
   1927     _GLIBCXX_CALL(seqs_end - seqs_begin)
   1928 
   1929     // catch special case: no sequences
   1930     if (seqs_begin == seqs_end)
   1931       return target;
   1932 
   1933     // Execute merge; maybe parallel, depending on the number of merged
   1934     // elements and the number of sequences and global thresholds in
   1935     // Settings.
   1936     if ((seqs_end - seqs_begin > 1) &&
   1937           _GLIBCXX_PARALLEL_CONDITION(
   1938           ((seqs_end - seqs_begin) >=
   1939             __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   1940           && ((sequence_index_t)length >=
   1941             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   1942       return parallel_multiway_merge
   1943         </* stable = */ false, /* sentinels = */ true>
   1944           (seqs_begin, seqs_end, target,
   1945           multiway_merge_sampling_splitting</* stable = */ false,
   1946             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   1947               ::value_type*, Comparator, _DifferenceTp>,
   1948           static_cast<difference_type>(length), comp, tag.get_num_threads());
   1949     else
   1950       return sequential_multiway_merge
   1951         </* stable = */false, /* sentinels = */ true>(
   1952           seqs_begin, seqs_end,
   1953           target, *(seqs_begin->second), length, comp);
   1954 }
   1955 
   1956 // public interface
   1957 template<
   1958     typename RandomAccessIteratorPairIterator
   1959   , typename RandomAccessIteratorOut
   1960   , typename _DifferenceTp
   1961   , typename Comparator>
   1962 RandomAccessIteratorOut
   1963 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   1964     , RandomAccessIteratorPairIterator seqs_end
   1965     , RandomAccessIteratorOut target
   1966     , _DifferenceTp length, Comparator comp
   1967     , parallel_tag tag = parallel_tag(0))
   1968 {
   1969   return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
   1970                          exact_tag(tag.get_num_threads()));
   1971 }
   1972 
   1973 // public interface
   1974 template<
   1975     typename RandomAccessIteratorPairIterator
   1976   , typename RandomAccessIteratorOut
   1977   , typename _DifferenceTp
   1978   , typename Comparator>
   1979 RandomAccessIteratorOut
   1980 multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   1981     , RandomAccessIteratorPairIterator seqs_end
   1982     , RandomAccessIteratorOut target
   1983     , _DifferenceTp length, Comparator comp
   1984     , default_parallel_tag tag)
   1985 {
   1986   return multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
   1987                          exact_tag(tag.get_num_threads()));
   1988 }
   1989 
   1990 // stable_multiway_merge_sentinels
   1991 // public interface
   1992 template<
   1993     typename RandomAccessIteratorPairIterator
   1994   , typename RandomAccessIteratorOut
   1995   , typename _DifferenceTp
   1996   , typename Comparator>
   1997 RandomAccessIteratorOut
   1998 stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   1999     , RandomAccessIteratorPairIterator seqs_end
   2000     , RandomAccessIteratorOut target
   2001     , _DifferenceTp length, Comparator comp
   2002     , __gnu_parallel::sequential_tag)
   2003 {
   2004     typedef _DifferenceTp difference_type;
   2005     _GLIBCXX_CALL(seqs_end - seqs_begin)
   2006 
   2007     // catch special case: no sequences
   2008     if (seqs_begin == seqs_end)
   2009       return target;
   2010 
   2011     // Execute multiway merge *sequentially*.
   2012     return sequential_multiway_merge
   2013       </* stable = */ true, /* sentinels = */ true>
   2014         (seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
   2015 }
   2016 
   2017 // public interface
   2018 template<
   2019     typename RandomAccessIteratorPairIterator
   2020   , typename RandomAccessIteratorOut
   2021   , typename _DifferenceTp
   2022   , typename Comparator>
   2023 RandomAccessIteratorOut
   2024 stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   2025     , RandomAccessIteratorPairIterator seqs_end
   2026     , RandomAccessIteratorOut target
   2027     , _DifferenceTp length, Comparator comp
   2028     , __gnu_parallel::exact_tag tag)
   2029 {
   2030     typedef _DifferenceTp difference_type;
   2031     _GLIBCXX_CALL(seqs_end - seqs_begin)
   2032 
   2033     // catch special case: no sequences
   2034     if (seqs_begin == seqs_end)
   2035       return target;
   2036 
   2037     // Execute merge; maybe parallel, depending on the number of merged
   2038     // elements and the number of sequences and global thresholds in
   2039     // Settings.
   2040     if ((seqs_end - seqs_begin > 1) &&
   2041           _GLIBCXX_PARALLEL_CONDITION(
   2042           ((seqs_end - seqs_begin) >=
   2043           __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   2044           && ((sequence_index_t)length >=
   2045           __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   2046       return parallel_multiway_merge
   2047         </* stable = */ true, /* sentinels = */ true>(
   2048           seqs_begin, seqs_end,
   2049           target,
   2050           multiway_merge_exact_splitting</* stable = */ true,
   2051             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   2052               ::value_type*, Comparator, _DifferenceTp>,
   2053           static_cast<difference_type>(length), comp, tag.get_num_threads());
   2054     else
   2055       return sequential_multiway_merge
   2056         </* stable = */ true, /* sentinels = */ true>(
   2057           seqs_begin, seqs_end, target, *(seqs_begin->second), length, comp);
   2058 }
   2059 
   2060 // public interface
   2061 template<
   2062     typename RandomAccessIteratorPairIterator
   2063   , typename RandomAccessIteratorOut
   2064   , typename _DifferenceTp
   2065   , typename Comparator>
   2066 RandomAccessIteratorOut
   2067 stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   2068     , RandomAccessIteratorPairIterator seqs_end
   2069     , RandomAccessIteratorOut target
   2070     , _DifferenceTp length, Comparator comp
   2071     , sampling_tag tag)
   2072 {
   2073     typedef _DifferenceTp difference_type;
   2074     _GLIBCXX_CALL(seqs_end - seqs_begin)
   2075 
   2076     // catch special case: no sequences
   2077     if (seqs_begin == seqs_end)
   2078       return target;
   2079 
   2080     // Execute merge; maybe parallel, depending on the number of merged
   2081     // elements and the number of sequences and global thresholds in
   2082     // Settings.
   2083     if ((seqs_end - seqs_begin > 1) &&
   2084           _GLIBCXX_PARALLEL_CONDITION(
   2085           ((seqs_end - seqs_begin) >=
   2086             __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
   2087           && ((sequence_index_t)length >=
   2088             __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
   2089       return parallel_multiway_merge
   2090         </* stable = */ true, /* sentinels = */ true>(
   2091           seqs_begin, seqs_end,
   2092           target,
   2093           multiway_merge_sampling_splitting</* stable = */ true,
   2094             typename std::iterator_traits<RandomAccessIteratorPairIterator>
   2095               ::value_type*, Comparator, _DifferenceTp>,
   2096           static_cast<difference_type>(length), comp, tag.get_num_threads());
   2097     else
   2098       return sequential_multiway_merge
   2099         </* stable = */ true, /* sentinels = */ true>(
   2100           seqs_begin, seqs_end,
   2101           target, *(seqs_begin->second), length, comp);
   2102 }
   2103 
   2104 // public interface
   2105 template<
   2106     typename RandomAccessIteratorPairIterator
   2107   , typename RandomAccessIteratorOut
   2108   , typename _DifferenceTp
   2109   , typename Comparator>
   2110 RandomAccessIteratorOut
   2111 stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   2112     , RandomAccessIteratorPairIterator seqs_end
   2113     , RandomAccessIteratorOut target
   2114     , _DifferenceTp length, Comparator comp
   2115     , parallel_tag tag = parallel_tag(0))
   2116 {
   2117   return stable_multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
   2118                          exact_tag(tag.get_num_threads()));
   2119 }
   2120 
   2121 // public interface
   2122 template<
   2123     typename RandomAccessIteratorPairIterator
   2124   , typename RandomAccessIteratorOut
   2125   , typename _DifferenceTp
   2126   , typename Comparator>
   2127 RandomAccessIteratorOut
   2128 stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
   2129     , RandomAccessIteratorPairIterator seqs_end
   2130     , RandomAccessIteratorOut target
   2131     , _DifferenceTp length, Comparator comp
   2132     , default_parallel_tag tag)
   2133 {
   2134   return stable_multiway_merge_sentinels(seqs_begin, seqs_end, target, length, comp,
   2135                          exact_tag(tag.get_num_threads()));
   2136 }
   2137 
   2138 }; // namespace __gnu_parallel
   2139 
   2140 #endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */
   2141