williamr@4: /* williamr@4: * williamr@4: * williamr@4: * Copyright (c) 1994 williamr@4: * Hewlett-Packard Company williamr@4: * williamr@4: * Copyright (c) 1996,1997 williamr@4: * Silicon Graphics Computer Systems, Inc. williamr@4: * williamr@4: * Copyright (c) 1997 williamr@4: * Moscow Center for SPARC Technology williamr@4: * williamr@4: * Copyright (c) 1999 williamr@4: * Boris Fomitchev williamr@4: * williamr@4: * This material is provided "as is", with absolutely no warranty expressed williamr@4: * or implied. Any use is at your own risk. williamr@4: * williamr@4: * Permission to use or copy this software for any purpose is hereby granted williamr@4: * without fee, provided the above notices are retained on all copies. williamr@4: * Permission to modify the code and to distribute modified code is granted, williamr@4: * provided the above notices are retained, and a notice that the code was williamr@4: * modified is included with the above copyright notice. williamr@4: * williamr@4: */ williamr@4: #ifndef _STLP_HEAP_C williamr@4: #define _STLP_HEAP_C williamr@4: williamr@4: #ifndef _STLP_INTERNAL_HEAP_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: #ifndef _STLP_INTERNAL_ITERATOR_BASE_H williamr@4: # include williamr@4: #endif williamr@4: williamr@4: _STLP_BEGIN_NAMESPACE williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP williamr@4: void williamr@4: __push_heap(_RandomAccessIterator __first, williamr@4: _Distance __holeIndex, _Distance __topIndex, _Tp __val) williamr@4: { williamr@4: _Distance __parent = (__holeIndex - 1) / 2; williamr@4: while (__holeIndex > __topIndex && *(__first + __parent) < __val) { williamr@4: *(__first + __holeIndex) = *(__first + __parent); williamr@4: __holeIndex = __parent; williamr@4: __parent = (__holeIndex - 1) / 2; williamr@4: } williamr@4: *(__first + __holeIndex) = __val; williamr@4: } williamr@4: williamr@4: template williamr@4: inline void williamr@4: __push_heap_aux(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last, _Distance*, _Tp*) williamr@4: { williamr@4: __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), williamr@4: _Tp(*(__last - 1))); williamr@4: } williamr@4: williamr@4: template williamr@4: void williamr@4: push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) williamr@4: { williamr@4: __push_heap_aux(__first, __last, williamr@4: _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator), _STLP_VALUE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP williamr@4: void williamr@4: __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, williamr@4: _Distance __topIndex, _Tp __val, _Compare __comp) williamr@4: { williamr@4: _Distance __parent = (__holeIndex - 1) / 2; williamr@4: while (__holeIndex > __topIndex && __comp(*(__first + __parent), __val)) { williamr@4: *(__first + __holeIndex) = *(__first + __parent); williamr@4: __holeIndex = __parent; williamr@4: __parent = (__holeIndex - 1) / 2; williamr@4: } williamr@4: *(__first + __holeIndex) = __val; williamr@4: } williamr@4: williamr@4: template williamr@4: inline void williamr@4: __push_heap_aux(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last, _Compare __comp, williamr@4: _Distance*, _Tp*) williamr@4: { williamr@4: __push_heap(__first, _Distance((__last - __first) - 1), _Distance(0), williamr@4: _Tp(*(__last - 1)), __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: void williamr@4: push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, williamr@4: _Compare __comp) williamr@4: { williamr@4: __push_heap_aux(__first, __last, __comp, williamr@4: _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator), _STLP_VALUE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: template williamr@4: void williamr@4: __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, williamr@4: _Distance __len, _Tp __val) { williamr@4: _Distance __topIndex = __holeIndex; williamr@4: _Distance __secondChild = 2 * __holeIndex + 2; williamr@4: while (__secondChild < __len) { williamr@4: if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) williamr@4: __secondChild--; williamr@4: *(__first + __holeIndex) = *(__first + __secondChild); williamr@4: __holeIndex = __secondChild; williamr@4: __secondChild = 2 * (__secondChild + 1); williamr@4: } williamr@4: if (__secondChild == __len) { williamr@4: *(__first + __holeIndex) = *(__first + (__secondChild - 1)); williamr@4: __holeIndex = __secondChild - 1; williamr@4: } williamr@4: __push_heap(__first, __holeIndex, __topIndex, __val); williamr@4: } williamr@4: williamr@4: williamr@4: template williamr@4: inline void williamr@4: __pop_heap_aux(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp*) { williamr@4: __pop_heap(__first, __last - 1, __last - 1, williamr@4: _Tp(*(__last - 1)), _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: template williamr@4: void pop_heap(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last) { williamr@4: __pop_heap_aux(__first, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: template williamr@4: void williamr@4: __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, williamr@4: _Distance __len, _Tp __val, _Compare __comp) williamr@4: { williamr@4: _Distance __topIndex = __holeIndex; williamr@4: _Distance __secondChild = 2 * __holeIndex + 2; williamr@4: while (__secondChild < __len) { williamr@4: if (__comp(*(__first + __secondChild), *(__first + (__secondChild - 1)))) williamr@4: __secondChild--; williamr@4: *(__first + __holeIndex) = *(__first + __secondChild); williamr@4: __holeIndex = __secondChild; williamr@4: __secondChild = 2 * (__secondChild + 1); williamr@4: } williamr@4: if (__secondChild == __len) { williamr@4: *(__first + __holeIndex) = *(__first + (__secondChild - 1)); williamr@4: __holeIndex = __secondChild - 1; williamr@4: } williamr@4: __push_heap(__first, __holeIndex, __topIndex, __val, __comp); williamr@4: } williamr@4: williamr@4: williamr@4: template williamr@4: inline void williamr@4: __pop_heap_aux(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last, _Tp*, _Compare __comp) williamr@4: { williamr@4: __pop_heap(__first, __last - 1, __last - 1, _Tp(*(__last - 1)), __comp, williamr@4: _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: williamr@4: template williamr@4: void williamr@4: pop_heap(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last, _Compare __comp) williamr@4: { williamr@4: __pop_heap_aux(__first, __last, _STLP_VALUE_TYPE(__first, _RandomAccessIterator), __comp); williamr@4: } williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP williamr@4: void williamr@4: __make_heap(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last, _Tp*, _Distance*) williamr@4: { williamr@4: if (__last - __first < 2) return; williamr@4: _Distance __len = __last - __first; williamr@4: _Distance __parent = (__len - 2)/2; williamr@4: williamr@4: while (true) { williamr@4: __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent))); williamr@4: if (__parent == 0) return; williamr@4: __parent--; williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: void williamr@4: make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) williamr@4: { williamr@4: __make_heap(__first, __last, williamr@4: _STLP_VALUE_TYPE(__first, _RandomAccessIterator), _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: template williamr@4: _STLP_INLINE_LOOP williamr@4: void williamr@4: __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, williamr@4: _Compare __comp, _Tp*, _Distance*) williamr@4: { williamr@4: if (__last - __first < 2) return; williamr@4: _Distance __len = __last - __first; williamr@4: _Distance __parent = (__len - 2)/2; williamr@4: williamr@4: while (true) { williamr@4: __adjust_heap(__first, __parent, __len, _Tp(*(__first + __parent)), williamr@4: __comp); williamr@4: if (__parent == 0) return; williamr@4: __parent--; williamr@4: } williamr@4: } williamr@4: williamr@4: template williamr@4: void williamr@4: make_heap(_RandomAccessIterator __first, williamr@4: _RandomAccessIterator __last, _Compare __comp) williamr@4: { williamr@4: __make_heap(__first, __last, __comp, williamr@4: _STLP_VALUE_TYPE(__first, _RandomAccessIterator), _STLP_DISTANCE_TYPE(__first, _RandomAccessIterator)); williamr@4: } williamr@4: williamr@4: _STLP_END_NAMESPACE williamr@4: williamr@4: #endif /* _STLP_HEAP_C */ williamr@4: williamr@4: // Local Variables: williamr@4: // mode:C++ williamr@4: // End: