X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Finclude%2Fbits%2Fstl_heap.h;h=9348fe9702fb37e00698e71c83df6cf360ee0ae3;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=c19195aad39a4dab6e04c8f79d90586d50dc6d68;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h index c19195aa..9348fe97 100644 --- a/libstdc++-v3/include/bits/stl_heap.h +++ b/libstdc++-v3/include/bits/stl_heap.h @@ -1,11 +1,12 @@ // Heap implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +// 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 2, or (at your option) +// 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, @@ -13,19 +14,14 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. +// 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. -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. +// 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 +// . /* * @@ -57,30 +53,104 @@ * You should not attempt to use it directly. */ -#ifndef _CPP_BITS_STL_HEAP_H -#define _CPP_BITS_STL_HEAP_H 1 +#ifndef _STL_HEAP_H +#define _STL_HEAP_H 1 -namespace std -{ +#include +#include - // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap. +_GLIBCXX_BEGIN_NAMESPACE(std) + + /** + * @defgroup heap_algorithms Heap Algorithms + * @ingroup sorting_algorithms + */ + + template + _Distance + __is_heap_until(_RandomAccessIterator __first, _Distance __n) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__first[__parent] < __first[__child]) + return __child; + if ((__child & 1) == 0) + ++__parent; + } + return __n; + } + + template + _Distance + __is_heap_until(_RandomAccessIterator __first, _Distance __n, + _Compare __comp) + { + _Distance __parent = 0; + for (_Distance __child = 1; __child < __n; ++__child) + { + if (__comp(__first[__parent], __first[__child])) + return __child; + if ((__child & 1) == 0) + ++__parent; + } + return __n; + } + + // __is_heap, a predicate testing whether or not a range is a heap. + // This function is an extension, not part of the C++ standard. + template + inline bool + __is_heap(_RandomAccessIterator __first, _Distance __n) + { return std::__is_heap_until(__first, __n) == __n; } + + template + inline bool + __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n) + { return std::__is_heap_until(__first, __n, __comp) == __n; } + + template + inline bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::__is_heap(__first, std::distance(__first, __last)); } + + template + inline bool + __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { return std::__is_heap(__first, __comp, std::distance(__first, __last)); } + + // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap, + // + is_heap and is_heap_until in C++0x. template - void + void __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __topIndex, _Tp __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; + while (__holeIndex > __topIndex && *(__first + __parent) < __value) + { + *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); } + /** + * @brief Push an element onto a heap. + * @param first Start of heap. + * @param last End of heap + element. + * @ingroup heap_algorithms + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + */ template - inline void + inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::value_type @@ -89,31 +159,47 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last - 1); - __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), - _ValueType(*(__last - 1))); + _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _GLIBCXX_MOVE(__value)); } - template + template void __push_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __topIndex, _Tp __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; + while (__holeIndex > __topIndex + && __comp(*(__first + __parent), __value)) + { + *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent)); + __holeIndex = __parent; + __parent = (__holeIndex - 1) / 2; + } + *(__first + __holeIndex) = _GLIBCXX_MOVE(__value); } + /** + * @brief Push an element onto a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap + element. + * @param comp Comparison functor. + * @ingroup heap_algorithms + * + * This operation pushes the element at last-1 onto the valid heap over the + * range [first,last-1). After completion, [first,last) is a valid heap. + * Compare operations are performed using comp. + */ template - inline void + inline void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -123,56 +209,84 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last - 1, __comp); - __push_heap(__first, _DistanceType((__last - __first) - 1), _DistanceType(0), - _ValueType(*(__last - 1)), __comp); + _ValueType __value = _GLIBCXX_MOVE(*(__last - 1)); + std::__push_heap(__first, _DistanceType((__last - __first) - 1), + _DistanceType(0), _GLIBCXX_MOVE(__value), __comp); } template - void + void __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex, _Distance __len, _Tp __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); + const _Distance __topIndex = __holeIndex; + _Distance __secondChild = __holeIndex; + while (__secondChild < (__len - 1) / 2) + { + __secondChild = 2 * (__secondChild + 1); + if (*(__first + __secondChild) < *(__first + (__secondChild - 1))) + __secondChild--; + *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); + __holeIndex = __secondChild; + } + if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2) + { + __secondChild = 2 * (__secondChild + 1); + *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + + (__secondChild - 1))); + __holeIndex = __secondChild - 1; + } + std::__push_heap(__first, __holeIndex, __topIndex, + _GLIBCXX_MOVE(__value)); } - template - inline void + template + inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result, _Tp __value) + _RandomAccessIterator __result) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; - *__result = *__first; - __adjust_heap(__first, _Distance(0), _Distance(__last - __first), __value); + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + _ValueType __value = _GLIBCXX_MOVE(*__result); + *__result = _GLIBCXX_MOVE(*__first); + std::__adjust_heap(__first, _DistanceType(0), + _DistanceType(__last - __first), + _GLIBCXX_MOVE(__value)); } + /** + * @brief Pop an element off a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap_algorithms + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. + */ template inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); - __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1))); + --__last; + std::__pop_heap(__first, __last, __last); } template - inline void + template + inline void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, - _RandomAccessIterator __result, _Tp __value, _Compare __comp) + _RandomAccessIterator __result, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type _Distance; - *__result = *__first; - __adjust_heap(__first, _Distance(0), _Distance(__last - __first), - __value, __comp); + typedef typename iterator_traits<_RandomAccessIterator>::value_type + _ValueType; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type + _DistanceType; + + _ValueType __value = _GLIBCXX_MOVE(*__result); + *__result = _GLIBCXX_MOVE(*__first); + std::__adjust_heap(__first, _DistanceType(0), + _DistanceType(__last - __first), + _GLIBCXX_MOVE(__value), __comp); } + /** + * @brief Pop an element off a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap_algorithms + * + * This operation pops the top of the heap. The elements first and last-1 + * are swapped and [first,last-1) is made into a heap. Comparisons are + * made using comp. + */ template - inline void + inline void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); - typedef typename iterator_traits<_RandomAccessIterator>::value_type _ValueType; - __pop_heap(__first, __last - 1, __last - 1, _ValueType(*(__last - 1)), __comp); + --__last; + std::__pop_heap(__first, __last, __last, __comp); } + /** + * @brief Construct a heap over a range. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap_algorithms + * + * This operation makes the elements in [first,last) into a heap. + */ template - void + void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { typedef typename iterator_traits<_RandomAccessIterator>::value_type @@ -231,23 +378,38 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept<_ValueType>) - - if (__last - __first < 2) return; - _DistanceType __len = __last - __first; - _DistanceType __parent = (__len - 2)/2; - - while (true) { - __adjust_heap(__first, __parent, __len, _ValueType(*(__first + __parent))); - if (__parent == 0) return; - __parent--; - } + __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>) + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); + std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value)); + if (__parent == 0) + return; + __parent--; + } } + /** + * @brief Construct a heap over a range using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap_algorithms + * + * This operation makes the elements in [first,last) into a heap. + * Comparisons are made using comp. + */ template - inline void + void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { @@ -257,52 +419,160 @@ namespace std _DistanceType; // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - - if (__last - __first < 2) return; - _DistanceType __len = __last - __first; - _DistanceType __parent = (__len - 2)/2; - - while (true) { - __adjust_heap(__first, __parent, __len, - _ValueType(*(__first + __parent)), __comp); - if (__parent == 0) return; - __parent--; - } + __glibcxx_requires_valid_range(__first, __last); + + if (__last - __first < 2) + return; + + const _DistanceType __len = __last - __first; + _DistanceType __parent = (__len - 2) / 2; + while (true) + { + _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent)); + std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value), + __comp); + if (__parent == 0) + return; + __parent--; + } } + /** + * @brief Sort a heap. + * @param first Start of heap. + * @param last End of heap. + * @ingroup heap_algorithms + * + * This operation sorts the valid heap in the range [first,last). + */ template void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) - __glibcpp_function_requires(_LessThanComparableConcept< + __glibcxx_function_requires(_LessThanComparableConcept< typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap(__first, __last); while (__last - __first > 1) - pop_heap(__first, __last--); + { + --__last; + std::__pop_heap(__first, __last, __last); + } } + /** + * @brief Sort a heap using comparison functor. + * @param first Start of heap. + * @param last End of heap. + * @param comp Comparison functor to use. + * @ingroup heap_algorithms + * + * This operation sorts the valid heap in the range [first,last). + * Comparisons are made using comp. + */ template - void + void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { // concept requirements - __glibcpp_function_requires(_Mutable_RandomAccessIteratorConcept< + __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept< _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_heap_pred(__first, __last, __comp); while (__last - __first > 1) - pop_heap(__first, __last--, __comp); + { + --__last; + std::__pop_heap(__first, __last, __last, __comp); + } + } + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + /** + * @brief Search the end of a heap. + * @param first Start of range. + * @param last End of range. + * @return An iterator pointing to the first element not in the heap. + * @ingroup heap_algorithms + * + * This operation returns the last iterator i in [first, last) for which + * the range [first, i) is a heap. + */ + template + inline _RandomAccessIterator + is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_function_requires(_LessThanComparableConcept< + typename iterator_traits<_RandomAccessIterator>::value_type>) + __glibcxx_requires_valid_range(__first, __last); + + return __first + std::__is_heap_until(__first, std::distance(__first, + __last)); } -} // namespace std + /** + * @brief Search the end of a heap using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor to use. + * @return An iterator pointing to the first element not in the heap. + * @ingroup heap_algorithms + * + * This operation returns the last iterator i in [first, last) for which + * the range [first, i) is a heap. Comparisons are made using comp. + */ + template + inline _RandomAccessIterator + is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { + // concept requirements + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) + __glibcxx_requires_valid_range(__first, __last); + + return __first + std::__is_heap_until(__first, std::distance(__first, + __last), + __comp); + } + + /** + * @brief Determines whether a range is a heap. + * @param first Start of range. + * @param last End of range. + * @return True if range is a heap, false otherwise. + * @ingroup heap_algorithms + */ + template + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) + { return std::is_heap_until(__first, __last) == __last; } + + /** + * @brief Determines whether a range is a heap using comparison functor. + * @param first Start of range. + * @param last End of range. + * @param comp Comparison functor to use. + * @return True if range is a heap, false otherwise. + * @ingroup heap_algorithms + */ + template + inline bool + is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) + { return std::is_heap_until(__first, __last, __comp) == __last; } +#endif -#endif /* _CPP_BITS_STL_HEAP_H */ +_GLIBCXX_END_NAMESPACE -// Local Variables: -// mode:C++ -// End: +#endif /* _STL_HEAP_H */