// -*- C++ -*-

// Copyright (C) 2007-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software
// Foundation; either version 3, or (at your option) any later
// version.

// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file parallel/multiway_merge.h
*  @brief Implementation of sequential and parallel multiway merge.
*
*  Explanations on the high-speed merging routines in the appendix of
*
*  P. Sanders.
*  Fast priority queues for cached memory.
*  ACM Journal of Experimental Algorithmics, 5, 2000.
*
*  This file is a GNU parallel extension to the Standard C++ Library.
*/

// Written by Johannes Singler and Manuel Holtgrewe.

#ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
#define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H

#include <vector>

#include <bits/stl_algo.h>
#include <parallel/features.h>
#include <parallel/parallel.h>
#include <parallel/losertree.h>
#include <parallel/multiseq_selection.h>
#if _GLIBCXX_PARALLEL_ASSERTIONS
#include <parallel/checkers.h>
#endif

/** @brief Length of a sequence described by a pair of iterators. */
#define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)

namespace __gnu_parallel
{
  template<typename _RAIter1, typename _RAIter2, typename _OutputIterator,
	   typename _DifferenceTp, typename _Compare>
    _OutputIterator
    __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2,
		    _OutputIterator, _DifferenceTp, _Compare);

  /** @brief _Iterator wrapper supporting an implicit supremum at the end
   *         of the sequence, dominating all comparisons.
   *
   * The implicit supremum comes with a performance cost.
   *
   * Deriving from _RAIter is not possible since
   * _RAIter need not be a class.
   */
  template<typename _RAIter, typename _Compare>
    class _GuardedIterator
    {
    private:
      /** @brief Current iterator __position. */
      _RAIter _M_current;

      /** @brief End iterator of the sequence. */
      _RAIter _M_end;

      /** @brief _Compare. */
      _Compare& __comp;

    public:
      /** @brief Constructor. Sets iterator to beginning of sequence.
      *  @param __begin Begin iterator of sequence.
      *  @param __end End iterator of sequence.
      *  @param __comp Comparator provided for associated overloaded
      *  compare operators. */
      _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp)
      : _M_current(__begin), _M_end(__end), __comp(__comp)
      { }

      /** @brief Pre-increment operator.
      *  @return This. */
      _GuardedIterator<_RAIter, _Compare>&
      operator++()
      {
	++_M_current;
	return *this;
      }

      /** @brief Dereference operator.
      *  @return Referenced element. */
      typename std::iterator_traits<_RAIter>::value_type&
      operator*() const
      { return *_M_current; }

      /** @brief Convert to wrapped iterator.
      *  @return Wrapped iterator. */
      operator _RAIter() const
      { return _M_current; }

      /** @brief Compare two elements referenced by guarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c true if less. */
      friend bool
      operator<(const _GuardedIterator<_RAIter, _Compare>& __bi1,
		const _GuardedIterator<_RAIter, _Compare>& __bi2)
      {
	if (__bi1._M_current == __bi1._M_end)       // __bi1 is sup
	  return __bi2._M_current == __bi2._M_end;  // __bi2 is not sup
	if (__bi2._M_current == __bi2._M_end)       // __bi2 is sup
	  return true;
	return (__bi1.__comp)(*__bi1, *__bi2);      // normal compare
      }

      /** @brief Compare two elements referenced by guarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c True if less equal. */
      friend bool
      operator<=(const _GuardedIterator<_RAIter, _Compare>& __bi1,
		 const _GuardedIterator<_RAIter, _Compare>& __bi2)
      {
	if (__bi2._M_current == __bi2._M_end)       // __bi1 is sup
	  return __bi1._M_current != __bi1._M_end;  // __bi2 is not sup
	if (__bi1._M_current == __bi1._M_end)       // __bi2 is sup
	  return false;
	return !(__bi1.__comp)(*__bi2, *__bi1);     // normal compare
      } 
    };

  template<typename _RAIter, typename _Compare>
    class _UnguardedIterator
    {
    private:
      /** @brief Current iterator __position. */
      _RAIter _M_current;
      /** @brief _Compare. */
      _Compare& __comp;

    public:
      /** @brief Constructor. Sets iterator to beginning of sequence.
      *  @param __begin Begin iterator of sequence.
      *  @param __end Unused, only for compatibility.
      *  @param __comp Unused, only for compatibility. */
      _UnguardedIterator(_RAIter __begin,
                	 _RAIter /* __end */, _Compare& __comp)
      : _M_current(__begin), __comp(__comp)
      { }

      /** @brief Pre-increment operator.
      *  @return This. */
      _UnguardedIterator<_RAIter, _Compare>&
      operator++()
      {
	++_M_current;
	return *this;
      }

      /** @brief Dereference operator.
      *  @return Referenced element. */
      typename std::iterator_traits<_RAIter>::value_type&
      operator*() const
      { return *_M_current; }

      /** @brief Convert to wrapped iterator.
      *  @return Wrapped iterator. */
      operator _RAIter() const
      { return _M_current; }

      /** @brief Compare two elements referenced by unguarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c true if less. */
      friend bool
      operator<(const _UnguardedIterator<_RAIter, _Compare>& __bi1,
		const _UnguardedIterator<_RAIter, _Compare>& __bi2)
      {
	// Normal compare.
	return (__bi1.__comp)(*__bi1, *__bi2);
      }

      /** @brief Compare two elements referenced by unguarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c True if less equal. */
      friend bool
      operator<=(const _UnguardedIterator<_RAIter, _Compare>& __bi1,
		 const _UnguardedIterator<_RAIter, _Compare>& __bi2)
      {
	// Normal compare.
	return !(__bi1.__comp)(*__bi2, *__bi1);
      }
    };

  /** @brief 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++).
   *
   * This works well for merging up to 4 sequences.
   *
   * Note that making the merging stable does @a not come at a
   * performance hit.
   *
   * Whether the merging is done guarded or unguarded is selected by the
   * used iterator class.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  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)
    {
      _GLIBCXX_CALL(__length);

      typedef _DifferenceTp _DifferenceType;

      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      if (__length == 0)
	return __target;

#if _GLIBCXX_PARALLEL_ASSERTIONS
      _DifferenceTp __orig_length = __length;
#endif

      iterator<_RAIter1, _Compare>
	__seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
	__seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
	__seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);

      if (__seq0 <= __seq1)
	{
          if (__seq1 <= __seq2)
            goto __s012;
          else
            if (__seq2 <  __seq0)
              goto __s201;
            else
              goto __s021;
	}
      else
	{
          if (__seq1 <= __seq2)
            {
              if (__seq0 <= __seq2)
        	goto __s102;
              else
        	goto __s120;
            }
          else
            goto __s210;
	}
#define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \
      __s ## __a ## __b ## __c :                            \
	*__target = *__seq ## __a;                          \
	++__target;                                         \
	--__length;                                         \
	++__seq ## __a;                                     \
	if (__length == 0) goto __finish;                   \
	if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \
	if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \
	goto __s ## __b ## __c ## __a;

      _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
      _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
      _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
      _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );

#undef _GLIBCXX_PARALLEL_MERGE_3_CASE

    __finish:
      ;

#if _GLIBCXX_PARALLEL_ASSERTIONS
    _GLIBCXX_PARALLEL_ASSERT(
	((_RAIter1)__seq0 - __seqs_begin[0].first) +
	((_RAIter1)__seq1 - __seqs_begin[1].first) +
	((_RAIter1)__seq2 - __seqs_begin[2].first)
	== __orig_length);
#endif

      __seqs_begin[0].first = __seq0;
      __seqs_begin[1].first = __seq1;
      __seqs_begin[2].first = __seq2;

      return __target;
    }

  /**
   * @brief Highly efficient 4-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 goto labels in C++).
   *
   * This works well for merging up to 4 sequences.
   *
   * Note that making the merging stable does @a not come at a
   * performance hit.
   *
   * Whether the merging is done guarded or unguarded is selected by the
   * used iterator class.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  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)
    {
      _GLIBCXX_CALL(__length);
      typedef _DifferenceTp _DifferenceType;

      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      iterator<_RAIter1, _Compare>
	__seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
	__seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
	__seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
	__seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);

#define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) {  \
	if (__seq ## __d < __seq ## __a)		  \
	  goto __s ## __d ## __a ## __b ## __c;		  \
	if (__seq ## __d < __seq ## __b)		  \
	  goto __s ## __a ## __d ## __b ## __c;		  \
	if (__seq ## __d < __seq ## __c)		  \
	  goto __s ## __a ## __b ## __d ## __c;		  \
	goto __s ## __a ## __b ## __c ## __d;  }

      if (__seq0 <= __seq1)
	{
          if (__seq1 <= __seq2)
            _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
            else
              if (__seq2 < __seq0)
        	_GLIBCXX_PARALLEL_DECISION(2,0,1,3)
        	else
                  _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
                    }
      else
	{
          if (__seq1 <= __seq2)
            {
              if (__seq0 <= __seq2)
        	_GLIBCXX_PARALLEL_DECISION(1,0,2,3)
        	else
                  _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
                    }
          else
            _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
              }

#define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d,  \
				       __c0, __c1, __c2)    \
      __s ## __a ## __b ## __c ## __d:                      \
      if (__length == 0) goto __finish;                     \
      *__target = *__seq ## __a;                            \
      ++__target;                                           \
      --__length;                                           \
      ++__seq ## __a;                                       \
      if (__seq ## __a __c0 __seq ## __b)      \
	goto __s ## __a ## __b ## __c ## __d;  \
      if (__seq ## __a __c1 __seq ## __c)      \
	goto __s ## __b ## __a ## __c ## __d;  \
      if (__seq ## __a __c2 __seq ## __d)      \
	goto __s ## __b ## __c ## __a ## __d;  \
      goto __s ## __b ## __c ## __d ## __a;

      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );

#undef _GLIBCXX_PARALLEL_MERGE_4_CASE
#undef _GLIBCXX_PARALLEL_DECISION

    __finish:
      ;

      __seqs_begin[0].first = __seq0;
      __seqs_begin[1].first = __seq1;
      __seqs_begin[2].first = __seq2;
      __seqs_begin[3].first = __seq3;

      return __target;
    }

  /** @brief Multi-way merging procedure for a high branching factor,
   *         guarded case.
   *
   * This merging variant uses a LoserTree class as selected by <tt>_LT</tt>.
   *
   * Stability is selected through the used LoserTree class <tt>_LT</tt>.
   *
   * At least one non-empty sequence is required.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  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)
    {
      _GLIBCXX_CALL(__length)

      typedef _DifferenceTp _DifferenceType;
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);

      _LT __lt(__k, __comp);

      // Default value for potentially non-default-constructible types.
      _ValueType* __arbitrary_element = 0;

      for (_SeqNumber __t = 0; __t < __k; ++__t)
	{
          if(!__arbitrary_element
	     && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0)
            __arbitrary_element = &(*__seqs_begin[__t].first);
	}

      for (_SeqNumber __t = 0; __t < __k; ++__t)
	{
          if (__seqs_begin[__t].first == __seqs_begin[__t].second)
            __lt.__insert_start(*__arbitrary_element, __t, true);
          else
            __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
	}

      __lt.__init();

      _SeqNumber __source;

      for (_DifferenceType __i = 0; __i < __length; ++__i)
	{
          //take out
          __source = __lt.__get_min_source();

          *(__target++) = *(__seqs_begin[__source].first++);

          // Feed.
          if (__seqs_begin[__source].first == __seqs_begin[__source].second)
            __lt.__delete_min_insert(*__arbitrary_element, true);
          else
            // Replace from same __source.
            __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
	}

      return __target;
    }

  /** @brief Multi-way merging procedure for a high branching factor,
   *         unguarded case.
   *
   * Merging is done using the LoserTree class <tt>_LT</tt>.
   *
   * Stability is selected by the used LoserTrees.
   *
   * @pre No input will run out of elements during the merge.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  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)
    {
      _GLIBCXX_CALL(__length)
      typedef _DifferenceTp _DifferenceType;

      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      _SeqNumber __k = __seqs_end - __seqs_begin;

      _LT __lt(__k, __sentinel, __comp);

      for (_SeqNumber __t = 0; __t < __k; ++__t)
	{
#if _GLIBCXX_PARALLEL_ASSERTIONS
          _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
                                   != __seqs_begin[__t].second);
#endif
          __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
	}

      __lt.__init();

      _SeqNumber __source;

#if _GLIBCXX_PARALLEL_ASSERTIONS
      _DifferenceType __i = 0;
#endif

      _RAIter3 __target_end = __target + __length;
      while (__target < __target_end)
	{
          // Take out.
          __source = __lt.__get_min_source();

#if _GLIBCXX_PARALLEL_ASSERTIONS
          _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k);
          _GLIBCXX_PARALLEL_ASSERT(__i == 0
              || !__comp(*(__seqs_begin[__source].first), *(__target - 1)));
#endif

          // Feed.
          *(__target++) = *(__seqs_begin[__source].first++);

#if _GLIBCXX_PARALLEL_ASSERTIONS
          ++__i;
#endif
          // Replace from same __source.
          __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
	}

      return __target;
    }


  /** @brief Multi-way merging procedure for a high branching factor,
   *         requiring sentinels to exist.
   *
   * @tparam _UnguardedLoserTree Loser Tree variant to use for the unguarded
   *				 merging.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  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)
    {
      _GLIBCXX_CALL(__length)

      typedef _DifferenceTp _DifferenceType;
      typedef std::iterator_traits<_RAIterIterator> _TraitsType;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      _RAIter3 __target_end;

      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	// Move the sequence ends to the sentinel.  This has the
	// effect that the sentinel appears to be within the sequence. Then,
	// we can use the unguarded variant if we merge out as many
	// non-sentinel elements as we have.
	++((*__s).second);

      __target_end = multiway_merge_loser_tree_unguarded<_UnguardedLoserTree>
	(__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);

#if _GLIBCXX_PARALLEL_ASSERTIONS
      _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
      _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp));
#endif

      // Restore the sequence ends so the sentinels are not contained in the
      // sequence any more (see comment in loop above).
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	--((*__s).second);

      return __target_end;
    }

  /**
   * @brief Traits for determining whether the loser tree should
   *   use pointers or copies.
   *
   * The field "_M_use_pointer" is used to determine whether to use pointers
   * in he loser trees or whether to copy the values into the loser tree.
   *
   * The default behavior is to use pointers if the data type is 4 times as
   * big as the pointer to it.
   *
   * Specialize for your data type to customize the behavior.
   *
   * Example:
   *
   *   template<>
   *   struct _LoserTreeTraits<int>
   *   { static const bool _M_use_pointer = false; };
   *
   *   template<>
   *   struct _LoserTreeTraits<heavyweight_type>
   *   { static const bool _M_use_pointer = true; };
   *
   * @param _Tp type to give the loser tree traits for.
   */
  template <typename _Tp>
    struct _LoserTreeTraits
    {
      /**
       * @brief True iff to use pointers instead of values in loser trees.
       *
       * The default behavior is to use pointers if the data type is four
       * times as big as the pointer to it.
       */
      static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*));
    };

  /**
   * @brief Switch for 3-way merging with __sentinels turned off.
   *
   * Note that 3-way merging is always stable!
   */
  template<bool __sentinels /*default == false*/,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_3_variant_sentinel_switch
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_3_variant<_GuardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for 3-way merging with __sentinels turned on.
   *
   * Note that 3-way merging is always stable!
   */
  template<typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_3_variant_sentinel_switch<true, _RAIterIterator,
						      _RAIter3, _DifferenceTp,
						      _Compare>
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_3_variant<_UnguardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for 4-way merging with __sentinels turned off.
   *
   * Note that 4-way merging is always stable!
   */
  template<bool __sentinels /*default == false*/,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_4_variant_sentinel_switch
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_4_variant<_GuardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for 4-way merging with __sentinels turned on.
   *
   * Note that 4-way merging is always stable!
   */
  template<typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_4_variant_sentinel_switch<true, _RAIterIterator,
						      _RAIter3, _DifferenceTp,
						      _Compare>
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_4_variant<_UnguardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for k-way merging with __sentinels turned on.
   */
  template<bool __sentinels,
	   bool __stable,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_k_variant_sentinel_switch
    {
      _RAIter3
      operator()(_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)
      {
	typedef typename std::iterator_traits<_RAIterIterator>
	  ::value_type::first_type
	  _RAIter1;
	typedef typename std::iterator_traits<_RAIter1>::value_type
	  _ValueType;

	return multiway_merge_loser_tree_sentinel<
	typename __gnu_cxx::__conditional_type<
	_LoserTreeTraits<_ValueType>::_M_use_pointer,
	  _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>,
	  _LoserTreeUnguarded<__stable, _ValueType, _Compare>
          >::__type>
	  (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
      }
    };

  /**
   * @brief Switch for k-way merging with __sentinels turned off.
   */
  template<bool __stable,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_k_variant_sentinel_switch<false, __stable,
						      _RAIterIterator,
						      _RAIter3, _DifferenceTp,
						      _Compare>
    {
      _RAIter3
      operator()(_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)
      {
	typedef typename std::iterator_traits<_RAIterIterator>
	  ::value_type::first_type
	  _RAIter1;
	typedef typename std::iterator_traits<_RAIter1>::value_type
	  _ValueType;

	return multiway_merge_loser_tree<
	typename __gnu_cxx::__conditional_type<
	_LoserTreeTraits<_ValueType>::_M_use_pointer,
	  _LoserTreePointer<__stable, _ValueType, _Compare>,
	  _LoserTree<__stable, _ValueType, _Compare>
          >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
      }
    };

  /** @brief Sequential multi-way merging switch.
   *
   *  The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and
   *  runtime settings.
   *  @param __seqs_begin Begin iterator of iterator pair input sequence.
   *  @param __seqs_end End iterator of iterator pair input sequence.
   *  @param __target Begin iterator of output sequence.
   *  @param __comp Comparator.
   *  @param __length Maximum length to merge, possibly larger than the
   *  number of elements available.
   *  @param __sentinel The sequences have __a __sentinel element.
   *  @return End iterator of output sequence. */
  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)
    {
      _GLIBCXX_CALL(__length)

      typedef _DifferenceTp _DifferenceType;
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

#if _GLIBCXX_PARALLEL_ASSERTIONS
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	{
          _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first,
					       (*__s).second, __comp));
	}
#endif

      _DifferenceTp __total_length = 0;
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	__total_length += _GLIBCXX_PARALLEL_LENGTH(*__s);

      __length = std::min<_DifferenceTp>(__length, __total_length);

      if(__length == 0)
	return __target;

      _RAIter3 __return_target = __target;
      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);

      switch (__k)
	{
	case 0:
          break;
	case 1:
          __return_target = std::copy(__seqs_begin[0].first,
				      __seqs_begin[0].first + __length,
				      __target);
          __seqs_begin[0].first += __length;
          break;
	case 2:
          __return_target = __merge_advance(__seqs_begin[0].first,
					    __seqs_begin[0].second,
					    __seqs_begin[1].first,
					    __seqs_begin[1].second,
					    __target, __length, __comp);
          break;
	case 3:
          __return_target = __multiway_merge_3_variant_sentinel_switch
	    <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
	    (__seqs_begin, __seqs_end, __target, __length, __comp);
          break;
	case 4:
          __return_target = __multiway_merge_4_variant_sentinel_switch
	    <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
	    (__seqs_begin, __seqs_end, __target, __length, __comp);
          break;
	default:
	  __return_target = __multiway_merge_k_variant_sentinel_switch
	    <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp,
	     _Compare>()
	    (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
	  break;
	}
#if _GLIBCXX_PARALLEL_ASSERTIONS
      _GLIBCXX_PARALLEL_ASSERT(
	__is_sorted(__target, __target + __length, __comp));
#endif

      return __return_target;
    }

  /**
   * @brief Stable sorting functor.
   *
   * Used to reduce code instanciation in multiway_merge_sampling_splitting.
   */
  template<bool __stable, class _RAIter, class _StrictWeakOrdering>
    struct _SamplingSorter
    {
      void
      operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
      { __gnu_sequential::stable_sort(__first, __last, __comp); }
    };

  /**
   * @brief Non-__stable sorting functor.
   *
   * Used to reduce code instantiation in multiway_merge_sampling_splitting.
   */
  template<class _RAIter, class _StrictWeakOrdering>
    struct _SamplingSorter<false, _RAIter, _StrictWeakOrdering>
    {
      void
      operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
      { __gnu_sequential::sort(__first, __last, __comp); }
    };

  /**
   * @brief Sampling based splitting for parallel multiway-merge routine.
   */
  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)
    {
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      // __k sequences.
      const _SeqNumber __k
	= static_cast<_SeqNumber>(__seqs_end - __seqs_begin);

      const _ThreadIndex __num_threads = omp_get_num_threads();

      const _DifferenceType __num_samples =
	__gnu_parallel::_Settings::get().merge_oversampling * __num_threads;

      _ValueType* __samples = static_cast<_ValueType*>
	(::operator new(sizeof(_ValueType) * __k * __num_samples));
      // Sample.
      for (_SeqNumber __s = 0; __s < __k; ++__s)
	for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
	  {
	    _DifferenceType sample_index = static_cast<_DifferenceType>
	      (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s])
	       * (double(__i + 1) / (__num_samples + 1))
	       * (double(__length) / __total_length));
	    new(&(__samples[__s * __num_samples + __i]))
              _ValueType(__seqs_begin[__s].first[sample_index]);
	  }

      // Sort stable or non-stable, depending on value of template parameter
      // "__stable".
      _SamplingSorter<__stable, _ValueType*, _Compare>()
	(__samples, __samples + (__num_samples * __k), __comp);

      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
	// For each slab / processor.
	for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
	  {
	    // For each sequence.
	    if (__slab > 0)
	      __pieces[__slab][__seq].first = std::upper_bound
		(__seqs_begin[__seq].first, __seqs_begin[__seq].second,
		 __samples[__num_samples * __k * __slab / __num_threads],
		 __comp)
		- __seqs_begin[__seq].first;
	    else
	      // Absolute beginning.
	      __pieces[__slab][__seq].first = 0;
	    if ((__slab + 1) < __num_threads)
	      __pieces[__slab][__seq].second = std::upper_bound
		(__seqs_begin[__seq].first, __seqs_begin[__seq].second,
		 __samples[__num_samples * __k * (__slab + 1) / __num_threads],
		 __comp)
		- __seqs_begin[__seq].first;
	    else
              // Absolute end.
	      __pieces[__slab][__seq].second =
		_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
	  }

      for (_SeqNumber __s = 0; __s < __k; ++__s)
	for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
	  __samples[__s * __num_samples + __i].~_ValueType();
      ::operator delete(__samples);
    }

  /**
   * @brief Exact splitting for parallel multiway-merge routine.
   *
   * None of the passed sequences may be empty.
   */
  template<bool __stable,
	   typename _RAIterIterator,
	   typename _Compare,
	   typename _DifferenceType>
    void
    multiway_merge_exact_splitting(_RAIterIterator __seqs_begin,
				   _RAIterIterator __seqs_end,
				   _DifferenceType __length,
				   _DifferenceType __total_length,
				   _Compare __comp,
       std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
    {
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;

      const bool __tight = (__total_length == __length);

      // __k sequences.
      const _SeqNumber __k = __seqs_end - __seqs_begin;

      const _ThreadIndex __num_threads = omp_get_num_threads();

      // (Settings::multiway_merge_splitting
      //  == __gnu_parallel::_Settings::EXACT).
      std::vector<_RAIter1>* __offsets = 
	new std::vector<_RAIter1>[__num_threads];
      std::vector<std::pair<_RAIter1, _RAIter1> > __se(__k);

      copy(__seqs_begin, __seqs_end, __se.begin());

      _DifferenceType* __borders =
	new _DifferenceType[__num_threads + 1];
      __equally_split(__length, __num_threads, __borders);

      for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
	{
	  __offsets[__s].resize(__k);
	  multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1],
			     __offsets[__s].begin(), __comp);

	  // Last one also needed and available.
	  if (!__tight)
	    {
	      __offsets[__num_threads - 1].resize(__k);
	      multiseq_partition(__se.begin(), __se.end(),
				 _DifferenceType(__length),
				 __offsets[__num_threads - 1].begin(),
				 __comp);
	    }
	}
      delete[] __borders;

      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
	{
	  // For each slab / processor.
	  for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
	    {
	      // For each sequence.
	      if (__slab == 0)
		{
		  // Absolute beginning.
		  __pieces[__slab][__seq].first = 0;
		}
	      else
		__pieces[__slab][__seq].first =
		  __pieces[__slab - 1][__seq].second;
	      if (!__tight || __slab < (__num_threads - 1))
		__pieces[__slab][__seq].second =
		  __offsets[__slab][__seq] - __seqs_begin[__seq].first;
	      else
		{
		  // __slab == __num_threads - 1
		  __pieces[__slab][__seq].second =
                    _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
		}
	    }
	}
      delete[] __offsets;
    }

  /** @brief Parallel multi-way merge routine.
   *
   * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor
   * and runtime settings.
   *
   * Must not be called if the number of sequences is 1.
   *
   * @tparam _Splitter functor to split input (either __exact or sampling based)
   * @tparam __stable Stable merging incurs a performance penalty.
   * @tparam __sentinel Ignored.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, possibly larger than the
   * number of elements available.
   * @return End iterator of output sequence.
   */
  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)
      {
#if _GLIBCXX_PARALLEL_ASSERTIONS
	_GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
#endif

	_GLIBCXX_CALL(__length)

	typedef _DifferenceTp _DifferenceType;
        typedef typename std::iterator_traits<_RAIterIterator>
	  ::difference_type _SeqNumber;
	typedef typename std::iterator_traits<_RAIterIterator>
          ::value_type::first_type
          _RAIter1;
	typedef typename
          std::iterator_traits<_RAIter1>::value_type _ValueType;

	// Leave only non-empty sequences.
	typedef std::pair<_RAIter1, _RAIter1> seq_type;
	seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin];
	_SeqNumber __k = 0;
	_DifferenceType __total_length = 0;
	for (_RAIterIterator __raii = __seqs_begin;
             __raii != __seqs_end; ++__raii)
          {
            _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
            if(__seq_length > 0)
              {
        	__total_length += __seq_length;
        	__ne_seqs[__k++] = *__raii;
              }
          }

	_GLIBCXX_CALL(__total_length)

	__length = std::min<_DifferenceTp>(__length, __total_length);

	if (__total_length == 0 || __k == 0)
	  {
	    delete[] __ne_seqs;
	    return __target;
	  }

	std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;

	__num_threads = static_cast<_ThreadIndex>
          (std::min<_DifferenceType>(__num_threads, __total_length));

#       pragma omp parallel num_threads (__num_threads)
	{
#         pragma omp single
	  {
	    __num_threads = omp_get_num_threads();
	    // Thread __t will have to merge pieces[__iam][0..__k - 1]
	    __pieces = new std::vector<
	    std::pair<_DifferenceType, _DifferenceType> >[__num_threads];
	    for (_ThreadIndex __s = 0; __s < __num_threads; ++__s)
	      __pieces[__s].resize(__k);

	    _DifferenceType __num_samples =
	      __gnu_parallel::_Settings::get().merge_oversampling
	      * __num_threads;

	    __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
		       __comp, __pieces);
	  } //single

	  _ThreadIndex __iam = omp_get_thread_num();

	  _DifferenceType __target_position = 0;

	  for (_SeqNumber __c = 0; __c < __k; ++__c)
	    __target_position += __pieces[__iam][__c].first;

	  seq_type* __chunks = new seq_type[__k];

	  for (_SeqNumber __s = 0; __s < __k; ++__s)
	    __chunks[__s] = std::make_pair(__ne_seqs[__s].first
					   + __pieces[__iam][__s].first,
					   __ne_seqs[__s].first
					   + __pieces[__iam][__s].second);

	  if(__length > __target_position)
	    __sequential_multiway_merge<__stable, __sentinels>
	      (__chunks, __chunks + __k, __target + __target_position,
	       *(__seqs_begin->second), __length - __target_position, __comp);

	  delete[] __chunks;
	} // parallel

#if _GLIBCXX_PARALLEL_ASSERTIONS
	_GLIBCXX_PARALLEL_ASSERT(
          __is_sorted(__target, __target + __length, __comp));
#endif

	__k = 0;
	// Update ends of sequences.
	for (_RAIterIterator __raii = __seqs_begin;
             __raii != __seqs_end; ++__raii)
          {
            _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
            if(__length > 0)
              (*__raii).first += __pieces[__num_threads - 1][__k++].second;
          }

	delete[] __pieces;
	delete[] __ne_seqs;

	return __target + __length;
      }

  /**
   * @brief 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 the _M_end of
   * the same sequence in their second entry.
   *
   * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
   * that breaks ties by sequence number but is slower.
   *
   * The first entries of the pairs (i.e. the begin iterators) will be moved
   * forward.
   *
   * The output sequence has to provide enough space for all elements
   * that are written to it.
   *
   * 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:
   *
   * <pre>
   *   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);
   * </pre>
   *
   * @see stable_multiway_merge
   *
   * @pre All input sequences must be sorted.
   * @pre Target must provide enough space to merge out length elements or
   *    the number of elements in all sequences, whichever is smaller.
   *
   * @post [__target, return __value) contains merged __elements from the
   *    input sequences.
   * @post return __value - __target = min(__length, number of elements in all
   *    sequences).
   *
   * @tparam _RAIterPairIterator iterator over sequence
   *    of pairs of iterators
   * @tparam _RAIterOut iterator over target sequence
   * @tparam _DifferenceTp difference type for the sequence
   * @tparam _Compare strict weak ordering type to compare elements
   *    in sequences
   *
   * @param __seqs_begin  __begin of sequence __sequence
   * @param __seqs_end    _M_end of sequence __sequence
   * @param __target      target sequence to merge to.
   * @param __comp        strict weak ordering to use for element comparison.
   * @param __length Maximum length to merge, possibly larger than the
   * number of elements available.
   *
   * @return _M_end iterator of output sequence
   */
  // multiway_merge
  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ false, /* __sentinels = */ false>
	(__seqs_begin, __seqs_end, __target,
	 *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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))
    { return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
			    __comp, exact_tag(__tag.__get_num_threads())); }

  // public interface
  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)
    { return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
			    __comp, exact_tag(__tag.__get_num_threads())); }

  // stable_multiway_merge
  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ true, /* __sentinels = */ false>
          (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
	  </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_sampling_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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))
    {
      return stable_multiway_merge
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // public interface
  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)
    {
      return stable_multiway_merge
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  /**
   * @brief 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 the _M_end of
   * the same sequence in their second entry.
   *
   * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
   * that breaks ties by sequence number but is slower.
   *
   * 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 elements
   * that are written to it.
   *
   * 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.
   *
   * Example:
   *
   * <pre>
   *   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);
   * </pre>
   *
   * @pre All input sequences must be sorted.
   * @pre Target must provide enough space to merge out length elements or
   *    the number of elements in all sequences, whichever is smaller.
   * @pre For each @c __i, @c __seqs_begin[__i].second must be the end
   *    marker of the sequence, but also reference the one more __sentinel
   *    element.
   *
   * @post [__target, return __value) contains merged __elements from the
   *    input sequences.
   * @post return __value - __target = min(__length, number of elements in all
   *    sequences).
   *
   * @see stable_multiway_merge_sentinels
   *
   * @tparam _RAIterPairIterator iterator over sequence
   *    of pairs of iterators
   * @tparam _RAIterOut iterator over target sequence
   * @tparam _DifferenceTp difference type for the sequence
   * @tparam _Compare strict weak ordering type to compare elements
   *    in sequences
   *
   * @param __seqs_begin  __begin of sequence __sequence
   * @param __seqs_end    _M_end of sequence __sequence
   * @param __target      target sequence to merge to.
   * @param __comp        strict weak ordering to use for element comparison.
   * @param __length Maximum length to merge, possibly larger than the
   * number of elements available.
   *
   * @return _M_end iterator of output sequence
   */
  // multiway_merge_sentinels
  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ false, /* __sentinels = */ true>
          (__seqs_begin, __seqs_end,
           __target, *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ false, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ false, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ false, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_sampling_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */false, /* __sentinels = */ true>(
            __seqs_begin, __seqs_end, __target,
	    *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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))
    {
      return multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // public interface
  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)
    {
      return multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // stable_multiway_merge_sentinels
  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ true, /* __sentinels = */ true>
	(__seqs_begin, __seqs_end, __target,
	 *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
            __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
            __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_sampling_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  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))
    {
      return stable_multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // public interface
  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)
    {
      return stable_multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }
}; // namespace __gnu_parallel

#endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */
