27 #ifndef BOOST_HEAP_INTERVAL_HEAP_HPP_
28 #define BOOST_HEAP_INTERVAL_HEAP_HPP_
31 #error interval_heap.hpp requires a C++ compiler.
35 #if (__cplusplus >= 201103L)
47 template <
typename Iterator,
typename Compare>
51 template <
typename Iterator,
typename Compare = std::less<
typename
52 std::iterator_traits<Iterator>::value_type> >
57 template <
typename Iterator,
typename Compare>
60 template <
typename Iterator,
typename Compare>
64 template <
typename Iterator,
typename Compare>
66 typename std::iterator_traits<Iterator>::difference_type index,
70 template <
typename Iterator,
typename Compare>
72 typename std::iterator_traits<Iterator>::difference_type index,
76 template <
typename Iterator,
typename Compare>
79 template <
typename Iterator,
typename Compare>
82 template <
typename Iterator,
typename Compare>
87 namespace interval_heap_internal {
89 template <
typename Iterator,
typename Compare>
90 void sift_leaf (Iterator first, Iterator last,
91 typename std::iterator_traits<Iterator>::difference_type index,
94 template <
bool left_bound,
typename Iterator,
typename Offset,
typename Compare>
95 void sift_up (Iterator first, Offset index, Compare compare,Offset limit_child);
97 template <
typename Iterator,
typename Offset,
typename Compare>
98 void sift_leaf_max (Iterator first, Iterator last, Offset index,
99 Compare compare, Offset limit_child);
101 template <
typename Iterator,
typename Offset,
typename Compare>
102 void sift_leaf_min (Iterator first, Iterator last, Offset index,
103 Compare compare, Offset limit_child);
105 template <
bool left_bound,
typename Iterator,
typename Offset,
typename Compare>
106 void sift_down (Iterator first, Iterator last, Offset index, Compare compare,
124 template <
typename Iterator,
typename Compare>
126 typename std::iterator_traits<Iterator>::difference_type index,
133 sift_down<false, Iterator, Offset, Compare>(first, last, index,
compare,2);
135 sift_down<true, Iterator, Offset, Compare>(first, last, index,
compare, 2);
149 template <
typename Iterator,
typename Compare>
152 sift_leaf<Iterator, Compare>(first, last, (last - first) - 1, compare);
170 template <
typename Iterator,
typename Compare>
172 typename std::iterator_traits<Iterator>::difference_type index,
177 swap(*(first + index), *last);
179 update_interval_heap<Iterator, Compare>(first, last, index,
compare);
182 swap(*last, *(first + index));
200 template <
typename Iterator,
typename Compare>
208 sift_down<true, Iterator, Offset, Compare>(first, last, 0,
compare, 2);
229 template <
typename Iterator,
typename Compare>
235 if (last - first <= 2)
238 swap(*(first + 1), *last);
240 sift_down<false, Iterator, Offset, Compare>(first, last, 1,
compare, 2);
243 swap(*last, *(first + 1));
258 template <
typename Iterator,
typename Compare>
260 Iterator cursor = last;
261 while (cursor != first) {
263 pop_interval_heap_max<Iterator, Compare>(first, cursor,
compare);
270 template <
typename Iterator,
typename Compare>
276 Offset index =
static_cast<Offset
>(0);
279 Offset index_end = last - first;
280 while (index < index_end) {
281 Iterator cursor = first + index;
283 if ((index & 1) &&
compare(*cursor, *(cursor - 1)))
287 Iterator
parent = first + ((index / 2 - 1) | 1);
294 if (
compare(*cursor, *(parent - 1)))
301 return first + index;
308 template <
typename Iterator,
typename Compare>
311 return (is_interval_heap_until<Iterator,Compare>(first, last, compare)
326 template <
typename Iterator,
typename Compare>
332 Offset index_end = last - first;
337 const Offset end_parent = index_end / 2 - 1;
339 Offset index = index_end ^ (index_end & 1);
342 const Offset stop = (index <= end_parent) ? (index * 2 + 2) : index_end;
345 if (
compare(*(first + index + 1), *(first + index)))
346 swap(*(first + index + 1), *(first + index));
348 sift_down<false, Iterator, Offset, Compare>(first, last, index + 1,
350 sift_down<true , Iterator, Offset, Compare>(first, last, index,
353 }
while (index >= 2);
356 namespace interval_heap_internal {
358 template <
bool left_bound,
typename Iterator,
typename Offset,
typename Compare>
359 void sift_up (Iterator first, Offset origin, Compare compare, Offset limit_child)
365 Offset index = origin;
366 #if (__cplusplus >= 201103L) // C++11
367 Value swap_space = std::move_if_noexcept(*(first + index));
370 while (index >= limit_child) {
371 const Offset
parent = ((index / 2 - 1) | 1) ^ (left_bound ? 1 : 0);
372 #if (__cplusplus >= 201103L) // C++11
373 if (
compare((left_bound ? swap_space : *(first + parent)),
374 (left_bound ? *(first + parent) : swap_space))) {
375 *(first + index) = std::move_if_noexcept(*(first + parent));
377 if (
compare(*(first + (left_bound ? index : parent)),
378 *(first + (left_bound ? parent : index)))) {
379 swap(*(first + index), *(first + parent));
387 #if (__cplusplus < 201103L) // Not C++11
391 swap(*(first + index), swap_space);
393 swap(*(first + origin), swap_space);
394 while (origin > index) {
395 origin = ((origin / 2 - 1) | 1) ^ (left_bound ? 1 : 0);
396 swap(*(first + origin), swap_space);
400 #if (__cplusplus >= 201103L) // C++11
401 *(first + index) = std::move_if_noexcept(swap_space);
406 template <
typename Iterator,
typename Offset,
typename Compare>
408 Compare compare, Offset limit_child)
412 const Offset index_end = last - first;
415 const Offset co_index = (index * 2 < index_end) ? (index * 2) : (index ^ 1);
416 if (
compare(*(first + index), *(first + co_index))) {
417 swap(*(first + index), *(first + co_index));
419 sift_up<true, Iterator, Offset, Compare>(first, co_index,
compare,
422 swap(*(first + index), *(first + co_index));
426 sift_up<false, Iterator, Offset, Compare>(first, index,
compare,
431 template <
typename Iterator,
typename Offset,
typename Compare>
433 Compare compare, Offset limit_child)
437 const Offset index_end = last - first;
440 Offset co_index = index | 1;
442 if (co_index >= index_end) {
446 co_index = (co_index / 2 - 1) | 1;
448 if (
compare(*(first + co_index), *(first + index))) {
449 swap(*(first + index), *(first + co_index));
451 sift_up<false, Iterator, Offset, Compare>(first, co_index,
compare,
454 swap(*(first + index), *(first + co_index));
458 sift_up<true, Iterator, Offset, Compare>(first, index,
compare, limit_child);
462 template <
bool left_bound,
typename Iterator,
typename Offset,
typename Compare>
463 void sift_down (Iterator first, Iterator last, Offset origin, Compare compare,
470 Offset index = origin;
471 #if (__cplusplus >= 201103L) // C++11
472 Value limbo = std::move_if_noexcept(*(first + index));
475 const Offset index_end = last - first;
477 const Offset end_parent = index_end / 2 -
478 ((left_bound && ((index_end & 3) == 0)) ? 2 : 1);
480 while (index < end_parent) {
481 Offset child = index * 2 + (left_bound ? 2 : 1);
484 if (
compare(*(first + child + (left_bound ? 2 : 0)),
485 *(first + child + (left_bound ? 0 : 2))))
488 #if (__cplusplus >= 201103L) // C++11
490 *(first + index) = std::move_if_noexcept(limbo);
494 #if (__cplusplus >= 201103L) // C++11
495 *(first + index) = std::move_if_noexcept(*(first + child));
497 swap(*(first + index), *(first + child));
502 if (index <= end_parent + (left_bound ? 0 : 1)) {
503 Offset child = index * 2 + (left_bound ? 2 : 1);
504 if (child < index_end) {
506 if (!left_bound && (child + 1 < index_end)) {
510 swap_required =
compare(*(first + child), *(first + child + 1));
513 #if (__cplusplus >= 201103L)
514 *(first + index) = std::move_if_noexcept(limbo);
520 #if (__cplusplus >= 201103L) // C++11
521 *(first + index) = std::move_if_noexcept(*(first + child));
522 *(first + child) = std::move_if_noexcept(limbo);
524 swap(*(first + index), *(first + child));
528 sift_leaf_min<Iterator, Offset, Compare>(first, last, index,
533 #if (__cplusplus >= 201103L) // C++11
534 *(first + index) = std::move_if_noexcept(*(first + child));
536 swap(*(first + index), *(first + child));
542 #if (__cplusplus >= 201103L) // C++11
543 *(first + index) = std::move_if_noexcept(limbo);
546 sift_leaf_min<Iterator, Offset, Compare>(first, last, index,
compare,
549 sift_leaf_max<Iterator, Offset, Compare>(first, last, index,
compare,
553 while (index > origin) {
554 const Offset
parent = ((index / 2 - 1) | 1) ^ (left_bound ? 1 : 0);
555 swap(*(first + parent), *(first + index));
563 template <
typename Iterator,
typename Compare>
565 typename std::iterator_traits<Iterator>::difference_type index,
571 sift_leaf_max<Iterator, Offset, Compare>(first, last, index,
compare, 2);
573 sift_leaf_min<Iterator, Offset, Compare>(first, last, index,
compare, 2);
579 #endif // BOOST_HEAP_INTERVAL_HEAP_HPP_