Merge branch 'vendor/GCC44' into gcc441
[dragonfly.git] / contrib / gcc-4.4 / libstdc++-v3 / include / parallel / losertree.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
9 // version.
10
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file parallel/losertree.h
26 *  @brief Many generic loser tree variants.
27 *  This file is a GNU parallel extension to the Standard C++ Library.
28 */
29
30 // Written by Johannes Singler.
31
32 #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H
33 #define _GLIBCXX_PARALLEL_LOSERTREE_H 1
34
35 #include <functional>
36
37 #include <bits/stl_algobase.h>
38 #include <parallel/features.h>
39 #include <parallel/base.h>
40
41 namespace __gnu_parallel
42 {
43
44 /**
45  * @brief Guarded loser/tournament tree.
46  *
47  * The smallest element is at the top.
48  *
49  * Guarding is done explicitly through one flag sup per element,
50  * inf is not needed due to a better initialization routine.  This
51  * is a well-performing variant.
52  *
53  * @param T the element type
54  * @param Comparator the comparator to use, defaults to std::less<T>
55  */
56 template<typename T, typename Comparator>
57 class LoserTreeBase
58 {
59 protected:
60   /** @brief Internal representation of a LoserTree element. */
61   struct Loser
62   {
63     /** @brief flag, true iff this is a "maximum" sentinel. */
64     bool sup;
65     /** @brief index of the source sequence. */
66     int source;
67     /** @brief key of the element in the LoserTree. */
68     T key;
69   };
70
71   unsigned int ik, k, offset;
72
73   /** log_2{k} */
74   unsigned int _M_log_k;
75
76   /** @brief LoserTree elements. */
77   Loser* losers;
78
79   /** @brief Comparator to use. */
80   Comparator comp;
81
82   /**
83    * @brief State flag that determines whether the LoserTree is empty.
84    *
85    * Only used for building the LoserTree.
86    */
87   bool first_insert;
88
89 public:
90   /**
91    * @brief The constructor.
92    *
93    * @param _k The number of sequences to merge.
94    * @param _comp The comparator to use.
95    */
96   LoserTreeBase(unsigned int _k, Comparator _comp)
97   : comp(_comp)
98   {
99     ik = _k;
100
101     // Compute log_2{k} for the Loser Tree
102     _M_log_k = __log2(ik - 1) + 1;
103
104     // Next greater power of 2.
105     k = 1 << _M_log_k;
106     offset = k;
107
108     // Avoid default-constructing losers[].key
109     losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser)));
110     for (unsigned int i = ik - 1; i < k; ++i)
111       losers[i + k].sup = true;
112
113     first_insert = true;
114   }
115
116   /**
117    * @brief The destructor.
118    */
119   ~LoserTreeBase()
120   { ::operator delete(losers); }
121
122   /**
123    * @brief Initializes the sequence "source" with the element "key".
124    *
125    * @param key the element to insert
126    * @param source index of the source sequence
127    * @param sup flag that determines whether the value to insert is an
128    *   explicit supremum.
129    */
130   inline void
131   insert_start(const T& key, int source, bool sup)
132   {
133     unsigned int pos = k + source;
134
135     if(first_insert)
136       {
137         // Construct all keys, so we can easily deconstruct them.
138         for (unsigned int i = 0; i < (2 * k); ++i)
139           new(&(losers[i].key)) T(key);
140         first_insert = false;
141       }
142     else
143       new(&(losers[pos].key)) T(key);
144
145     losers[pos].sup = sup;
146     losers[pos].source = source;
147   }
148
149   /**
150    * @return the index of the sequence with the smallest element.
151    */
152   int get_min_source()
153   { return losers[0].source; }
154 };
155
156 /**
157  * @brief Stable LoserTree variant.
158  *
159  * Provides the stable implementations of insert_start, init_winner,
160  * init and delete_min_insert.
161  *
162  * Unstable variant is done using partial specialisation below.
163  */
164 template<bool stable/* default == true */, typename T, typename Comparator>
165 class LoserTree : public LoserTreeBase<T, Comparator>
166 {
167   typedef LoserTreeBase<T, Comparator> Base;
168   using Base::k;
169   using Base::losers;
170   using Base::first_insert;
171
172 public:
173   LoserTree(unsigned int _k, Comparator _comp)
174   : Base::LoserTreeBase(_k, _comp)
175   {}
176
177   unsigned int
178   init_winner(unsigned int root)
179   {
180     if (root >= k)
181       {
182         return root;
183       }
184     else
185       {
186         unsigned int left = init_winner (2 * root);
187         unsigned int right = init_winner (2 * root + 1);
188         if (losers[right].sup
189             || (!losers[left].sup
190               && !comp(losers[right].key, losers[left].key)))
191           {
192             // Left one is less or equal.
193             losers[root] = losers[right];
194             return left;
195           }
196         else
197           {
198             // Right one is less.
199             losers[root] = losers[left];
200             return right;
201           }
202       }
203   }
204
205   void init()
206   { losers[0] = losers[init_winner(1)]; }
207
208   /**
209    * @brief Delete the smallest element and insert a new element from
210    *   the previously smallest element's sequence.
211    *
212    * This implementation is stable.
213    */
214   // Do not pass a const reference since key will be used as local variable.
215   void delete_min_insert(T key, bool sup)
216   {
217 #if _GLIBCXX_ASSERTIONS
218     // no dummy sequence can ever be at the top!
219     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
220 #endif
221
222     int source = losers[0].source;
223     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
224       {
225         // The smaller one gets promoted, ties are broken by source.
226         if ((sup && (!losers[pos].sup || losers[pos].source < source))
227               || (!sup && !losers[pos].sup
228                 && ((comp(losers[pos].key, key))
229                   || (!comp(key, losers[pos].key)
230                     && losers[pos].source < source))))
231           {
232             // The other one is smaller.
233             std::swap(losers[pos].sup, sup);
234             std::swap(losers[pos].source, source);
235             std::swap(losers[pos].key, key);
236           }
237       }
238
239     losers[0].sup = sup;
240     losers[0].source = source;
241     losers[0].key = key;
242   }
243 };
244
245 /**
246  * @brief Unstable LoserTree variant.
247  *
248  * Stability (non-stable here) is selected with partial specialization.
249  */
250 template<typename T, typename Comparator>
251 class LoserTree</* stable == */false, T, Comparator> :
252     public LoserTreeBase<T, Comparator>
253 {
254   typedef LoserTreeBase<T, Comparator> Base;
255   using Base::_M_log_k;
256   using Base::k;
257   using Base::losers;
258   using Base::first_insert;
259
260 public:
261   LoserTree(unsigned int _k, Comparator _comp)
262   : Base::LoserTreeBase(_k, _comp)
263   {}
264
265   /**
266    * Computes the winner of the competition at position "root".
267    *
268    * Called recursively (starting at 0) to build the initial tree.
269    *
270    * @param root index of the "game" to start.
271    */
272   unsigned int
273   init_winner (unsigned int root)
274   {
275     if (root >= k)
276       {
277         return root;
278       }
279     else
280       {
281         unsigned int left = init_winner (2 * root);
282         unsigned int right = init_winner (2 * root + 1);
283         if (losers[right].sup ||
284             (!losers[left].sup
285               && !comp(losers[right].key, losers[left].key)))
286           {
287             // Left one is less or equal.
288             losers[root] = losers[right];
289             return left;
290           }
291         else
292           {
293             // Right one is less.
294             losers[root] = losers[left];
295             return right;
296           }
297       }
298   }
299
300   inline void
301   init()
302   { losers[0] = losers[init_winner(1)]; }
303
304   /**
305    * Delete the key smallest element and insert the element key instead.
306    *
307    * @param key the key to insert
308    * @param sup true iff key is an explicitly marked supremum
309    */
310   // Do not pass a const reference since key will be used as local variable.
311   inline void
312   delete_min_insert(T key, bool sup)
313   {
314 #if _GLIBCXX_ASSERTIONS
315     // no dummy sequence can ever be at the top!
316     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
317 #endif
318
319     int source = losers[0].source;
320     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
321     {
322         // The smaller one gets promoted.
323       if (sup || (!losers[pos].sup && comp(losers[pos].key, key)))
324       {
325             // The other one is smaller.
326         std::swap(losers[pos].sup, sup);
327         std::swap(losers[pos].source, source);
328         std::swap(losers[pos].key, key);
329       }
330     }
331
332     losers[0].sup = sup;
333     losers[0].source = source;
334     losers[0].key = key;
335   }
336 };
337
338
339 /**
340  * @brief Base class of Loser Tree implementation using pointers.
341  */
342 template<typename T, typename Comparator>
343 class LoserTreePointerBase
344 {
345 protected:
346   /** @brief Internal representation of LoserTree elements. */
347   struct Loser
348   {
349     bool sup;
350     int source;
351     const T* keyp;
352   };
353
354   unsigned int ik, k, offset;
355   Loser* losers;
356   Comparator comp;
357
358 public:
359   LoserTreePointerBase(unsigned int _k, Comparator _comp = std::less<T>())
360     : comp(_comp)
361   {
362     ik = _k;
363
364     // Next greater power of 2.
365     k = 1 << (__log2(ik - 1) + 1);
366     offset = k;
367     losers = new Loser[k * 2];
368     for (unsigned int i = ik - 1; i < k; i++)
369       losers[i + k].sup = true;
370   }
371
372   ~LoserTreePointerBase()
373   { ::operator delete[](losers); }
374
375   int get_min_source()
376   { return losers[0].source; }
377
378   void insert_start(const T& key, int source, bool sup)
379   {
380     unsigned int pos = k + source;
381
382     losers[pos].sup = sup;
383     losers[pos].source = source;
384     losers[pos].keyp = &key;
385   }
386 };
387
388 /**
389  * @brief Stable LoserTree implementation.
390  *
391  * The unstable variant is implemented using partial instantiation below.
392  */
393 template<bool stable/* default == true */, typename T, typename Comparator>
394 class LoserTreePointer : public LoserTreePointerBase<T, Comparator>
395 {
396   typedef LoserTreePointerBase<T, Comparator> Base;
397   using Base::k;
398   using Base::losers;
399
400 public:
401   LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>())
402     : Base::LoserTreePointerBase(_k, _comp)
403   {}
404
405   unsigned int
406   init_winner(unsigned int root)
407   {
408     if (root >= k)
409       {
410         return root;
411       }
412     else
413       {
414         unsigned int left = init_winner (2 * root);
415         unsigned int right = init_winner (2 * root + 1);
416         if (losers[right].sup
417             || (!losers[left].sup && !comp(*losers[right].keyp,
418                                           *losers[left].keyp)))
419           {
420             // Left one is less or equal.
421             losers[root] = losers[right];
422             return left;
423           }
424         else
425           {
426             // Right one is less.
427             losers[root] = losers[left];
428             return right;
429           }
430       }
431   }
432
433   void init()
434   { losers[0] = losers[init_winner(1)]; }
435
436   void delete_min_insert(const T& key, bool sup)
437   {
438 #if _GLIBCXX_ASSERTIONS
439     // no dummy sequence can ever be at the top!
440     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
441 #endif
442
443     const T* keyp = &key;
444     int source = losers[0].source;
445     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
446       {
447         // The smaller one gets promoted, ties are broken by source.
448         if ((sup && (!losers[pos].sup || losers[pos].source < source)) ||
449               (!sup && !losers[pos].sup &&
450               ((comp(*losers[pos].keyp, *keyp)) ||
451                 (!comp(*keyp, *losers[pos].keyp)
452                 && losers[pos].source < source))))
453           {
454             // The other one is smaller.
455             std::swap(losers[pos].sup, sup);
456             std::swap(losers[pos].source, source);
457             std::swap(losers[pos].keyp, keyp);
458           }
459       }
460
461     losers[0].sup = sup;
462     losers[0].source = source;
463     losers[0].keyp = keyp;
464   }
465 };
466
467 /**
468  * @brief Unstable LoserTree implementation.
469  *
470  * The stable variant is above.
471  */
472 template<typename T, typename Comparator>
473 class LoserTreePointer</* stable == */false, T, Comparator> :
474     public LoserTreePointerBase<T, Comparator>
475 {
476   typedef LoserTreePointerBase<T, Comparator> Base;
477   using Base::k;
478   using Base::losers;
479
480 public:
481   LoserTreePointer(unsigned int _k, Comparator _comp = std::less<T>())
482     : Base::LoserTreePointerBase(_k, _comp)
483   {}
484
485   unsigned int
486   init_winner(unsigned int root)
487   {
488     if (root >= k)
489       {
490         return root;
491       }
492     else
493       {
494         unsigned int left = init_winner (2 * root);
495         unsigned int right = init_winner (2 * root + 1);
496         if (losers[right].sup
497               || (!losers[left].sup
498                 && !comp(*losers[right].keyp, *losers[left].keyp)))
499           {
500             // Left one is less or equal.
501             losers[root] = losers[right];
502             return left;
503           }
504         else
505           {
506             // Right one is less.
507             losers[root] = losers[left];
508             return right;
509           }
510       }
511   }
512
513   void init()
514   { losers[0] = losers[init_winner(1)]; }
515
516   void delete_min_insert(const T& key, bool sup)
517   {
518 #if _GLIBCXX_ASSERTIONS
519     // no dummy sequence can ever be at the top!
520     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
521 #endif
522
523     const T* keyp = &key;
524     int source = losers[0].source;
525     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
526       {
527         // The smaller one gets promoted.
528         if (sup || (!losers[pos].sup && comp(*losers[pos].keyp, *keyp)))
529           {
530             // The other one is smaller.
531             std::swap(losers[pos].sup, sup);
532             std::swap(losers[pos].source, source);
533             std::swap(losers[pos].keyp, keyp);
534           }
535       }
536
537     losers[0].sup = sup;
538     losers[0].source = source;
539     losers[0].keyp = keyp;
540   }
541 };
542
543 /** @brief Base class for unguarded LoserTree implementation.
544  * 
545  * The whole element is copied into the tree structure.
546  *
547  * No guarding is done, therefore not a single input sequence must
548  * run empty.  Unused sequence heads are marked with a sentinel which
549  * is &gt; all elements that are to be merged.
550  *
551  * This is a very fast variant.
552  */
553 template<typename T, typename Comparator>
554 class LoserTreeUnguardedBase
555 {
556 protected:
557   struct Loser
558   {
559     int source;
560     T key;
561   };
562
563   unsigned int ik, k, offset;
564   Loser* losers;
565   Comparator comp;
566
567 public:
568   inline
569   LoserTreeUnguardedBase(unsigned int _k, const T _sentinel,
570                          Comparator _comp = std::less<T>())
571     : comp(_comp)
572   {
573     ik = _k;
574
575     // Next greater power of 2.
576     k = 1 << (__log2(ik - 1) + 1);
577     offset = k;
578     // Avoid default-constructing losers[].key
579     losers = static_cast<Loser*>(::operator new(2 * k * sizeof(Loser)));
580
581     for (unsigned int i = k + ik - 1; i < (2 * k); ++i)
582       {
583         losers[i].key = _sentinel;
584         losers[i].source = -1;
585       }
586   }
587
588   inline ~LoserTreeUnguardedBase()
589   { ::operator delete(losers); }
590
591   inline int
592   get_min_source()
593   {
594 #if _GLIBCXX_ASSERTIONS
595     // no dummy sequence can ever be at the top!
596     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
597 #endif
598     return losers[0].source;
599   }
600
601   inline void
602   insert_start(const T& key, int source, bool)
603   {
604     unsigned int pos = k + source;
605
606     new(&(losers[pos].key)) T(key);
607     losers[pos].source = source;
608   }
609 };
610
611 /**
612  * @brief Stable implementation of unguarded LoserTree.
613  *
614  * Unstable variant is selected below with partial specialization.
615  */
616 template<bool stable/* default == true */, typename T, typename Comparator>
617 class LoserTreeUnguarded : public LoserTreeUnguardedBase<T, Comparator>
618 {
619   typedef LoserTreeUnguardedBase<T, Comparator> Base;
620   using Base::k;
621   using Base::losers;
622
623 public:
624   LoserTreeUnguarded(unsigned int _k, const T _sentinel,
625                      Comparator _comp = std::less<T>())
626     : Base::LoserTreeUnguardedBase(_k, _sentinel, _comp)
627   {}
628
629   unsigned int
630   init_winner(unsigned int root)
631   {
632     if (root >= k)
633       {
634         return root;
635       }
636     else
637       {
638         unsigned int left = init_winner (2 * root);
639         unsigned int right = init_winner (2 * root + 1);
640         if (!comp(losers[right].key, losers[left].key))
641           {
642             // Left one is less or equal.
643             losers[root] = losers[right];
644             return left;
645           }
646         else
647           {
648             // Right one is less.
649             losers[root] = losers[left];
650             return right;
651           }
652       }
653   }
654
655   inline void
656   init()
657   {
658     losers[0] = losers[init_winner(1)];
659
660 #if _GLIBCXX_ASSERTIONS
661     // no dummy sequence can ever be at the top at the beginning (0 sequences!)
662     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
663 #endif
664   }
665
666   // Do not pass a const reference since key will be used as local variable.
667   inline void
668   delete_min_insert(T key, bool)
669   {
670 #if _GLIBCXX_ASSERTIONS
671     // no dummy sequence can ever be at the top!
672     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
673 #endif
674
675     int source = losers[0].source;
676     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
677       {
678         // The smaller one gets promoted, ties are broken by source.
679         if (comp(losers[pos].key, key)
680               || (!comp(key, losers[pos].key) && losers[pos].source < source))
681           {
682             // The other one is smaller.
683             std::swap(losers[pos].source, source);
684             std::swap(losers[pos].key, key);
685           }
686       }
687
688     losers[0].source = source;
689     losers[0].key = key;
690   }
691 };
692
693 /**
694  * @brief Non-Stable implementation of unguarded LoserTree.
695  *
696  * Stable implementation is above.
697  */
698 template<typename T, typename Comparator>
699 class LoserTreeUnguarded</* stable == */false, T, Comparator> :
700     public LoserTreeUnguardedBase<T, Comparator>
701 {
702   typedef LoserTreeUnguardedBase<T, Comparator> Base;
703   using Base::k;
704   using Base::losers;
705
706 public:
707   LoserTreeUnguarded(unsigned int _k, const T _sentinel,
708                      Comparator _comp = std::less<T>())
709     : Base::LoserTreeUnguardedBase(_k, _sentinel, _comp)
710   {}
711
712   unsigned int
713   init_winner (unsigned int root)
714   {
715     if (root >= k)
716       {
717         return root;
718       }
719     else
720       {
721         unsigned int left = init_winner (2 * root);
722         unsigned int right = init_winner (2 * root + 1);
723
724 #if _GLIBCXX_ASSERTIONS
725         // If left one is sentinel then right one must be, too.
726         if (losers[left].source == -1)
727           _GLIBCXX_PARALLEL_ASSERT(losers[right].source == -1);
728 #endif
729
730         if (!comp(losers[right].key, losers[left].key))
731           {
732             // Left one is less or equal.
733             losers[root] = losers[right];
734             return left;
735           }
736         else
737           {
738             // Right one is less.
739             losers[root] = losers[left];
740             return right;
741           }
742       }
743   }
744
745   inline void
746   init()
747   {
748     losers[0] = losers[init_winner(1)];
749
750 #if _GLIBCXX_ASSERTIONS
751     // no dummy sequence can ever be at the top at the beginning (0 sequences!)
752     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
753 #endif
754   }
755
756   // Do not pass a const reference since key will be used as local variable.
757   inline void
758   delete_min_insert(T key, bool)
759   {
760 #if _GLIBCXX_ASSERTIONS
761     // no dummy sequence can ever be at the top!
762     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
763 #endif
764
765     int source = losers[0].source;
766     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
767       {
768         // The smaller one gets promoted.
769         if (comp(losers[pos].key, key))
770           {
771             // The other one is smaller.
772             std::swap(losers[pos].source, source);
773             std::swap(losers[pos].key, key);
774           }
775       }
776
777     losers[0].source = source;
778     losers[0].key = key;
779   }
780 };
781
782 /** @brief Unguarded loser tree, keeping only pointers to the
783 * elements in the tree structure.
784 *
785 *  No guarding is done, therefore not a single input sequence must
786 *  run empty.  This is a very fast variant.
787 */
788 template<typename T, typename Comparator>
789 class LoserTreePointerUnguardedBase
790 {
791 protected:
792   struct Loser
793   {
794     int source;
795     const T* keyp;
796   };
797
798   unsigned int ik, k, offset;
799   Loser* losers;
800   Comparator comp;
801
802 public:
803
804   inline
805   LoserTreePointerUnguardedBase(unsigned int _k, const T& _sentinel,
806       Comparator _comp = std::less<T>())
807     : comp(_comp)
808   {
809     ik = _k;
810
811     // Next greater power of 2.
812     k = 1 << (__log2(ik - 1) + 1);
813     offset = k;
814     // Avoid default-constructing losers[].key
815     losers = new Loser[2 * k];
816
817     for (unsigned int i = k + ik - 1; i < (2 * k); ++i)
818       {
819         losers[i].keyp = &_sentinel;
820         losers[i].source = -1;
821       }
822   }
823
824   inline ~LoserTreePointerUnguardedBase()
825   { delete[] losers; }
826
827   inline int
828   get_min_source()
829   {
830 #if _GLIBCXX_ASSERTIONS
831     // no dummy sequence can ever be at the top!
832     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
833 #endif
834     return losers[0].source;
835   }
836
837   inline void
838   insert_start(const T& key, int source, bool)
839   {
840     unsigned int pos = k + source;
841
842     losers[pos].keyp = &key;
843     losers[pos].source = source;
844   }
845 };
846
847 /**
848  * @brief Stable unguarded LoserTree variant storing pointers.
849  *
850  * Unstable variant is implemented below using partial specialization.
851  */
852 template<bool stable/* default == true */, typename T, typename Comparator>
853 class LoserTreePointerUnguarded :
854     public LoserTreePointerUnguardedBase<T, Comparator>
855 {
856   typedef LoserTreePointerUnguardedBase<T, Comparator> Base;
857   using Base::k;
858   using Base::losers;
859
860 public:
861   LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel,
862       Comparator _comp = std::less<T>())
863     : Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
864   {}
865
866   unsigned int
867   init_winner(unsigned int root)
868   {
869     if (root >= k)
870       {
871         return root;
872       }
873     else
874       {
875         unsigned int left = init_winner (2 * root);
876         unsigned int right = init_winner (2 * root + 1);
877         if (!comp(*losers[right].keyp, *losers[left].keyp))
878           {
879             // Left one is less or equal.
880             losers[root] = losers[right];
881             return left;
882           }
883         else
884           {
885             // Right one is less.
886             losers[root] = losers[left];
887             return right;
888           }
889       }
890   }
891
892   inline void
893   init()
894   {
895     losers[0] = losers[init_winner(1)];
896
897 #if _GLIBCXX_ASSERTIONS
898     // no dummy sequence can ever be at the top at the beginning (0 sequences!)
899     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
900 #endif
901   }
902
903   inline void
904   delete_min_insert(const T& key, bool sup)
905   {
906 #if _GLIBCXX_ASSERTIONS
907     // no dummy sequence can ever be at the top!
908     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
909 #endif
910
911     const T* keyp = &key;
912     int source = losers[0].source;
913     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
914       {
915         // The smaller one gets promoted, ties are broken by source.
916         if (comp(*losers[pos].keyp, *keyp)
917           || (!comp(*keyp, *losers[pos].keyp) && losers[pos].source < source))
918           {
919             // The other one is smaller.
920             std::swap(losers[pos].source, source);
921             std::swap(losers[pos].keyp, keyp);
922           }
923       }
924
925     losers[0].source = source;
926     losers[0].keyp = keyp;
927   }
928 };
929
930 /**
931  * @brief Unstable unguarded LoserTree variant storing pointers.
932  *
933  * Stable variant is above.
934  */
935 template<typename T, typename Comparator>
936 class LoserTreePointerUnguarded</* stable == */false, T, Comparator> :
937     public LoserTreePointerUnguardedBase<T, Comparator>
938 {
939   typedef LoserTreePointerUnguardedBase<T, Comparator> Base;
940   using Base::k;
941   using Base::losers;
942
943 public:
944   LoserTreePointerUnguarded(unsigned int _k, const T& _sentinel,
945       Comparator _comp = std::less<T>())
946     : Base::LoserTreePointerUnguardedBase(_k, _sentinel, _comp)
947   {}
948
949   unsigned int
950   init_winner(unsigned int root)
951   {
952     if (root >= k)
953       {
954         return root;
955       }
956     else
957       {
958         unsigned int left = init_winner (2 * root);
959         unsigned int right = init_winner (2 * root + 1);
960
961 #if _GLIBCXX_ASSERTIONS
962         // If left one is sentinel then right one must be, too.
963         if (losers[left].source == -1)
964           _GLIBCXX_PARALLEL_ASSERT(losers[right].source == -1);
965 #endif
966
967         if (!comp(*losers[right].keyp, *losers[left].keyp))
968           {
969             // Left one is less or equal.
970             losers[root] = losers[right];
971             return left;
972           }
973         else
974           {
975             // Right one is less.
976             losers[root] = losers[left];
977             return right;
978           }
979       }
980   }
981
982   inline void
983   init()
984   {
985     losers[0] = losers[init_winner(1)];
986
987 #if _GLIBCXX_ASSERTIONS
988     // no dummy sequence can ever be at the top at the beginning (0 sequences!)
989     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
990 #endif
991   }
992
993   inline void
994   delete_min_insert(const T& key, bool sup)
995   {
996 #if _GLIBCXX_ASSERTIONS
997     // no dummy sequence can ever be at the top!
998     _GLIBCXX_PARALLEL_ASSERT(losers[0].source != -1);
999 #endif
1000
1001     const T* keyp = &key;
1002     int source = losers[0].source;
1003     for (unsigned int pos = (k + source) / 2; pos > 0; pos /= 2)
1004       {
1005         // The smaller one gets promoted.
1006         if (comp(*(losers[pos].keyp), *keyp))
1007           {
1008             // The other one is smaller.
1009             std::swap(losers[pos].source, source);
1010             std::swap(losers[pos].keyp, keyp);
1011           }
1012       }
1013
1014     losers[0].source = source;
1015     losers[0].keyp = keyp;
1016   }
1017 };
1018
1019 } // namespace __gnu_parallel
1020
1021 #endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */