annotate DEPENDENCIES/generic/include/boost/heap/heap_merge.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // boost heap: heap merge algorithms
Chris@16 2 //
Chris@16 3 // Copyright (C) 2011 Tim Blechmann
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #ifndef BOOST_HEAP_MERGE_HPP
Chris@16 10 #define BOOST_HEAP_MERGE_HPP
Chris@16 11
Chris@16 12 #include <boost/concept/assert.hpp>
Chris@16 13 #include <boost/heap/heap_concepts.hpp>
Chris@16 14 #include <boost/type_traits/is_same.hpp>
Chris@16 15
Chris@101 16 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@101 17 #pragma once
Chris@101 18 #endif
Chris@101 19
Chris@101 20
Chris@16 21 namespace boost {
Chris@16 22 namespace heap {
Chris@16 23 namespace detail {
Chris@16 24
Chris@16 25 template <typename Heap1, typename Heap2>
Chris@16 26 struct heap_merge_emulate
Chris@16 27 {
Chris@16 28 struct dummy_reserver
Chris@16 29 {
Chris@16 30 static void reserve (Heap1 & lhs, std::size_t required_size)
Chris@16 31 {}
Chris@16 32 };
Chris@16 33
Chris@16 34 struct reserver
Chris@16 35 {
Chris@16 36 static void reserve (Heap1 & lhs, std::size_t required_size)
Chris@16 37 {
Chris@16 38 lhs.reserve(required_size);
Chris@16 39 }
Chris@16 40 };
Chris@16 41
Chris@16 42 typedef typename boost::mpl::if_c<Heap1::has_reserve,
Chris@16 43 reserver,
Chris@16 44 dummy_reserver>::type space_reserver;
Chris@16 45
Chris@16 46 static void merge(Heap1 & lhs, Heap2 & rhs)
Chris@16 47 {
Chris@16 48 if (Heap1::constant_time_size && Heap2::constant_time_size) {
Chris@16 49 if (Heap1::has_reserve) {
Chris@16 50 std::size_t required_size = lhs.size() + rhs.size();
Chris@16 51 space_reserver::reserve(lhs, required_size);
Chris@16 52 }
Chris@16 53 }
Chris@16 54
Chris@16 55 // FIXME: container adaptors could benefit from first appending all elements and then restoring the heap order
Chris@16 56 // FIXME: optimize: if we have ordered iterators and we can efficiently insert keys with a below the lowest key in the heap
Chris@16 57 // d-ary, b and fibonacci heaps fall into this category
Chris@16 58
Chris@16 59 while (!rhs.empty()) {
Chris@16 60 lhs.push(rhs.top());
Chris@16 61 rhs.pop();
Chris@16 62 }
Chris@16 63
Chris@16 64 lhs.set_stability_count((std::max)(lhs.get_stability_count(),
Chris@16 65 rhs.get_stability_count()));
Chris@16 66 rhs.set_stability_count(0);
Chris@16 67 }
Chris@16 68
Chris@16 69 };
Chris@16 70
Chris@16 71
Chris@16 72 template <typename Heap>
Chris@16 73 struct heap_merge_same_mergable
Chris@16 74 {
Chris@16 75 static void merge(Heap & lhs, Heap & rhs)
Chris@16 76 {
Chris@16 77 lhs.merge(rhs);
Chris@16 78 }
Chris@16 79 };
Chris@16 80
Chris@16 81
Chris@16 82 template <typename Heap>
Chris@16 83 struct heap_merge_same
Chris@16 84 {
Chris@16 85 static const bool is_mergable = Heap::is_mergable;
Chris@16 86 typedef typename boost::mpl::if_c<is_mergable,
Chris@16 87 heap_merge_same_mergable<Heap>,
Chris@16 88 heap_merge_emulate<Heap, Heap>
Chris@16 89 >::type heap_merger;
Chris@16 90
Chris@16 91 static void merge(Heap & lhs, Heap & rhs)
Chris@16 92 {
Chris@16 93 heap_merger::merge(lhs, rhs);
Chris@16 94 }
Chris@16 95 };
Chris@16 96
Chris@16 97 } /* namespace detail */
Chris@16 98
Chris@16 99
Chris@16 100 /** merge rhs into lhs
Chris@16 101 *
Chris@16 102 * \b Effect: lhs contains all elements that have been part of rhs, rhs is empty.
Chris@16 103 *
Chris@16 104 * */
Chris@16 105 template <typename Heap1,
Chris@16 106 typename Heap2
Chris@16 107 >
Chris@16 108 void heap_merge(Heap1 & lhs, Heap2 & rhs)
Chris@16 109 {
Chris@16 110 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>));
Chris@16 111 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>));
Chris@16 112
Chris@16 113 // if this assertion is triggered, the value_compare types are incompatible
Chris@16 114 BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value));
Chris@16 115
Chris@16 116 const bool same_heaps = boost::is_same<Heap1, Heap2>::value;
Chris@16 117
Chris@16 118 typedef typename boost::mpl::if_c<same_heaps,
Chris@16 119 detail::heap_merge_same<Heap1>,
Chris@16 120 detail::heap_merge_emulate<Heap1, Heap2>
Chris@16 121 >::type heap_merger;
Chris@16 122
Chris@16 123 heap_merger::merge(lhs, rhs);
Chris@16 124 }
Chris@16 125
Chris@16 126
Chris@16 127 } /* namespace heap */
Chris@16 128 } /* namespace boost */
Chris@16 129
Chris@16 130 #endif /* BOOST_HEAP_MERGE_HPP */