/** -*- C++ -*- ** ** KAI C++ Compiler ** ** Copyright (C) 1996-2001 Intel Corp. All rights reserved. ** ** The heap functions are split out of algorithm to speed up compilation of queue. ** Queue only needs the heap functions from algorithm. **/ /** ** Lib++ : The Modena C++ Standard Library, ** Version 2.4, October 1997 ** ** Copyright (c) 1995-1997 Modena Software Inc. **/ #ifndef __KAI_HEAP #define __KAI_HEAP #include namespace __kai { // For implementation of class priority_queue and Heap operations template void __push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value) { Distance parent = (holeIndex - 1) / 2; while (holeIndex > topIndex && *(first + parent) < value) { *(first + holeIndex) = *(first + parent); holeIndex = parent; parent = (holeIndex - 1) / 2; } *(first + holeIndex) = value; } template void __push_heap(RandomAccessIterator first, Distance holeIndex, Distance topIndex, T value, Compare comp) { Distance parent = (holeIndex - 1) / 2; while (holeIndex > topIndex && comp(* (first + parent), value)) { *(first + holeIndex) = *(first + parent); holeIndex = parent; parent = (holeIndex - 1) / 2; } *(first + holeIndex) = value; } template inline void __adjust_heap(RandomAccessIterator first, Distance holeIndex, Distance len, T value) { Distance topIndex = holeIndex; Distance secondChild = 2 * holeIndex + 2; while (secondChild < len) { if (*(first + secondChild) < *(first + (secondChild - 1))) secondChild--; *(first + holeIndex) = *(first + secondChild); holeIndex = secondChild; secondChild = 2 * (secondChild + 1); } if (secondChild == len) { *(first + holeIndex) = *(first + (secondChild - 1)); holeIndex = secondChild - 1; } __push_heap(first, holeIndex, topIndex, value); } template void __adjust_heap (RandomAccessIterator first, Distance holeIndex, Distance len, T value, Compare comp) { Distance topIndex = holeIndex; Distance secondChild = 2 * holeIndex + 2; while (secondChild < len) { if (comp (* (first + secondChild), * (first + (secondChild - 1)))) secondChild--; *(first + holeIndex) = *(first + secondChild); holeIndex = secondChild; secondChild = 2 * (secondChild + 1); } if (secondChild == len) { *(first + holeIndex) = *(first + (secondChild - 1)); holeIndex = secondChild - 1; } __push_heap (first, holeIndex, topIndex, value, comp); } template inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value) { typedef typename std::iterator_traits::difference_type Distance; *result = *first; __adjust_heap(first, Distance(0), Distance(last - first), value); } template inline void __pop_heap(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIterator result, T value, Compare comp ) { typedef typename std::iterator_traits::difference_type Distance; *result = *first; __adjust_heap(first, Distance(0), Distance(last - first), value, comp); } } // namespace __kai namespace std { // Section 25.3.6 -- Heap operations // Section 25.3.6.1 -- push_heap template inline void push_heap(RandomAccessIterator first, RandomAccessIterator last) { typedef typename iterator_traits::difference_type Distance; typedef typename iterator_traits::value_type Value; __kai::__push_heap(first, Distance((last - first) - 1), Distance(0), Value(* (last - 1))); } template inline void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { typedef typename iterator_traits::difference_type Distance; typedef typename iterator_traits::value_type Value; __kai::__push_heap(first, Distance((last - first) - 1), Distance(0), Value(* (last - 1)), comp); } // Section 25.3.6.2 -- pop_heap template inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last) { typedef typename iterator_traits::value_type Value; __kai::__pop_heap(first, last-1, last-1, Value(* (last - 1))); } template inline void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { typedef typename iterator_traits::value_type Value; __kai::__pop_heap(first, last - 1, last - 1, Value(* (last - 1)), comp); } // Section 25.3.6.3 -- make_heap template void make_heap(RandomAccessIterator first, RandomAccessIterator last) { typedef typename iterator_traits::difference_type Distance; typedef typename iterator_traits::value_type Value; if (last - first < 2) return; Distance len = last - first; Distance parent = (len - 2)/2; while (true) { __kai::__adjust_heap(first, parent, len, Value(* (first + parent))); if (parent == 0) return; --parent; } } template void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { typedef typename iterator_traits::difference_type Distance; typedef typename iterator_traits::value_type Value; if (last - first < 2) return; Distance len = last - first; Distance parent = (len - 2)/2; while (true) { __kai::__adjust_heap(first, parent, len, Value(* (first + parent)), comp); if (parent == 0) return; --parent; } } // Section 25.3.6.4 -- sort_heap template void sort_heap(RandomAccessIterator first, RandomAccessIterator last) { while (last - first > 1) { pop_heap(first, last); --last; } } template void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp) { while (last - first > 1) { pop_heap(first, last, comp); --last; } } } // namespace std #endif /* __KAI_HEAP */