// -*- C++ -*-

// Copyright (C) 2007, 2008, 2009 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/losertree.h
*  @brief Many generic loser tree variants.
*  This file is a GNU parallel extension to the Standard C++ Library.
*/

// Written by Johannes Singler.

#ifndef _GLIBCXX_PARALLEL_LOSERTREE_H
#define _GLIBCXX_PARALLEL_LOSERTREE_H 1

#include <bits/stl_algobase.h>
#include <bits/stl_function.h>
#include <parallel/features.h>
#include <parallel/base.h>

namespace __gnu_parallel
{
  /**
   * @brief Guarded loser/tournament tree.
   *
   * The smallest element is at the top.
   *
   * Guarding is done explicitly through one flag _M_sup per element,
   * inf is not needed due to a better initialization routine.  This
   * is a well-performing variant.
   *
   * @param _Tp the element type
   * @param _Compare the comparator to use, defaults to std::less<_Tp>
   */
  template<typename _Tp, typename _Compare>
    class _LoserTreeBase
    {
    protected:
      /** @brief Internal representation of a _LoserTree element. */
      struct _Loser
      {
	/** @brief flag, true iff this is a "maximum" __sentinel. */
	bool _M_sup;
	/** @brief __index of the __source __sequence. */
	int _M_source;
	/** @brief _M_key of the element in the _LoserTree. */
	_Tp _M_key;
      };

      unsigned int _M_ik, _M_k, _M_offset;

      /** log_2{_M_k} */
      unsigned int _M_log_k;

      /** @brief _LoserTree __elements. */
      _Loser* _M_losers;

      /** @brief _Compare to use. */
      _Compare _M_comp;

      /**
       * @brief State flag that determines whether the _LoserTree is empty.
       *
       * Only used for building the _LoserTree.
       */
      bool _M_first_insert;

    public:
      /**
       * @brief The constructor.
       *
       * @param __k The number of sequences to merge.
       * @param __comp The comparator to use.
       */
      _LoserTreeBase(unsigned int __k, _Compare __comp)
      : _M_comp(__comp)
      {
	_M_ik = __k;

	// Compute log_2{_M_k} for the _Loser Tree
	_M_log_k = __rd_log2(_M_ik - 1) + 1;

	// Next greater power of 2.
	_M_k = 1 << _M_log_k;
	_M_offset = _M_k;

	// Avoid default-constructing _M_losers[]._M_key
	_M_losers = static_cast<_Loser*>(::operator new(2 * _M_k
							* sizeof(_Loser)));
	for (unsigned int __i = _M_ik - 1; __i < _M_k; ++__i)
	  _M_losers[__i + _M_k]._M_sup = true;

	_M_first_insert = true;
      }

      /**
       * @brief The destructor.
       */
      ~_LoserTreeBase()
      { ::operator delete(_M_losers); }

      /**
       * @brief Initializes the sequence "_M_source" with the element "__key".
       *
       * @param __key the element to insert
       * @param __source __index of the __source __sequence
       * @param __sup flag that determines whether the value to insert is an
       *   explicit __supremum.
       */
      void
      __insert_start(const _Tp& __key, int __source, bool __sup)
      {
	unsigned int __pos = _M_k + __source;

	if(_M_first_insert)
	  {
	    // Construct all keys, so we can easily deconstruct them.
	    for (unsigned int __i = 0; __i < (2 * _M_k); ++__i)
	      new(&(_M_losers[__i]._M_key)) _Tp(__key);
	    _M_first_insert = false;
	  }
	else
	  new(&(_M_losers[__pos]._M_key)) _Tp(__key);

	_M_losers[__pos]._M_sup = __sup;
	_M_losers[__pos]._M_source = __source;
      }

      /**
       * @return the index of the sequence with the smallest element.
       */
      int __get_min_source()
      { return _M_losers[0]._M_source; }
    };

    /**
     * @brief Stable _LoserTree variant.
     *
     * Provides the stable implementations of insert_start, __init_winner,
     * __init and __delete_min_insert.
     *
     * Unstable variant is done using partial specialisation below.
     */
  template<bool __stable/* default == true */, typename _Tp,
	   typename _Compare>
    class _LoserTree
    : public _LoserTreeBase<_Tp, _Compare>
    {
      typedef _LoserTreeBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;
      using _Base::_M_first_insert;

    public:
      _LoserTree(unsigned int __k, _Compare __comp)
      : _Base::_LoserTreeBase(__k, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);
	    if (_M_losers[__right]._M_sup
		|| (!_M_losers[__left]._M_sup
		    && !_M_comp(_M_losers[__right]._M_key,
				_M_losers[__left]._M_key)))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void __init()
      { _M_losers[0] = _M_losers[__init_winner(1)]; }

      /**
       * @brief Delete the smallest element and insert a new element from
       *   the previously smallest element's sequence.
       *
       * This implementation is stable.
       */
      // Do not pass a const reference since __key will be used as
      // local variable.
      void
      __delete_min_insert(_Tp __key, bool __sup)
      {
        using std::swap;
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted, ties are broken by _M_source.
	    if ((__sup && (!_M_losers[__pos]._M_sup
			   || _M_losers[__pos]._M_source < __source))
		|| (!__sup && !_M_losers[__pos]._M_sup
		    && ((_M_comp(_M_losers[__pos]._M_key, __key))
			|| (!_M_comp(__key, _M_losers[__pos]._M_key)
			    && _M_losers[__pos]._M_source < __source))))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_sup, __sup);
		std::swap(_M_losers[__pos]._M_source, __source);
		swap(_M_losers[__pos]._M_key, __key);
	      }
	  }

	_M_losers[0]._M_sup = __sup;
	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_key = __key;
      }
    };

    /**
     * @brief Unstable _LoserTree variant.
     *
     * Stability (non-stable here) is selected with partial specialization.
     */
  template<typename _Tp, typename _Compare>
    class _LoserTree</* __stable == */false, _Tp, _Compare>
    : public _LoserTreeBase<_Tp, _Compare>
    {
      typedef _LoserTreeBase<_Tp, _Compare> _Base;
      using _Base::_M_log_k;
      using _Base::_M_k;
      using _Base::_M_losers;
      using _Base::_M_first_insert;

    public:
      _LoserTree(unsigned int __k, _Compare __comp)
      : _Base::_LoserTreeBase(__k, __comp)
      { }

      /**
       * Computes the winner of the competition at position "__root".
       *
       * Called recursively (starting at 0) to build the initial tree.
       *
       * @param __root __index of the "game" to start.
       */
      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);
	    if (_M_losers[__right]._M_sup
		|| (!_M_losers[__left]._M_sup
		    && !_M_comp(_M_losers[__right]._M_key,
				_M_losers[__left]._M_key)))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void
      __init()
      { _M_losers[0] = _M_losers[__init_winner(1)]; }

      /**
       * Delete the _M_key smallest element and insert the element __key
       * instead.
       *
       * @param __key the _M_key to insert
       * @param __sup true iff __key is an explicitly marked supremum
       */
      // Do not pass a const reference since __key will be used as local
      // variable.
      void
      __delete_min_insert(_Tp __key, bool __sup)
      {
        using std::swap;
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted.
	    if (__sup || (!_M_losers[__pos]._M_sup
			  && _M_comp(_M_losers[__pos]._M_key, __key)))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_sup, __sup);
		std::swap(_M_losers[__pos]._M_source, __source);
		swap(_M_losers[__pos]._M_key, __key);
	      }
	  }

	_M_losers[0]._M_sup = __sup;
	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_key = __key;
      }
    };

  /**
   * @brief Base class of _Loser Tree implementation using pointers.
   */
  template<typename _Tp, typename _Compare>
    class _LoserTreePointerBase
    {
    protected:
      /** @brief Internal representation of _LoserTree __elements. */
      struct _Loser
      {
	bool _M_sup;
	int _M_source;
	const _Tp* _M_keyp;
      };

      unsigned int _M_ik, _M_k, _M_offset;
      _Loser* _M_losers;
      _Compare _M_comp;

    public:
      _LoserTreePointerBase(unsigned int __k,
			    _Compare __comp = std::less<_Tp>())
      : _M_comp(__comp)
      {
	_M_ik = __k;

	// Next greater power of 2.
	_M_k = 1 << (__rd_log2(_M_ik - 1) + 1);
	_M_offset = _M_k;
	_M_losers = new _Loser[_M_k * 2];
	for (unsigned int __i = _M_ik - 1; __i < _M_k; __i++)
	  _M_losers[__i + _M_k]._M_sup = true;
      }

      ~_LoserTreePointerBase()
      { ::operator delete[](_M_losers); }

      int __get_min_source()
      { return _M_losers[0]._M_source; }

      void __insert_start(const _Tp& __key, int __source, bool __sup)
      {
	unsigned int __pos = _M_k + __source;

	_M_losers[__pos]._M_sup = __sup;
	_M_losers[__pos]._M_source = __source;
	_M_losers[__pos]._M_keyp = &__key;
      }
    };

  /**
   * @brief Stable _LoserTree implementation.
   *
   * The unstable variant is implemented using partial instantiation below.
   */
  template<bool __stable/* default == true */, typename _Tp, typename _Compare>
    class _LoserTreePointer
    : public _LoserTreePointerBase<_Tp, _Compare>
    {
      typedef _LoserTreePointerBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;

    public:
      _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>())
      : _Base::_LoserTreePointerBase(__k, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);
	    if (_M_losers[__right]._M_sup
		|| (!_M_losers[__left]._M_sup
		    && !_M_comp(*_M_losers[__right]._M_keyp,
				*_M_losers[__left]._M_keyp)))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void __init()
      { _M_losers[0] = _M_losers[__init_winner(1)]; }

      void __delete_min_insert(const _Tp& __key, bool __sup)
      {
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	const _Tp* __keyp = &__key;
	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted, ties are broken by __source.
	    if ((__sup && (!_M_losers[__pos]._M_sup
			   || _M_losers[__pos]._M_source < __source))
		|| (!__sup && !_M_losers[__pos]._M_sup &&
		    ((_M_comp(*_M_losers[__pos]._M_keyp, *__keyp))
		     || (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp)
			 && _M_losers[__pos]._M_source < __source))))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_sup, __sup);
		std::swap(_M_losers[__pos]._M_source, __source);
		std::swap(_M_losers[__pos]._M_keyp, __keyp);
	      }
	  }

	_M_losers[0]._M_sup = __sup;
	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_keyp = __keyp;
      }
    };

  /**
   * @brief Unstable _LoserTree implementation.
   *
   * The stable variant is above.
   */
  template<typename _Tp, typename _Compare>
    class _LoserTreePointer</* __stable == */false, _Tp, _Compare>
    : public _LoserTreePointerBase<_Tp, _Compare>
    {
      typedef _LoserTreePointerBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;

    public:
      _LoserTreePointer(unsigned int __k, _Compare __comp = std::less<_Tp>())
      : _Base::_LoserTreePointerBase(__k, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);
	    if (_M_losers[__right]._M_sup
        	|| (!_M_losers[__left]._M_sup
		    && !_M_comp(*_M_losers[__right]._M_keyp,
				*_M_losers[__left]._M_keyp)))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void __init()
      { _M_losers[0] = _M_losers[__init_winner(1)]; }

      void __delete_min_insert(const _Tp& __key, bool __sup)
      {
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	const _Tp* __keyp = &__key;
	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted.
	    if (__sup || (!_M_losers[__pos]._M_sup
			  && _M_comp(*_M_losers[__pos]._M_keyp, *__keyp)))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_sup, __sup);
		std::swap(_M_losers[__pos]._M_source, __source);
		std::swap(_M_losers[__pos]._M_keyp, __keyp);
	      }
	  }

	_M_losers[0]._M_sup = __sup;
	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_keyp = __keyp;
      }
    };

  /** @brief Base class for unguarded _LoserTree implementation.
   * 
   * The whole element is copied into the tree structure.
   *
   * No guarding is done, therefore not a single input sequence must
   * run empty.  Unused __sequence heads are marked with a sentinel which
   * is &gt; all elements that are to be merged.
   *
   * This is a very fast variant.
   */
  template<typename _Tp, typename _Compare>
    class _LoserTreeUnguardedBase
    {
    protected:
      struct _Loser
      {
	int _M_source;
	_Tp _M_key;
      };

      unsigned int _M_ik, _M_k, _M_offset;
      _Loser* _M_losers;
      _Compare _M_comp;

    public:
      _LoserTreeUnguardedBase(unsigned int __k, const _Tp __sentinel,
			      _Compare __comp = std::less<_Tp>())
      : _M_comp(__comp)
      {
	_M_ik = __k;

	// Next greater power of 2.
	_M_k = 1 << (__rd_log2(_M_ik - 1) + 1);
	_M_offset = _M_k;
	// Avoid default-constructing _M_losers[]._M_key
	_M_losers = static_cast<_Loser*>(::operator new(2 * _M_k
							* sizeof(_Loser)));

	for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
	  {
	    _M_losers[__i]._M_key = __sentinel;
	    _M_losers[__i]._M_source = -1;
	  }
      }

      ~_LoserTreeUnguardedBase()
      { ::operator delete(_M_losers); }

      int
      __get_min_source()
      {
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
	return _M_losers[0]._M_source;
      }

      void
      __insert_start(const _Tp& __key, int __source, bool)
      {
	unsigned int __pos = _M_k + __source;

	new(&(_M_losers[__pos]._M_key)) _Tp(__key);
	_M_losers[__pos]._M_source = __source;
      }
    };

  /**
   * @brief Stable implementation of unguarded _LoserTree.
   *
   * Unstable variant is selected below with partial specialization.
   */
  template<bool __stable/* default == true */, typename _Tp, typename _Compare>
    class _LoserTreeUnguarded
    : public _LoserTreeUnguardedBase<_Tp, _Compare>
    {
      typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;

  public:
      _LoserTreeUnguarded(unsigned int __k, const _Tp __sentinel,
			  _Compare __comp = std::less<_Tp>())
      : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);
	    if (!_M_comp(_M_losers[__right]._M_key,
			 _M_losers[__left]._M_key))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void
      __init()
      {
	_M_losers[0] = _M_losers[__init_winner(1)];

#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top at the beginning
	// (0 sequences!)
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
      }

      // Do not pass a const reference since __key will be used as
      // local variable.
      void
      __delete_min_insert(_Tp __key, bool)
      {
        using std::swap;
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted, ties are broken by _M_source.
	    if (_M_comp(_M_losers[__pos]._M_key, __key)
        	|| (!_M_comp(__key, _M_losers[__pos]._M_key)
                    && _M_losers[__pos]._M_source < __source))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_source, __source);
		swap(_M_losers[__pos]._M_key, __key);
	      }
	  }

	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_key = __key;
      }
    };

  /**
   * @brief Non-Stable implementation of unguarded _LoserTree.
   *
   * Stable implementation is above.
   */
  template<typename _Tp, typename _Compare>
    class _LoserTreeUnguarded</* __stable == */false, _Tp, _Compare>
    : public _LoserTreeUnguardedBase<_Tp, _Compare>
    {
      typedef _LoserTreeUnguardedBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;

    public:
      _LoserTreeUnguarded(unsigned int __k, const _Tp __sentinel,
			  _Compare __comp = std::less<_Tp>())
      : _Base::_LoserTreeUnguardedBase(__k, __sentinel, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);

#if _GLIBCXX_ASSERTIONS
	    // If __left one is sentinel then __right one must be, too.
	    if (_M_losers[__left]._M_source == -1)
	      _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1);
#endif

	    if (!_M_comp(_M_losers[__right]._M_key,
			 _M_losers[__left]._M_key))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void
      __init()
      {
	_M_losers[0] = _M_losers[__init_winner(1)];

#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top at the beginning
	// (0 sequences!)
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
      }

      // Do not pass a const reference since __key will be used as
      // local variable.
      void
      __delete_min_insert(_Tp __key, bool)
      {
        using std::swap;
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted.
	    if (_M_comp(_M_losers[__pos]._M_key, __key))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_source, __source);
		swap(_M_losers[__pos]._M_key, __key);
	      }
	  }

	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_key = __key;
      }
    };

  /** @brief Unguarded loser tree, keeping only pointers to the
  * elements in the tree structure.
  *
  *  No guarding is done, therefore not a single input sequence must
  *  run empty.  This is a very fast variant.
  */
  template<typename _Tp, typename _Compare>
    class _LoserTreePointerUnguardedBase
    {
    protected:
      struct _Loser
      {
	int _M_source;
	const _Tp* _M_keyp;
      };

      unsigned int _M_ik, _M_k, _M_offset;
      _Loser* _M_losers;
      _Compare _M_comp;

    public:

      _LoserTreePointerUnguardedBase(unsigned int __k, const _Tp& __sentinel,
				     _Compare __comp = std::less<_Tp>())
      : _M_comp(__comp)
      {
	_M_ik = __k;

	// Next greater power of 2.
	_M_k = 1 << (__rd_log2(_M_ik - 1) + 1);
	_M_offset = _M_k;
	// Avoid default-constructing _M_losers[]._M_key
	_M_losers = new _Loser[2 * _M_k];

	for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i)
	  {
	    _M_losers[__i]._M_keyp = &__sentinel;
	    _M_losers[__i]._M_source = -1;
	  }
      }

      ~_LoserTreePointerUnguardedBase()
      { delete[] _M_losers; }

      int
      __get_min_source()
      {
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
	return _M_losers[0]._M_source;
      }

      void
      __insert_start(const _Tp& __key, int __source, bool)
      {
	unsigned int __pos = _M_k + __source;

	_M_losers[__pos]._M_keyp = &__key;
	_M_losers[__pos]._M_source = __source;
      }
    };

  /**
   * @brief Stable unguarded _LoserTree variant storing pointers.
   *
   * Unstable variant is implemented below using partial specialization.
   */
  template<bool __stable/* default == true */, typename _Tp, typename _Compare>
    class _LoserTreePointerUnguarded
    : public _LoserTreePointerUnguardedBase<_Tp, _Compare>
    {
      typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;

    public:
      _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel,
				 _Compare __comp = std::less<_Tp>())
      : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);
	    if (!_M_comp(*_M_losers[__right]._M_keyp,
			 *_M_losers[__left]._M_keyp))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void
      __init()
      {
	_M_losers[0] = _M_losers[__init_winner(1)];

#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top at the beginning
	// (0 sequences!)
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
      }

      void
      __delete_min_insert(const _Tp& __key, bool __sup)
      {
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	const _Tp* __keyp = &__key;
	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted, ties are broken by _M_source.
	    if (_M_comp(*_M_losers[__pos]._M_keyp, *__keyp)
		|| (!_M_comp(*__keyp, *_M_losers[__pos]._M_keyp)
		    && _M_losers[__pos]._M_source < __source))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_source, __source);
		std::swap(_M_losers[__pos]._M_keyp, __keyp);
	      }
	  }

	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_keyp = __keyp;
      }
    };

  /**
   * @brief Unstable unguarded _LoserTree variant storing pointers.
   *
   * Stable variant is above.
   */
  template<typename _Tp, typename _Compare>
    class _LoserTreePointerUnguarded</* __stable == */false, _Tp, _Compare>
    : public _LoserTreePointerUnguardedBase<_Tp, _Compare>
    {
      typedef _LoserTreePointerUnguardedBase<_Tp, _Compare> _Base;
      using _Base::_M_k;
      using _Base::_M_losers;

  public:
      _LoserTreePointerUnguarded(unsigned int __k, const _Tp& __sentinel,
				 _Compare __comp = std::less<_Tp>())
      : _Base::_LoserTreePointerUnguardedBase(__k, __sentinel, __comp)
      { }

      unsigned int
      __init_winner(unsigned int __root)
      {
	if (__root >= _M_k)
	  return __root;
	else
	  {
	    unsigned int __left = __init_winner(2 * __root);
	    unsigned int __right = __init_winner(2 * __root + 1);

#if _GLIBCXX_ASSERTIONS
	    // If __left one is sentinel then __right one must be, too.
	    if (_M_losers[__left]._M_source == -1)
	      _GLIBCXX_PARALLEL_ASSERT(_M_losers[__right]._M_source == -1);
#endif

	    if (!_M_comp(*_M_losers[__right]._M_keyp,
			 *_M_losers[__left]._M_keyp))
	      {
		// Left one is less or equal.
		_M_losers[__root] = _M_losers[__right];
		return __left;
	      }
	    else
	      {
		// Right one is less.
		_M_losers[__root] = _M_losers[__left];
		return __right;
	      }
	  }
      }

      void
      __init()
      {
	_M_losers[0] = _M_losers[__init_winner(1)];

#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top at the beginning
	// (0 sequences!)
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif
      }

      void
      __delete_min_insert(const _Tp& __key, bool __sup)
      {
#if _GLIBCXX_ASSERTIONS
	// no dummy sequence can ever be at the top!
	_GLIBCXX_PARALLEL_ASSERT(_M_losers[0]._M_source != -1);
#endif

	const _Tp* __keyp = &__key;
	int __source = _M_losers[0]._M_source;
	for (unsigned int __pos = (_M_k + __source) / 2; __pos > 0;
	     __pos /= 2)
	  {
	    // The smaller one gets promoted.
	    if (_M_comp(*(_M_losers[__pos]._M_keyp), *__keyp))
	      {
		// The other one is smaller.
		std::swap(_M_losers[__pos]._M_source, __source);
		std::swap(_M_losers[__pos]._M_keyp, __keyp);
	      }
	  }

	_M_losers[0]._M_source = __source;
	_M_losers[0]._M_keyp = __keyp;
      }
    };
} // namespace __gnu_parallel

#endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */
