3 // Copyright (C) 2007 Free Software Foundation, Inc.
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 2, or (at your option) any later
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.
16 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction. Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License. This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
31 /** @file parallel/losertree.h
32 * @brief Many generic loser tree variants.
33 * This file is a GNU parallel extension to the Standard C++ Library.
36 // Written by Johannes Singler.
38 #ifndef _GLIBCXX_PARALLEL_LOSERTREE_H
39 #define _GLIBCXX_PARALLEL_LOSERTREE_H 1
43 #include <bits/stl_algobase.h>
44 #include <parallel/features.h>
45 #include <parallel/base.h>
47 namespace __gnu_parallel
50 #if _GLIBCXX_LOSER_TREE_EXPLICIT
52 /** @brief Guarded loser tree, copying the whole element into the
55 * Guarding is done explicitly through two flags per element, inf
56 * and sup This is a quite slow variant.
58 template<typename T
, typename Comparator
= std::less
<T
> >
59 class LoserTreeExplicit
64 // The relevant element.
67 // Is this an infimum or supremum element?
70 // Number of the sequence the element comes from.
74 unsigned int size
, offset
;
79 inline LoserTreeExplicit(unsigned int _size
, Comparator _comp
= std::less
<T
>()) : comp(_comp
)
83 losers
= new Loser
[size
];
84 for (unsigned int l
= 0; l
< size
; l
++)
86 //losers[l].key = ... stays unset
88 losers
[l
].sup
= false;
89 //losers[l].source = -1; //sentinel
93 inline ~LoserTreeExplicit()
101 { return losers
[0].source
; }
104 insert_start(T key
, int source
, bool sup
)
107 for (unsigned int pos
= (offset
+ source
) / 2; pos
> 0; pos
/= 2)
109 if ((!inf
&& !losers
[pos
].inf
&& !sup
&& !losers
[pos
].sup
&& comp(losers
[pos
].key
, key
)) || losers
[pos
].inf
|| sup
)
111 // The other one is smaller.
112 std::swap(losers
[pos
].key
, key
);
113 std::swap(losers
[pos
].inf
, inf
);
114 std::swap(losers
[pos
].sup
, sup
);
115 std::swap(losers
[pos
].source
, source
);
122 losers
[0].source
= source
;
129 delete_min_insert(T key
, bool sup
)
132 int source
= losers
[0].source
;
133 for (unsigned int pos
= (offset
+ source
) / 2; pos
> 0; pos
/= 2)
135 // The smaller one gets promoted.
136 if ((!inf
&& !losers
[pos
].inf
&& !sup
&& !losers
[pos
].sup
137 && comp(losers
[pos
].key
, key
))
138 || losers
[pos
].inf
|| sup
)
140 // The other one is smaller.
141 std::swap(losers
[pos
].key
, key
);
142 std::swap(losers
[pos
].inf
, inf
);
143 std::swap(losers
[pos
].sup
, sup
);
144 std::swap(losers
[pos
].source
, source
);
151 losers
[0].source
= source
;
155 insert_start_stable(T key
, int source
, bool sup
)
158 for (unsigned int pos
= (offset
+ source
) / 2; pos
> 0; pos
/= 2)
160 if ((!inf
&& !losers
[pos
].inf
&& !sup
&& !losers
[pos
].sup
&&
161 ((comp(losers
[pos
].key
, key
)) ||
162 (!comp(key
, losers
[pos
].key
) && losers
[pos
].source
< source
)))
163 || losers
[pos
].inf
|| sup
)
166 std::swap(losers
[pos
].key
, key
);
167 std::swap(losers
[pos
].inf
, inf
);
168 std::swap(losers
[pos
].sup
, sup
);
169 std::swap(losers
[pos
].source
, source
);
176 losers
[0].source
= source
;
183 delete_min_insert_stable(T key
, bool sup
)
186 int source
= losers
[0].source
;
187 for (unsigned int pos
= (offset
+ source
) / 2; pos
> 0; pos
/= 2)
189 if ((!inf
&& !losers
[pos
].inf
&& !sup
&& !losers
[pos
].sup
190 && ((comp(losers
[pos
].key
, key
)) ||
191 (!comp(key
, losers
[pos
].key
) && losers
[pos
].source
< source
)))
192 || losers
[pos
].inf
|| sup
)
194 std::swap(losers
[pos
].key
, key
);
195 std::swap(losers
[pos
].inf
, inf
);
196 std::swap(losers
[pos
].sup
, sup
);
197 std::swap(losers
[pos
].source
, source
);
204 losers
[0].source
= source
;
210 #if _GLIBCXX_LOSER_TREE
212 /** @brief Guarded loser tree, either copying the whole element into
213 * the tree structure, or looking up the element via the index.
215 * Guarding is done explicitly through one flag sup per element,
216 * inf is not needed due to a better initialization routine. This
217 * is a well-performing variant.
219 template<typename T
, typename Comparator
= std::less
<T
> >
230 unsigned int ik
, k
, offset
;
235 inline LoserTree(unsigned int _k
, Comparator _comp
= std::less
<T
>())
240 // Next greater power of 2.
241 k
= 1 << (log2(ik
- 1) + 1);
243 losers
= new Loser
[k
* 2];
244 for (unsigned int i
= ik
- 1; i
< k
; i
++)
245 losers
[i
+ k
].sup
= true;
254 for (unsigned int i
= 0; i
< (k
* 2); i
++)
255 printf("%d %d from %d, %d\n", i
, losers
[i
].key
,
256 losers
[i
].source
, losers
[i
].sup
);
261 { return losers
[0].source
; }
264 insert_start(const T
& key
, int source
, bool sup
)
266 unsigned int pos
= k
+ source
;
268 losers
[pos
].sup
= sup
;
269 losers
[pos
].source
= source
;
270 losers
[pos
].key
= key
;
274 init_winner (unsigned int root
)
282 unsigned int left
= init_winner (2 * root
);
283 unsigned int right
= init_winner (2 * root
+ 1);
284 if (losers
[right
].sup
||
285 (!losers
[left
].sup
&& !comp(losers
[right
].key
, losers
[left
].key
)))
287 // Left one is less or equal.
288 losers
[root
] = losers
[right
];
292 { // Right one is less.
293 losers
[root
] = losers
[left
];
301 { losers
[0] = losers
[init_winner(1)]; }
303 // Do not pass const reference since key will be used as local variable.
305 delete_min_insert(T key
, bool sup
)
307 int source
= losers
[0].source
;
308 for (unsigned int pos
= (k
+ source
) / 2; pos
> 0; pos
/= 2)
310 // The smaller one gets promoted.
311 if (sup
|| (!losers
[pos
].sup
&& comp(losers
[pos
].key
, key
)))
313 // The other one is smaller.
314 std::swap(losers
[pos
].sup
, sup
);
315 std::swap(losers
[pos
].source
, source
);
316 std::swap(losers
[pos
].key
, key
);
321 losers
[0].source
= source
;
326 insert_start_stable(const T
& key
, int source
, bool sup
)
327 { return insert_start(key
, source
, sup
); }
330 init_winner_stable (unsigned int root
)
338 unsigned int left
= init_winner (2 * root
);
339 unsigned int right
= init_winner (2 * root
+ 1);
340 if ( losers
[right
].sup
||
341 (!losers
[left
].sup
&& !comp(losers
[right
].key
, losers
[left
].key
)))
343 // Left one is less or equal.
344 losers
[root
] = losers
[right
];
349 // Right one is less.
350 losers
[root
] = losers
[left
];
358 { losers
[0] = losers
[init_winner_stable(1)]; }
360 // Do not pass const reference since key will be used as local variable.
362 delete_min_insert_stable(T key
, bool sup
)
364 int source
= losers
[0].source
;
365 for (unsigned int pos
= (k
+ source
) / 2; pos
> 0; pos
/= 2)
367 // The smaller one gets promoted, ties are broken by source.
368 if ( (sup
&& (!losers
[pos
].sup
|| losers
[pos
].source
< source
)) ||
369 (!sup
&& !losers
[pos
].sup
&&
370 ((comp(losers
[pos
].key
, key
)) ||
371 (!comp(key
, losers
[pos
].key
) && losers
[pos
].source
< source
))))
373 // The other one is smaller.
374 std::swap(losers
[pos
].sup
, sup
);
375 std::swap(losers
[pos
].source
, source
);
376 std::swap(losers
[pos
].key
, key
);
381 losers
[0].source
= source
;
388 #if _GLIBCXX_LOSER_TREE_REFERENCE
390 /** @brief Guarded loser tree, either copying the whole element into
391 * the tree structure, or looking up the element via the index.
393 * Guarding is done explicitly through one flag sup per element,
394 * inf is not needed due to a better initialization routine. This
395 * is a well-performing variant.
397 template<typename T
, typename Comparator
= std::less
<T
> >
398 class LoserTreeReference
402 #define KEY(i) losers[i].key
403 #define KEY_SOURCE(i) key
405 #define KEY(i) keys[losers[i].source]
406 #define KEY_SOURCE(i) keys[i]
418 unsigned int ik
, k
, offset
;
426 inline LoserTreeReference(unsigned int _k
, Comparator _comp
= std::less
<T
>()) : comp(_comp
)
430 // Next greater power of 2.
431 k
= 1 << (log2(ik
- 1) + 1);
433 losers
= new Loser
[k
* 2];
437 for (unsigned int i
= ik
- 1; i
< k
; i
++)
438 losers
[i
+ k
].sup
= true;
441 inline ~LoserTreeReference()
452 for (unsigned int i
= 0; i
< (k
* 2); i
++)
453 printf("%d %d from %d, %d\n", i
, KEY(i
), losers
[i
].source
, losers
[i
].sup
);
458 { return losers
[0].source
; }
461 insert_start(T key
, int source
, bool sup
)
463 unsigned int pos
= k
+ source
;
465 losers
[pos
].sup
= sup
;
466 losers
[pos
].source
= source
;
471 init_winner(unsigned int root
)
479 unsigned int left
= init_winner (2 * root
);
480 unsigned int right
= init_winner (2 * root
+ 1);
481 if ( losers
[right
].sup
||
482 (!losers
[left
].sup
&& !comp(KEY(right
), KEY(left
))))
484 // Left one is less or equal.
485 losers
[root
] = losers
[right
];
490 // Right one is less.
491 losers
[root
] = losers
[left
];
500 losers
[0] = losers
[init_winner(1)];
504 delete_min_insert(T key
, bool sup
)
506 int source
= losers
[0].source
;
507 for (unsigned int pos
= (k
+ source
) / 2; pos
> 0; pos
/= 2)
509 // The smaller one gets promoted.
510 if (sup
|| (!losers
[pos
].sup
&& comp(KEY(pos
), KEY_SOURCE(source
))))
512 // The other one is smaller.
513 std::swap(losers
[pos
].sup
, sup
);
514 std::swap(losers
[pos
].source
, source
);
516 std::swap(KEY(pos
), KEY_SOURCE(source
));
522 losers
[0].source
= source
;
524 KEY(0) = KEY_SOURCE(source
);
529 insert_start_stable(T key
, int source
, bool sup
)
530 { return insert_start(key
, source
, sup
); }
533 init_winner_stable(unsigned int root
)
541 unsigned int left
= init_winner (2 * root
);
542 unsigned int right
= init_winner (2 * root
+ 1);
543 if (losers
[right
].sup
544 || (!losers
[left
].sup
&& !comp(KEY(right
), KEY(left
))))
546 // Left one is less or equal.
547 losers
[root
] = losers
[right
];
552 // Right one is less.
553 losers
[root
] = losers
[left
];
561 { losers
[0] = losers
[init_winner_stable(1)]; }
564 delete_min_insert_stable(T key
, bool sup
)
566 int source
= losers
[0].source
;
567 for (unsigned int pos
= (k
+ source
) / 2; pos
> 0; pos
/= 2)
569 // The smaller one gets promoted, ties are broken by source.
570 if ( (sup
&& (!losers
[pos
].sup
|| losers
[pos
].source
< source
)) ||
571 (!sup
&& !losers
[pos
].sup
&&
572 ((comp(KEY(pos
), KEY_SOURCE(source
))) ||
573 (!comp(KEY_SOURCE(source
), KEY(pos
)) && losers
[pos
].source
< source
))))
575 // The other one is smaller.
576 std::swap(losers
[pos
].sup
, sup
);
577 std::swap(losers
[pos
].source
, source
);
579 std::swap(KEY(pos
), KEY_SOURCE(source
));
585 losers
[0].source
= source
;
587 KEY(0) = KEY_SOURCE(source
);
596 #if _GLIBCXX_LOSER_TREE_POINTER
598 /** @brief Guarded loser tree, either copying the whole element into
599 the tree structure, or looking up the element via the index.
600 * Guarding is done explicitly through one flag sup per element,
601 * inf is not needed due to a better initialization routine.
602 * This is a well-performing variant.
604 template<typename T
, typename Comparator
= std::less
<T
> >
605 class LoserTreePointer
615 unsigned int ik
, k
, offset
;
620 inline LoserTreePointer(unsigned int _k
, Comparator _comp
= std::less
<T
>()) : comp(_comp
)
624 // Next greater power of 2.
625 k
= 1 << (log2(ik
- 1) + 1);
627 losers
= new Loser
[k
* 2];
628 for (unsigned int i
= ik
- 1; i
< k
; i
++)
629 losers
[i
+ k
].sup
= true;
632 inline ~LoserTreePointer()
638 for (unsigned int i
= 0; i
< (k
* 2); i
++)
639 printf("%d %d from %d, %d\n", i
, losers
[i
].keyp
, losers
[i
].source
, losers
[i
].sup
);
644 { return losers
[0].source
; }
647 insert_start(const T
& key
, int source
, bool sup
)
649 unsigned int pos
= k
+ source
;
651 losers
[pos
].sup
= sup
;
652 losers
[pos
].source
= source
;
653 losers
[pos
].keyp
= &key
;
657 init_winner(unsigned int root
)
665 unsigned int left
= init_winner (2 * root
);
666 unsigned int right
= init_winner (2 * root
+ 1);
667 if ( losers
[right
].sup
||
668 (!losers
[left
].sup
&& !comp(*losers
[right
].keyp
, *losers
[left
].keyp
)))
670 // Left one is less or equal.
671 losers
[root
] = losers
[right
];
676 // Right one is less.
677 losers
[root
] = losers
[left
];
685 { losers
[0] = losers
[init_winner(1)]; }
688 delete_min_insert(const T
& key
, bool sup
)
690 const T
* keyp
= &key
;
691 int source
= losers
[0].source
;
692 for (unsigned int pos
= (k
+ source
) / 2; pos
> 0; pos
/= 2)
694 // The smaller one gets promoted.
695 if (sup
|| (!losers
[pos
].sup
&& comp(*losers
[pos
].keyp
, *keyp
)))
697 // The other one is smaller.
698 std::swap(losers
[pos
].sup
, sup
);
699 std::swap(losers
[pos
].source
, source
);
700 std::swap(losers
[pos
].keyp
, keyp
);
705 losers
[0].source
= source
;
706 losers
[0].keyp
= keyp
;
710 insert_start_stable(const T
& key
, int source
, bool sup
)
711 { return insert_start(key
, source
, sup
); }
714 init_winner_stable(unsigned int root
)
722 unsigned int left
= init_winner (2 * root
);
723 unsigned int right
= init_winner (2 * root
+ 1);
724 if (losers
[right
].sup
725 || (!losers
[left
].sup
&& !comp(*losers
[right
].keyp
,
726 *losers
[left
].keyp
)))
728 // Left one is less or equal.
729 losers
[root
] = losers
[right
];
734 // Right one is less.
735 losers
[root
] = losers
[left
];
743 { losers
[0] = losers
[init_winner_stable(1)]; }
746 delete_min_insert_stable(const T
& key
, bool sup
)
748 const T
* keyp
= &key
;
749 int source
= losers
[0].source
;
750 for (unsigned int pos
= (k
+ source
) / 2; pos
> 0; pos
/= 2)
752 // The smaller one gets promoted, ties are broken by source.
753 if ( (sup
&& (!losers
[pos
].sup
|| losers
[pos
].source
< source
)) ||
754 (!sup
&& !losers
[pos
].sup
&&
755 ((comp(*losers
[pos
].keyp
, *keyp
)) ||
756 (!comp(*keyp
, *losers
[pos
].keyp
)
757 && losers
[pos
].source
< source
))))
759 // The other one is smaller.
760 std::swap(losers
[pos
].sup
, sup
);
761 std::swap(losers
[pos
].source
, source
);
762 std::swap(losers
[pos
].keyp
, keyp
);
767 losers
[0].source
= source
;
768 losers
[0].keyp
= keyp
;
774 #if _GLIBCXX_LOSER_TREE_UNGUARDED
776 /** @brief Unguarded loser tree, copying the whole element into the
779 * No guarding is done, therefore not a single input sequence must
780 * run empty. This is a very fast variant.
782 template<typename T
, typename Comparator
= std::less
<T
> >
783 class LoserTreeUnguarded
792 unsigned int ik
, k
, offset
;
793 unsigned int* mapping
;
798 map(unsigned int root
, unsigned int begin
, unsigned int end
)
800 if (begin
+ 1 == end
)
801 mapping
[begin
] = root
;
804 // Next greater or equal power of 2.
805 unsigned int left
= 1 << (log2(end
- begin
- 1));
806 map(root
* 2, begin
, begin
+ left
);
807 map(root
* 2 + 1, begin
+ left
, end
);
812 inline LoserTreeUnguarded(unsigned int _k
, Comparator _comp
= std::less
<T
>()) : comp(_comp
)
815 // Next greater or equal power of 2.
816 k
= 1 << (log2(ik
- 1) + 1);
818 losers
= new Loser
[k
+ ik
];
819 mapping
= new unsigned int[ik
];
823 inline ~LoserTreeUnguarded()
832 for (unsigned int i
= 0; i
< k
+ ik
; i
++)
833 printf("%d %d from %d\n", i
, losers
[i
].key
, losers
[i
].source
);
838 { return losers
[0].source
; }
841 insert_start(const T
& key
, int source
, bool)
843 unsigned int pos
= mapping
[source
];
844 losers
[pos
].source
= source
;
845 losers
[pos
].key
= key
;
849 init_winner(unsigned int root
, unsigned int begin
, unsigned int end
)
851 if (begin
+ 1 == end
)
852 return mapping
[begin
];
855 // Next greater or equal power of 2.
856 unsigned int division
= 1 << (log2(end
- begin
- 1));
857 unsigned int left
= init_winner(2 * root
, begin
, begin
+ division
);
858 unsigned int right
= init_winner(2 * root
+ 1, begin
+ division
, end
);
859 if (!comp(losers
[right
].key
, losers
[left
].key
))
861 // Left one is less or equal.
862 losers
[root
] = losers
[right
];
867 // Right one is less.
868 losers
[root
] = losers
[left
];
876 { losers
[0] = losers
[init_winner(1, 0, ik
)]; }
878 // Do not pass const reference since key will be used as local variable.
880 delete_min_insert(const T
& key
, bool)
883 T
& keyr
= losers
[0].key
;
884 int& source
= losers
[0].source
;
885 for (int pos
= mapping
[source
] / 2; pos
> 0; pos
/= 2)
887 // The smaller one gets promoted.
888 if (comp(losers
[pos
].key
, keyr
))
890 // The other one is smaller.
891 std::swap(losers
[pos
].source
, source
);
892 std::swap(losers
[pos
].key
, keyr
);
898 insert_start_stable(const T
& key
, int source
, bool)
899 { return insert_start(key
, source
, false); }
906 delete_min_insert_stable(const T
& key
, bool)
909 T
& keyr
= losers
[0].key
;
910 int& source
= losers
[0].source
;
911 for (int pos
= mapping
[source
] / 2; pos
> 0; pos
/= 2)
913 // The smaller one gets promoted, ties are broken by source.
914 if (comp(losers
[pos
].key
, keyr
)
915 || (!comp(keyr
, losers
[pos
].key
) && losers
[pos
].source
< source
))
917 // The other one is smaller.
918 std::swap(losers
[pos
].source
, source
);
919 std::swap(losers
[pos
].key
, keyr
);
927 #if _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
929 /** @brief Unguarded loser tree, keeping only pointers to the
930 * elements in the tree structure.
932 * No guarding is done, therefore not a single input sequence must
933 * run empty. This is a very fast variant.
935 template<typename T
, typename Comparator
= std::less
<T
> >
936 class LoserTreePointerUnguarded
945 unsigned int ik
, k
, offset
;
946 unsigned int* mapping
;
950 void map(unsigned int root
, unsigned int begin
, unsigned int end
)
952 if (begin
+ 1 == end
)
953 mapping
[begin
] = root
;
956 // Next greater or equal power of 2.
957 unsigned int left
= 1 << (log2(end
- begin
- 1));
958 map(root
* 2, begin
, begin
+ left
);
959 map(root
* 2 + 1, begin
+ left
, end
);
964 inline LoserTreePointerUnguarded(unsigned int _k
, Comparator _comp
= std::less
<T
>()) : comp(_comp
)
968 // Next greater power of 2.
969 k
= 1 << (log2(ik
- 1) + 1);
971 losers
= new Loser
[k
+ ik
];
972 mapping
= new unsigned int[ik
];
976 inline ~LoserTreePointerUnguarded()
985 for (unsigned int i
= 0; i
< k
+ ik
; i
++)
986 printf("%d %d from %d\n", i
, *losers
[i
].keyp
, losers
[i
].source
);
991 { return losers
[0].source
; }
994 insert_start(const T
& key
, int source
, bool)
996 unsigned int pos
= mapping
[source
];
997 losers
[pos
].source
= source
;
998 losers
[pos
].keyp
= &key
;
1002 init_winner(unsigned int root
, unsigned int begin
, unsigned int end
)
1004 if (begin
+ 1 == end
)
1005 return mapping
[begin
];
1008 // Next greater or equal power of 2.
1009 unsigned int division
= 1 << (log2(end
- begin
- 1));
1010 unsigned int left
= init_winner(2 * root
, begin
, begin
+ division
);
1011 unsigned int right
= init_winner(2 * root
+ 1, begin
+ division
, end
);
1012 if (!comp(*losers
[right
].keyp
, *losers
[left
].keyp
))
1014 // Left one is less or equal.
1015 losers
[root
] = losers
[right
];
1020 // Right one is less.
1021 losers
[root
] = losers
[left
];
1030 losers
[0] = losers
[init_winner(1, 0, ik
)];
1034 delete_min_insert(const T
& key
, bool)
1036 const T
* keyp
= &key
;
1037 int& source
= losers
[0].source
;
1038 for (int pos
= mapping
[source
] / 2; pos
> 0; pos
/= 2)
1040 // The smaller one gets promoted.
1041 if (comp(*losers
[pos
].keyp
, *keyp
))
1043 // The other one is smaller.
1044 std::swap(losers
[pos
].source
, source
);
1045 std::swap(losers
[pos
].keyp
, keyp
);
1049 losers
[0].keyp
= keyp
;
1053 insert_start_stable(const T
& key
, int source
, bool)
1054 { return insert_start(key
, source
, false); }
1061 delete_min_insert_stable(const T
& key
, bool)
1063 int& source
= losers
[0].source
;
1064 const T
* keyp
= &key
;
1065 for (int pos
= mapping
[source
] / 2; pos
> 0; pos
/= 2)
1067 // The smaller one gets promoted, ties are broken by source.
1068 if (comp(*losers
[pos
].keyp
, *keyp
)
1069 || (!comp(*keyp
, *losers
[pos
].keyp
)
1070 && losers
[pos
].source
< source
))
1072 // The other one is smaller.
1073 std::swap(losers
[pos
].source
, source
);
1074 std::swap(losers
[pos
].keyp
, keyp
);
1077 losers
[0].keyp
= keyp
;
1082 template<typename _ValueTp
, class Comparator
>
1083 struct loser_tree_traits
1085 #if _GLIBCXX_LOSER_TREE
1086 typedef LoserTree
<_ValueTp
, Comparator
> LT
;
1088 # if _GLIBCXX_LOSER_TREE_POINTER
1089 typedef LoserTreePointer
<_ValueTp
, Comparator
> LT
;
1091 # error Must define some type in losertree.h.
1096 template<typename _ValueTp
, class Comparator
>
1097 struct loser_tree_traits_unguarded
1099 #if _GLIBCXX_LOSER_TREE_UNGUARDED
1100 typedef LoserTreeUnguarded
<_ValueTp
, Comparator
> LT
;
1102 # if _GLIBCXX_LOSER_TREE_POINTER_UNGUARDED
1103 typedef LoserTreePointerUnguarded
<_ValueTp
, Comparator
> LT
;
1105 # error Must define some type in losertree.h.