// -*- C++ -*-

// Copyright (C) 2007-2016 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_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*()
      { return *_M_current; }

      /** @brief Convert to wrapped iterator.
      *  @return Wrapped iterator. */
      operator _RAIter()
      { 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<(_GuardedIterator<_RAIter, _Compare>& __bi1,
		_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<=(_GuardedIterator<_RAIter, _Compare>& __bi1,
		 _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*()
      { return *_M_current; }

      /** @brief Convert to wrapped iterator.
      *  @return Wrapped iterator. */
      operator _RAIter()
      { 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<(_UnguardedIterator<_RAIter, _Compare>& __bi1,
		_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<=(_UnguardedIterator<_RAIter, _Compare>& __bi1,
		 _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 C> 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_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_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 C> 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_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_ASSERTIONS
      _DifferenceType __i = 0;
#endif

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

#if _GLIBCXX_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_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_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_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_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_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_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 */
