123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- // boost heap: heap node helper classes
- //
- // Copyright (C) 2010 Tim Blechmann
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP
- #define BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP
- #include <boost/assert.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/concept/assert.hpp>
- #include <boost/heap/heap_concepts.hpp>
- #include <boost/type_traits/conditional.hpp>
- #ifdef BOOST_HEAP_SANITYCHECKS
- #define BOOST_HEAP_ASSERT BOOST_ASSERT
- #else
- #define BOOST_HEAP_ASSERT(expression)
- #endif
- namespace boost {
- namespace heap {
- namespace detail {
- template <typename Heap1, typename Heap2>
- bool value_equality(Heap1 const & lhs, Heap2 const & rhs,
- typename Heap1::value_type lval, typename Heap2::value_type rval)
- {
- typename Heap1::value_compare const & cmp = lhs.value_comp();
- bool ret = !(cmp(lval, rval)) && !(cmp(rval, lval));
- // if this assertion is triggered, the value_compare objects of lhs and rhs return different values
- BOOST_ASSERT((ret == (!(rhs.value_comp()(lval, rval)) && !(rhs.value_comp()(rval, lval)))));
- return ret;
- }
- template <typename Heap1, typename Heap2>
- bool value_compare(Heap1 const & lhs, Heap2 const & rhs,
- typename Heap1::value_type lval, typename Heap2::value_type rval)
- {
- typename Heap1::value_compare const & cmp = lhs.value_comp();
- bool ret = cmp(lval, rval);
- // if this assertion is triggered, the value_compare objects of lhs and rhs return different values
- BOOST_ASSERT((ret == rhs.value_comp()(lval, rval)));
- return ret;
- }
- struct heap_equivalence_copy
- {
- template <typename Heap1, typename Heap2>
- bool operator()(Heap1 const & lhs, Heap2 const & rhs)
- {
- BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>));
- BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>));
- // if this assertion is triggered, the value_compare types are incompatible
- BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value));
- if (Heap1::constant_time_size && Heap2::constant_time_size)
- if (lhs.size() != rhs.size())
- return false;
- if (lhs.empty() && rhs.empty())
- return true;
- Heap1 lhs_copy(lhs);
- Heap2 rhs_copy(rhs);
- while (true) {
- if (!value_equality(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top()))
- return false;
- lhs_copy.pop();
- rhs_copy.pop();
- if (lhs_copy.empty() && rhs_copy.empty())
- return true;
- if (lhs_copy.empty())
- return false;
- if (rhs_copy.empty())
- return false;
- }
- }
- };
- struct heap_equivalence_iteration
- {
- template <typename Heap1, typename Heap2>
- bool operator()(Heap1 const & lhs, Heap2 const & rhs)
- {
- BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>));
- BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>));
- // if this assertion is triggered, the value_compare types are incompatible
- BOOST_STATIC_ASSERT((boost::is_same<typename Heap1::value_compare, typename Heap2::value_compare>::value));
- if (Heap1::constant_time_size && Heap2::constant_time_size)
- if (lhs.size() != rhs.size())
- return false;
- if (lhs.empty() && rhs.empty())
- return true;
- typename Heap1::ordered_iterator it1 = lhs.ordered_begin();
- typename Heap1::ordered_iterator it1_end = lhs.ordered_end();
- typename Heap1::ordered_iterator it2 = rhs.ordered_begin();
- typename Heap1::ordered_iterator it2_end = rhs.ordered_end();
- while (true) {
- if (!value_equality(lhs, rhs, *it1, *it2))
- return false;
- ++it1;
- ++it2;
- if (it1 == it1_end && it2 == it2_end)
- return true;
- if (it1 == it1_end || it2 == it2_end)
- return false;
- }
- }
- };
- template <typename Heap1,
- typename Heap2
- >
- bool heap_equality(Heap1 const & lhs, Heap2 const & rhs)
- {
- const bool use_ordered_iterators = Heap1::has_ordered_iterators && Heap2::has_ordered_iterators;
- typedef typename boost::conditional<use_ordered_iterators,
- heap_equivalence_iteration,
- heap_equivalence_copy
- >::type equivalence_check;
- equivalence_check eq_check;
- return eq_check(lhs, rhs);
- }
- struct heap_compare_iteration
- {
- template <typename Heap1,
- typename Heap2
- >
- bool operator()(Heap1 const & lhs, Heap2 const & rhs)
- {
- typename Heap1::size_type left_size = lhs.size();
- typename Heap2::size_type right_size = rhs.size();
- if (left_size < right_size)
- return true;
- if (left_size > right_size)
- return false;
- typename Heap1::ordered_iterator it1 = lhs.ordered_begin();
- typename Heap1::ordered_iterator it1_end = lhs.ordered_end();
- typename Heap1::ordered_iterator it2 = rhs.ordered_begin();
- typename Heap1::ordered_iterator it2_end = rhs.ordered_end();
- while (true) {
- if (value_compare(lhs, rhs, *it1, *it2))
- return true;
- if (value_compare(lhs, rhs, *it2, *it1))
- return false;
- ++it1;
- ++it2;
- if (it1 == it1_end && it2 == it2_end)
- return true;
- if (it1 == it1_end || it2 == it2_end)
- return false;
- }
- }
- };
- struct heap_compare_copy
- {
- template <typename Heap1,
- typename Heap2
- >
- bool operator()(Heap1 const & lhs, Heap2 const & rhs)
- {
- typename Heap1::size_type left_size = lhs.size();
- typename Heap2::size_type right_size = rhs.size();
- if (left_size < right_size)
- return true;
- if (left_size > right_size)
- return false;
- Heap1 lhs_copy(lhs);
- Heap2 rhs_copy(rhs);
- while (true) {
- if (value_compare(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top()))
- return true;
- if (value_compare(lhs_copy, rhs_copy, rhs_copy.top(), lhs_copy.top()))
- return false;
- lhs_copy.pop();
- rhs_copy.pop();
- if (lhs_copy.empty() && rhs_copy.empty())
- return false;
- }
- }
- };
- template <typename Heap1,
- typename Heap2
- >
- bool heap_compare(Heap1 const & lhs, Heap2 const & rhs)
- {
- const bool use_ordered_iterators = Heap1::has_ordered_iterators && Heap2::has_ordered_iterators;
- typedef typename boost::conditional<use_ordered_iterators,
- heap_compare_iteration,
- heap_compare_copy
- >::type compare_check;
- compare_check check_object;
- return check_object(lhs, rhs);
- }
- } /* namespace detail */
- } /* namespace heap */
- } /* namespace boost */
- #undef BOOST_HEAP_ASSERT
- #endif // BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP
|