| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- // 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/concept/assert.hpp>
- #include <boost/heap/heap_concepts.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/type_traits/conditional.hpp>
- #ifdef BOOST_HEAP_SANITYCHECKS
- # define BOOST_HEAP_ASSERT BOOST_ASSERT
- #else
- # define BOOST_HEAP_ASSERT( expression ) static_assert( true, "force semicolon" )
- #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 )
- {
- (void)rhs;
- 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 )
- {
- (void)rhs;
- 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( ( std::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( ( std::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 std::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 std::conditional< use_ordered_iterators, heap_compare_iteration, heap_compare_copy >::type compare_check;
- compare_check check_object;
- return check_object( lhs, rhs );
- }
- }}} // namespace boost::heap::detail
- #undef BOOST_HEAP_ASSERT
- #endif // BOOST_HEAP_DETAIL_HEAP_COMPARISON_HPP
|