stl_heap.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. // Heap implementation -*- C++ -*-
  2. // Copyright (C) 2001-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /*
  21. *
  22. * Copyright (c) 1994
  23. * Hewlett-Packard Company
  24. *
  25. * Permission to use, copy, modify, distribute and sell this software
  26. * and its documentation for any purpose is hereby granted without fee,
  27. * provided that the above copyright notice appear in all copies and
  28. * that both that copyright notice and this permission notice appear
  29. * in supporting documentation. Hewlett-Packard Company makes no
  30. * representations about the suitability of this software for any
  31. * purpose. It is provided "as is" without express or implied warranty.
  32. *
  33. * Copyright (c) 1997
  34. * Silicon Graphics Computer Systems, Inc.
  35. *
  36. * Permission to use, copy, modify, distribute and sell this software
  37. * and its documentation for any purpose is hereby granted without fee,
  38. * provided that the above copyright notice appear in all copies and
  39. * that both that copyright notice and this permission notice appear
  40. * in supporting documentation. Silicon Graphics makes no
  41. * representations about the suitability of this software for any
  42. * purpose. It is provided "as is" without express or implied warranty.
  43. */
  44. /** @file bits/stl_heap.h
  45. * This is an internal header file, included by other library headers.
  46. * Do not attempt to use it directly. @headername{queue}
  47. */
  48. #ifndef _STL_HEAP_H
  49. #define _STL_HEAP_H 1
  50. #include <debug/debug.h>
  51. #include <bits/move.h>
  52. #include <bits/predefined_ops.h>
  53. #include <bits/stl_iterator_base_funcs.h>
  54. namespace std _GLIBCXX_VISIBILITY(default)
  55. {
  56. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  57. /**
  58. * @defgroup heap_algorithms Heap
  59. * @ingroup sorting_algorithms
  60. */
  61. template<typename _RandomAccessIterator, typename _Distance,
  62. typename _Compare>
  63. _GLIBCXX20_CONSTEXPR
  64. _Distance
  65. __is_heap_until(_RandomAccessIterator __first, _Distance __n,
  66. _Compare& __comp)
  67. {
  68. _Distance __parent = 0;
  69. for (_Distance __child = 1; __child < __n; ++__child)
  70. {
  71. if (__comp(__first + __parent, __first + __child))
  72. return __child;
  73. if ((__child & 1) == 0)
  74. ++__parent;
  75. }
  76. return __n;
  77. }
  78. // __is_heap, a predicate testing whether or not a range is a heap.
  79. // This function is an extension, not part of the C++ standard.
  80. template<typename _RandomAccessIterator, typename _Distance>
  81. _GLIBCXX20_CONSTEXPR
  82. inline bool
  83. __is_heap(_RandomAccessIterator __first, _Distance __n)
  84. {
  85. __gnu_cxx::__ops::_Iter_less_iter __comp;
  86. return std::__is_heap_until(__first, __n, __comp) == __n;
  87. }
  88. template<typename _RandomAccessIterator, typename _Compare,
  89. typename _Distance>
  90. _GLIBCXX20_CONSTEXPR
  91. inline bool
  92. __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
  93. {
  94. typedef __decltype(__comp) _Cmp;
  95. __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
  96. return std::__is_heap_until(__first, __n, __cmp) == __n;
  97. }
  98. template<typename _RandomAccessIterator>
  99. _GLIBCXX20_CONSTEXPR
  100. inline bool
  101. __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  102. { return std::__is_heap(__first, std::distance(__first, __last)); }
  103. template<typename _RandomAccessIterator, typename _Compare>
  104. _GLIBCXX20_CONSTEXPR
  105. inline bool
  106. __is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  107. _Compare __comp)
  108. {
  109. return std::__is_heap(__first, _GLIBCXX_MOVE(__comp),
  110. std::distance(__first, __last));
  111. }
  112. // Heap-manipulation functions: push_heap, pop_heap, make_heap, sort_heap,
  113. // + is_heap and is_heap_until in C++0x.
  114. template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
  115. typename _Compare>
  116. _GLIBCXX20_CONSTEXPR
  117. void
  118. __push_heap(_RandomAccessIterator __first,
  119. _Distance __holeIndex, _Distance __topIndex, _Tp __value,
  120. _Compare& __comp)
  121. {
  122. _Distance __parent = (__holeIndex - 1) / 2;
  123. while (__holeIndex > __topIndex && __comp(__first + __parent, __value))
  124. {
  125. *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __parent));
  126. __holeIndex = __parent;
  127. __parent = (__holeIndex - 1) / 2;
  128. }
  129. *(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
  130. }
  131. /**
  132. * @brief Push an element onto a heap.
  133. * @param __first Start of heap.
  134. * @param __last End of heap + element.
  135. * @ingroup heap_algorithms
  136. *
  137. * This operation pushes the element at last-1 onto the valid heap
  138. * over the range [__first,__last-1). After completion,
  139. * [__first,__last) is a valid heap.
  140. */
  141. template<typename _RandomAccessIterator>
  142. _GLIBCXX20_CONSTEXPR
  143. inline void
  144. push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  145. {
  146. typedef typename iterator_traits<_RandomAccessIterator>::value_type
  147. _ValueType;
  148. typedef typename iterator_traits<_RandomAccessIterator>::difference_type
  149. _DistanceType;
  150. // concept requirements
  151. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  152. _RandomAccessIterator>)
  153. __glibcxx_function_requires(_LessThanComparableConcept<_ValueType>)
  154. __glibcxx_requires_valid_range(__first, __last);
  155. __glibcxx_requires_irreflexive(__first, __last);
  156. __glibcxx_requires_heap(__first, __last - 1);
  157. __gnu_cxx::__ops::_Iter_less_val __comp;
  158. _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
  159. std::__push_heap(__first, _DistanceType((__last - __first) - 1),
  160. _DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
  161. }
  162. /**
  163. * @brief Push an element onto a heap using comparison functor.
  164. * @param __first Start of heap.
  165. * @param __last End of heap + element.
  166. * @param __comp Comparison functor.
  167. * @ingroup heap_algorithms
  168. *
  169. * This operation pushes the element at __last-1 onto the valid
  170. * heap over the range [__first,__last-1). After completion,
  171. * [__first,__last) is a valid heap. Compare operations are
  172. * performed using comp.
  173. */
  174. template<typename _RandomAccessIterator, typename _Compare>
  175. _GLIBCXX20_CONSTEXPR
  176. inline void
  177. push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  178. _Compare __comp)
  179. {
  180. typedef typename iterator_traits<_RandomAccessIterator>::value_type
  181. _ValueType;
  182. typedef typename iterator_traits<_RandomAccessIterator>::difference_type
  183. _DistanceType;
  184. // concept requirements
  185. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  186. _RandomAccessIterator>)
  187. __glibcxx_requires_valid_range(__first, __last);
  188. __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
  189. __glibcxx_requires_heap_pred(__first, __last - 1, __comp);
  190. __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
  191. __cmp(_GLIBCXX_MOVE(__comp));
  192. _ValueType __value = _GLIBCXX_MOVE(*(__last - 1));
  193. std::__push_heap(__first, _DistanceType((__last - __first) - 1),
  194. _DistanceType(0), _GLIBCXX_MOVE(__value), __cmp);
  195. }
  196. template<typename _RandomAccessIterator, typename _Distance,
  197. typename _Tp, typename _Compare>
  198. _GLIBCXX20_CONSTEXPR
  199. void
  200. __adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
  201. _Distance __len, _Tp __value, _Compare __comp)
  202. {
  203. const _Distance __topIndex = __holeIndex;
  204. _Distance __secondChild = __holeIndex;
  205. while (__secondChild < (__len - 1) / 2)
  206. {
  207. __secondChild = 2 * (__secondChild + 1);
  208. if (__comp(__first + __secondChild,
  209. __first + (__secondChild - 1)))
  210. __secondChild--;
  211. *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
  212. __holeIndex = __secondChild;
  213. }
  214. if ((__len & 1) == 0 && __secondChild == (__len - 2) / 2)
  215. {
  216. __secondChild = 2 * (__secondChild + 1);
  217. *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
  218. + (__secondChild - 1)));
  219. __holeIndex = __secondChild - 1;
  220. }
  221. __decltype(__gnu_cxx::__ops::__iter_comp_val(_GLIBCXX_MOVE(__comp)))
  222. __cmp(_GLIBCXX_MOVE(__comp));
  223. std::__push_heap(__first, __holeIndex, __topIndex,
  224. _GLIBCXX_MOVE(__value), __cmp);
  225. }
  226. template<typename _RandomAccessIterator, typename _Compare>
  227. _GLIBCXX20_CONSTEXPR
  228. inline void
  229. __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  230. _RandomAccessIterator __result, _Compare& __comp)
  231. {
  232. typedef typename iterator_traits<_RandomAccessIterator>::value_type
  233. _ValueType;
  234. typedef typename iterator_traits<_RandomAccessIterator>::difference_type
  235. _DistanceType;
  236. _ValueType __value = _GLIBCXX_MOVE(*__result);
  237. *__result = _GLIBCXX_MOVE(*__first);
  238. std::__adjust_heap(__first, _DistanceType(0),
  239. _DistanceType(__last - __first),
  240. _GLIBCXX_MOVE(__value), __comp);
  241. }
  242. /**
  243. * @brief Pop an element off a heap.
  244. * @param __first Start of heap.
  245. * @param __last End of heap.
  246. * @pre [__first, __last) is a valid, non-empty range.
  247. * @ingroup heap_algorithms
  248. *
  249. * This operation pops the top of the heap. The elements __first
  250. * and __last-1 are swapped and [__first,__last-1) is made into a
  251. * heap.
  252. */
  253. template<typename _RandomAccessIterator>
  254. _GLIBCXX20_CONSTEXPR
  255. inline void
  256. pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  257. {
  258. // concept requirements
  259. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  260. _RandomAccessIterator>)
  261. __glibcxx_function_requires(_LessThanComparableConcept<
  262. typename iterator_traits<_RandomAccessIterator>::value_type>)
  263. __glibcxx_requires_non_empty_range(__first, __last);
  264. __glibcxx_requires_valid_range(__first, __last);
  265. __glibcxx_requires_irreflexive(__first, __last);
  266. __glibcxx_requires_heap(__first, __last);
  267. if (__last - __first > 1)
  268. {
  269. --__last;
  270. __gnu_cxx::__ops::_Iter_less_iter __comp;
  271. std::__pop_heap(__first, __last, __last, __comp);
  272. }
  273. }
  274. /**
  275. * @brief Pop an element off a heap using comparison functor.
  276. * @param __first Start of heap.
  277. * @param __last End of heap.
  278. * @param __comp Comparison functor to use.
  279. * @ingroup heap_algorithms
  280. *
  281. * This operation pops the top of the heap. The elements __first
  282. * and __last-1 are swapped and [__first,__last-1) is made into a
  283. * heap. Comparisons are made using comp.
  284. */
  285. template<typename _RandomAccessIterator, typename _Compare>
  286. _GLIBCXX20_CONSTEXPR
  287. inline void
  288. pop_heap(_RandomAccessIterator __first,
  289. _RandomAccessIterator __last, _Compare __comp)
  290. {
  291. // concept requirements
  292. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  293. _RandomAccessIterator>)
  294. __glibcxx_requires_valid_range(__first, __last);
  295. __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
  296. __glibcxx_requires_non_empty_range(__first, __last);
  297. __glibcxx_requires_heap_pred(__first, __last, __comp);
  298. if (__last - __first > 1)
  299. {
  300. typedef __decltype(__comp) _Cmp;
  301. __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
  302. --__last;
  303. std::__pop_heap(__first, __last, __last, __cmp);
  304. }
  305. }
  306. template<typename _RandomAccessIterator, typename _Compare>
  307. _GLIBCXX20_CONSTEXPR
  308. void
  309. __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  310. _Compare& __comp)
  311. {
  312. typedef typename iterator_traits<_RandomAccessIterator>::value_type
  313. _ValueType;
  314. typedef typename iterator_traits<_RandomAccessIterator>::difference_type
  315. _DistanceType;
  316. if (__last - __first < 2)
  317. return;
  318. const _DistanceType __len = __last - __first;
  319. _DistanceType __parent = (__len - 2) / 2;
  320. while (true)
  321. {
  322. _ValueType __value = _GLIBCXX_MOVE(*(__first + __parent));
  323. std::__adjust_heap(__first, __parent, __len, _GLIBCXX_MOVE(__value),
  324. __comp);
  325. if (__parent == 0)
  326. return;
  327. __parent--;
  328. }
  329. }
  330. /**
  331. * @brief Construct a heap over a range.
  332. * @param __first Start of heap.
  333. * @param __last End of heap.
  334. * @ingroup heap_algorithms
  335. *
  336. * This operation makes the elements in [__first,__last) into a heap.
  337. */
  338. template<typename _RandomAccessIterator>
  339. _GLIBCXX20_CONSTEXPR
  340. inline void
  341. make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  342. {
  343. // concept requirements
  344. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  345. _RandomAccessIterator>)
  346. __glibcxx_function_requires(_LessThanComparableConcept<
  347. typename iterator_traits<_RandomAccessIterator>::value_type>)
  348. __glibcxx_requires_valid_range(__first, __last);
  349. __glibcxx_requires_irreflexive(__first, __last);
  350. __gnu_cxx::__ops::_Iter_less_iter __comp;
  351. std::__make_heap(__first, __last, __comp);
  352. }
  353. /**
  354. * @brief Construct a heap over a range using comparison functor.
  355. * @param __first Start of heap.
  356. * @param __last End of heap.
  357. * @param __comp Comparison functor to use.
  358. * @ingroup heap_algorithms
  359. *
  360. * This operation makes the elements in [__first,__last) into a heap.
  361. * Comparisons are made using __comp.
  362. */
  363. template<typename _RandomAccessIterator, typename _Compare>
  364. _GLIBCXX20_CONSTEXPR
  365. inline void
  366. make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  367. _Compare __comp)
  368. {
  369. // concept requirements
  370. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  371. _RandomAccessIterator>)
  372. __glibcxx_requires_valid_range(__first, __last);
  373. __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
  374. typedef __decltype(__comp) _Cmp;
  375. __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
  376. std::__make_heap(__first, __last, __cmp);
  377. }
  378. template<typename _RandomAccessIterator, typename _Compare>
  379. _GLIBCXX20_CONSTEXPR
  380. void
  381. __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  382. _Compare& __comp)
  383. {
  384. while (__last - __first > 1)
  385. {
  386. --__last;
  387. std::__pop_heap(__first, __last, __last, __comp);
  388. }
  389. }
  390. /**
  391. * @brief Sort a heap.
  392. * @param __first Start of heap.
  393. * @param __last End of heap.
  394. * @ingroup heap_algorithms
  395. *
  396. * This operation sorts the valid heap in the range [__first,__last).
  397. */
  398. template<typename _RandomAccessIterator>
  399. _GLIBCXX20_CONSTEXPR
  400. inline void
  401. sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  402. {
  403. // concept requirements
  404. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  405. _RandomAccessIterator>)
  406. __glibcxx_function_requires(_LessThanComparableConcept<
  407. typename iterator_traits<_RandomAccessIterator>::value_type>)
  408. __glibcxx_requires_valid_range(__first, __last);
  409. __glibcxx_requires_irreflexive(__first, __last);
  410. __glibcxx_requires_heap(__first, __last);
  411. __gnu_cxx::__ops::_Iter_less_iter __comp;
  412. std::__sort_heap(__first, __last, __comp);
  413. }
  414. /**
  415. * @brief Sort a heap using comparison functor.
  416. * @param __first Start of heap.
  417. * @param __last End of heap.
  418. * @param __comp Comparison functor to use.
  419. * @ingroup heap_algorithms
  420. *
  421. * This operation sorts the valid heap in the range [__first,__last).
  422. * Comparisons are made using __comp.
  423. */
  424. template<typename _RandomAccessIterator, typename _Compare>
  425. _GLIBCXX20_CONSTEXPR
  426. inline void
  427. sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  428. _Compare __comp)
  429. {
  430. // concept requirements
  431. __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
  432. _RandomAccessIterator>)
  433. __glibcxx_requires_valid_range(__first, __last);
  434. __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
  435. __glibcxx_requires_heap_pred(__first, __last, __comp);
  436. typedef __decltype(__comp) _Cmp;
  437. __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
  438. std::__sort_heap(__first, __last, __cmp);
  439. }
  440. #if __cplusplus >= 201103L
  441. /**
  442. * @brief Search the end of a heap.
  443. * @param __first Start of range.
  444. * @param __last End of range.
  445. * @return An iterator pointing to the first element not in the heap.
  446. * @ingroup heap_algorithms
  447. *
  448. * This operation returns the last iterator i in [__first, __last) for which
  449. * the range [__first, i) is a heap.
  450. */
  451. template<typename _RandomAccessIterator>
  452. _GLIBCXX20_CONSTEXPR
  453. inline _RandomAccessIterator
  454. is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
  455. {
  456. // concept requirements
  457. __glibcxx_function_requires(_RandomAccessIteratorConcept<
  458. _RandomAccessIterator>)
  459. __glibcxx_function_requires(_LessThanComparableConcept<
  460. typename iterator_traits<_RandomAccessIterator>::value_type>)
  461. __glibcxx_requires_valid_range(__first, __last);
  462. __glibcxx_requires_irreflexive(__first, __last);
  463. __gnu_cxx::__ops::_Iter_less_iter __comp;
  464. return __first +
  465. std::__is_heap_until(__first, std::distance(__first, __last), __comp);
  466. }
  467. /**
  468. * @brief Search the end of a heap using comparison functor.
  469. * @param __first Start of range.
  470. * @param __last End of range.
  471. * @param __comp Comparison functor to use.
  472. * @return An iterator pointing to the first element not in the heap.
  473. * @ingroup heap_algorithms
  474. *
  475. * This operation returns the last iterator i in [__first, __last) for which
  476. * the range [__first, i) is a heap. Comparisons are made using __comp.
  477. */
  478. template<typename _RandomAccessIterator, typename _Compare>
  479. _GLIBCXX20_CONSTEXPR
  480. inline _RandomAccessIterator
  481. is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last,
  482. _Compare __comp)
  483. {
  484. // concept requirements
  485. __glibcxx_function_requires(_RandomAccessIteratorConcept<
  486. _RandomAccessIterator>)
  487. __glibcxx_requires_valid_range(__first, __last);
  488. __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
  489. typedef __decltype(__comp) _Cmp;
  490. __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
  491. return __first
  492. + std::__is_heap_until(__first, std::distance(__first, __last), __cmp);
  493. }
  494. /**
  495. * @brief Determines whether a range is a heap.
  496. * @param __first Start of range.
  497. * @param __last End of range.
  498. * @return True if range is a heap, false otherwise.
  499. * @ingroup heap_algorithms
  500. */
  501. template<typename _RandomAccessIterator>
  502. _GLIBCXX20_CONSTEXPR
  503. inline bool
  504. is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
  505. { return std::is_heap_until(__first, __last) == __last; }
  506. /**
  507. * @brief Determines whether a range is a heap using comparison functor.
  508. * @param __first Start of range.
  509. * @param __last End of range.
  510. * @param __comp Comparison functor to use.
  511. * @return True if range is a heap, false otherwise.
  512. * @ingroup heap_algorithms
  513. */
  514. template<typename _RandomAccessIterator, typename _Compare>
  515. _GLIBCXX20_CONSTEXPR
  516. inline bool
  517. is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
  518. _Compare __comp)
  519. {
  520. // concept requirements
  521. __glibcxx_function_requires(_RandomAccessIteratorConcept<
  522. _RandomAccessIterator>)
  523. __glibcxx_requires_valid_range(__first, __last);
  524. __glibcxx_requires_irreflexive_pred(__first, __last, __comp);
  525. const auto __dist = std::distance(__first, __last);
  526. typedef __decltype(__comp) _Cmp;
  527. __gnu_cxx::__ops::_Iter_comp_iter<_Cmp> __cmp(_GLIBCXX_MOVE(__comp));
  528. return std::__is_heap_until(__first, __dist, __cmp) == __dist;
  529. }
  530. #endif
  531. _GLIBCXX_END_NAMESPACE_VERSION
  532. } // namespace
  533. #endif /* _STL_HEAP_H */