Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 18.116.67.226
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
usr /
include /
c++ /
9 /
parallel /
[ HOME SHELL ]
Name
Size
Permission
Action
algo.h
78.15
KB
-rw-r--r--
algobase.h
16.75
KB
-rw-r--r--
algorithm
1.35
KB
-rw-r--r--
algorithmfwd.h
31.45
KB
-rw-r--r--
balanced_quicksort.h
16.55
KB
-rw-r--r--
base.h
12.08
KB
-rw-r--r--
basic_iterator.h
1.55
KB
-rw-r--r--
checkers.h
2.25
KB
-rw-r--r--
compatibility.h
3.7
KB
-rw-r--r--
compiletime_settings.h
2.8
KB
-rw-r--r--
equally_split.h
3.28
KB
-rw-r--r--
features.h
3.46
KB
-rw-r--r--
find.h
13.27
KB
-rw-r--r--
find_selectors.h
6.83
KB
-rw-r--r--
for_each.h
3.85
KB
-rw-r--r--
for_each_selectors.h
10.32
KB
-rw-r--r--
iterator.h
5.54
KB
-rw-r--r--
list_partition.h
6.39
KB
-rw-r--r--
losertree.h
27.92
KB
-rw-r--r--
merge.h
9.35
KB
-rw-r--r--
multiseq_selection.h
21.56
KB
-rw-r--r--
multiway_merge.h
68.88
KB
-rw-r--r--
multiway_mergesort.h
14.91
KB
-rw-r--r--
numeric
20.23
KB
-rw-r--r--
numericfwd.h
7.32
KB
-rw-r--r--
omp_loop.h
3.94
KB
-rw-r--r--
omp_loop_static.h
4.01
KB
-rw-r--r--
par_loop.h
4.45
KB
-rw-r--r--
parallel.h
1.54
KB
-rw-r--r--
partial_sum.h
7.3
KB
-rw-r--r--
partition.h
14.61
KB
-rw-r--r--
queue.h
5.41
KB
-rw-r--r--
quicksort.h
5.98
KB
-rw-r--r--
random_number.h
4.13
KB
-rw-r--r--
random_shuffle.h
18.24
KB
-rw-r--r--
search.h
5.26
KB
-rw-r--r--
set_operations.h
14.25
KB
-rw-r--r--
settings.h
12.17
KB
-rw-r--r--
sort.h
7.53
KB
-rw-r--r--
tags.h
5.84
KB
-rw-r--r--
types.h
3.63
KB
-rw-r--r--
unique_copy.h
6.02
KB
-rw-r--r--
workstealing.h
9.38
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : losertree.h
// -*- C++ -*- // Copyright (C) 2007-2019 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() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::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 destruct them. for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) ::new(&(_M_losers[__i]._M_key)) _Tp(__key); _M_first_insert = false; } else _M_losers[__pos]._M_key = __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_comp; 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_PARALLEL_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_comp; 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_PARALLEL_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() { 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_comp; 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_PARALLEL_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_comp; 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_PARALLEL_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 > 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 = 0; __i < _M_k; ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } for (unsigned int __i = _M_k + _M_ik - 1; __i < (2 * _M_k); ++__i) { ::new(&(_M_losers[__i]._M_key)) _Tp(__sentinel); _M_losers[__i]._M_source = -1; } } ~_LoserTreeUnguardedBase() { for (unsigned int __i = 0; __i < (2 * _M_k); ++__i) _M_losers[__i].~_Loser(); ::operator delete(_M_losers); } int __get_min_source() { #if _GLIBCXX_PARALLEL_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_comp; 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_PARALLEL_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_PARALLEL_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_comp; 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_PARALLEL_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_PARALLEL_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_PARALLEL_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_PARALLEL_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_comp; 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_PARALLEL_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_PARALLEL_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_comp; 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_PARALLEL_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_PARALLEL_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_PARALLEL_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 */
Close