mirror of
https://github.com/boostorg/heap.git
synced 2026-01-19 04:12:12 +00:00
cleanup: run clang-format
This commit is contained in:
@@ -52,4 +52,4 @@ build: off
|
||||
test_script:
|
||||
- PATH=%ADDPATH%%PATH%
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- b2 -j 3 libs/heap/test toolset=%TOOLSET% %CXXSTD%
|
||||
- b2 -j 3 libs/heap/test toolset=%TOOLSET% %CXXSTD%
|
||||
|
||||
@@ -419,4 +419,4 @@ The data structures can be configured with [@boost:/libs/parameter/doc/html/inde
|
||||
[For mentoring the Summer of Code project]
|
||||
]
|
||||
]
|
||||
[endsect]
|
||||
[endsect]
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include "../../../boost/heap/fibonacci_heap.hpp"
|
||||
|
||||
@@ -17,14 +17,14 @@ using namespace boost::heap;
|
||||
|
||||
//[ basic_interface
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void basic_interface(void)
|
||||
template < typename PriorityQueue >
|
||||
void basic_interface( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
|
||||
pq.push(2);
|
||||
pq.push(3);
|
||||
pq.push(1);
|
||||
pq.push( 2 );
|
||||
pq.push( 3 );
|
||||
pq.push( 1 );
|
||||
|
||||
cout << "Priority Queue: popped elements" << endl;
|
||||
cout << pq.top() << " "; // 3
|
||||
@@ -39,20 +39,20 @@ void basic_interface(void)
|
||||
|
||||
//[ iterator_interface
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void iterator_interface(void)
|
||||
template < typename PriorityQueue >
|
||||
void iterator_interface( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
|
||||
pq.push(2);
|
||||
pq.push(3);
|
||||
pq.push(1);
|
||||
pq.push( 2 );
|
||||
pq.push( 3 );
|
||||
pq.push( 1 );
|
||||
|
||||
typename PriorityQueue::iterator begin = pq.begin();
|
||||
typename PriorityQueue::iterator end = pq.end();
|
||||
typename PriorityQueue::iterator end = pq.end();
|
||||
|
||||
cout << "Priority Queue: iteration" << endl;
|
||||
for (typename PriorityQueue::iterator it = begin; it != end; ++it)
|
||||
for ( typename PriorityQueue::iterator it = begin; it != end; ++it )
|
||||
cout << *it << " "; // 1, 2, 3 in unspecified order
|
||||
cout << endl;
|
||||
}
|
||||
@@ -60,20 +60,20 @@ void iterator_interface(void)
|
||||
|
||||
//[ ordered_iterator_interface
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void ordered_iterator_interface(void)
|
||||
template < typename PriorityQueue >
|
||||
void ordered_iterator_interface( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
|
||||
pq.push(2);
|
||||
pq.push(3);
|
||||
pq.push(1);
|
||||
pq.push( 2 );
|
||||
pq.push( 3 );
|
||||
pq.push( 1 );
|
||||
|
||||
typename PriorityQueue::ordered_iterator begin = pq.ordered_begin();
|
||||
typename PriorityQueue::ordered_iterator end = pq.ordered_end();
|
||||
typename PriorityQueue::ordered_iterator end = pq.ordered_end();
|
||||
|
||||
cout << "Priority Queue: ordered iteration" << endl;
|
||||
for (typename PriorityQueue::ordered_iterator it = begin; it != end; ++it)
|
||||
for ( typename PriorityQueue::ordered_iterator it = begin; it != end; ++it )
|
||||
cout << *it << " "; // 3, 2, 1 (i.e. 1, 2, 3 in heap order)
|
||||
cout << endl;
|
||||
}
|
||||
@@ -82,33 +82,33 @@ void ordered_iterator_interface(void)
|
||||
|
||||
//[ merge_interface
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void merge_interface(void)
|
||||
template < typename PriorityQueue >
|
||||
void merge_interface( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
|
||||
pq.push(3);
|
||||
pq.push(5);
|
||||
pq.push(1);
|
||||
pq.push( 3 );
|
||||
pq.push( 5 );
|
||||
pq.push( 1 );
|
||||
|
||||
PriorityQueue pq2;
|
||||
|
||||
pq2.push(2);
|
||||
pq2.push(4);
|
||||
pq2.push(0);
|
||||
pq2.push( 2 );
|
||||
pq2.push( 4 );
|
||||
pq2.push( 0 );
|
||||
|
||||
pq.merge(pq2);
|
||||
pq.merge( pq2 );
|
||||
|
||||
cout << "Priority Queue: merge" << endl;
|
||||
cout << "first queue: ";
|
||||
while (!pq.empty()) {
|
||||
while ( !pq.empty() ) {
|
||||
cout << pq.top() << " "; // 5 4 3 2 1 0
|
||||
pq.pop();
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "second queue: ";
|
||||
while (!pq2.empty()) {
|
||||
while ( !pq2.empty() ) {
|
||||
cout << pq2.top() << " "; // 4 2 0
|
||||
pq2.pop();
|
||||
}
|
||||
@@ -118,33 +118,33 @@ void merge_interface(void)
|
||||
|
||||
//[ heap_merge_algorithm
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void heap_merge_algorithm(void)
|
||||
template < typename PriorityQueue >
|
||||
void heap_merge_algorithm( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
|
||||
pq.push(3);
|
||||
pq.push(5);
|
||||
pq.push(1);
|
||||
pq.push( 3 );
|
||||
pq.push( 5 );
|
||||
pq.push( 1 );
|
||||
|
||||
PriorityQueue pq2;
|
||||
|
||||
pq2.push(2);
|
||||
pq2.push(4);
|
||||
pq2.push(0);
|
||||
pq2.push( 2 );
|
||||
pq2.push( 4 );
|
||||
pq2.push( 0 );
|
||||
|
||||
boost::heap::heap_merge(pq, pq2);
|
||||
boost::heap::heap_merge( pq, pq2 );
|
||||
|
||||
cout << "Priority Queue: merge" << endl;
|
||||
cout << "first queue: ";
|
||||
while (!pq.empty()) {
|
||||
while ( !pq.empty() ) {
|
||||
cout << pq.top() << " "; // 5 4 3 2 1 0
|
||||
pq.pop();
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "second queue: ";
|
||||
while (!pq2.empty()) {
|
||||
while ( !pq2.empty() ) {
|
||||
cout << pq2.top() << " "; // 4 2 0
|
||||
pq2.pop();
|
||||
}
|
||||
@@ -154,22 +154,22 @@ void heap_merge_algorithm(void)
|
||||
|
||||
//[ mutable_interface
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void mutable_interface(void)
|
||||
template < typename PriorityQueue >
|
||||
void mutable_interface( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
PriorityQueue pq;
|
||||
typedef typename PriorityQueue::handle_type handle_t;
|
||||
|
||||
handle_t t3 = pq.push(3);
|
||||
handle_t t5 = pq.push(5);
|
||||
handle_t t1 = pq.push(1);
|
||||
handle_t t3 = pq.push( 3 );
|
||||
handle_t t5 = pq.push( 5 );
|
||||
handle_t t1 = pq.push( 1 );
|
||||
|
||||
pq.update(t3, 4);
|
||||
pq.increase(t5, 7);
|
||||
pq.decrease(t1, 0);
|
||||
pq.update( t3, 4 );
|
||||
pq.increase( t5, 7 );
|
||||
pq.decrease( t1, 0 );
|
||||
|
||||
cout << "Priority Queue: update" << endl;
|
||||
while (!pq.empty()) {
|
||||
while ( !pq.empty() ) {
|
||||
cout << pq.top() << " "; // 7, 4, 0
|
||||
pq.pop();
|
||||
}
|
||||
@@ -179,27 +179,27 @@ void mutable_interface(void)
|
||||
|
||||
//[ mutable_fixup_interface
|
||||
// PriorityQueue is expected to be a max-heap of integer values
|
||||
template <typename PriorityQueue>
|
||||
void mutable_fixup_interface(void)
|
||||
template < typename PriorityQueue >
|
||||
void mutable_fixup_interface( void )
|
||||
{
|
||||
PriorityQueue pq;
|
||||
PriorityQueue pq;
|
||||
typedef typename PriorityQueue::handle_type handle_t;
|
||||
|
||||
handle_t t3 = pq.push(3);
|
||||
handle_t t5 = pq.push(5);
|
||||
handle_t t1 = pq.push(1);
|
||||
handle_t t3 = pq.push( 3 );
|
||||
handle_t t5 = pq.push( 5 );
|
||||
handle_t t1 = pq.push( 1 );
|
||||
|
||||
*t3 = 4;
|
||||
pq.update(t3);
|
||||
pq.update( t3 );
|
||||
|
||||
*t5 = 7;
|
||||
pq.increase(t5);
|
||||
pq.increase( t5 );
|
||||
|
||||
*t1 = 0;
|
||||
pq.decrease(t1);
|
||||
pq.decrease( t1 );
|
||||
|
||||
cout << "Priority Queue: update with fixup" << endl;
|
||||
while (!pq.empty()) {
|
||||
while ( !pq.empty() ) {
|
||||
cout << pq.top() << " "; // 7, 4, 0
|
||||
pq.pop();
|
||||
}
|
||||
@@ -210,52 +210,52 @@ void mutable_fixup_interface(void)
|
||||
//[ mutable_interface_handle_in_value
|
||||
struct heap_data
|
||||
{
|
||||
fibonacci_heap<heap_data>::handle_type handle;
|
||||
int payload;
|
||||
fibonacci_heap< heap_data >::handle_type handle;
|
||||
int payload;
|
||||
|
||||
heap_data(int i):
|
||||
payload(i)
|
||||
heap_data( int i ) :
|
||||
payload( i )
|
||||
{}
|
||||
|
||||
bool operator<(heap_data const & rhs) const
|
||||
bool operator<( heap_data const& rhs ) const
|
||||
{
|
||||
return payload < rhs.payload;
|
||||
}
|
||||
};
|
||||
|
||||
void mutable_interface_handle_in_value(void)
|
||||
void mutable_interface_handle_in_value( void )
|
||||
{
|
||||
fibonacci_heap<heap_data> heap;
|
||||
heap_data f(2);
|
||||
fibonacci_heap< heap_data > heap;
|
||||
heap_data f( 2 );
|
||||
|
||||
fibonacci_heap<heap_data>::handle_type handle = heap.push(f);
|
||||
(*handle).handle = handle; // store handle in node
|
||||
fibonacci_heap< heap_data >::handle_type handle = heap.push( f );
|
||||
( *handle ).handle = handle; // store handle in node
|
||||
}
|
||||
//]
|
||||
|
||||
|
||||
int main(void)
|
||||
int main( void )
|
||||
{
|
||||
using boost::heap::fibonacci_heap;
|
||||
|
||||
cout << std::setw(2);
|
||||
cout << std::setw( 2 );
|
||||
|
||||
basic_interface<fibonacci_heap<int> >();
|
||||
basic_interface< fibonacci_heap< int > >();
|
||||
cout << endl;
|
||||
|
||||
iterator_interface<fibonacci_heap<int> >();
|
||||
iterator_interface< fibonacci_heap< int > >();
|
||||
cout << endl;
|
||||
|
||||
ordered_iterator_interface<fibonacci_heap<int> >();
|
||||
ordered_iterator_interface< fibonacci_heap< int > >();
|
||||
cout << endl;
|
||||
|
||||
merge_interface<fibonacci_heap<int> >();
|
||||
merge_interface< fibonacci_heap< int > >();
|
||||
cout << endl;
|
||||
|
||||
mutable_interface<fibonacci_heap<int> >();
|
||||
mutable_interface< fibonacci_heap< int > >();
|
||||
cout << endl;
|
||||
|
||||
mutable_fixup_interface<fibonacci_heap<int> >();
|
||||
mutable_fixup_interface< fibonacci_heap< int > >();
|
||||
|
||||
mutable_interface_handle_in_value();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -10,81 +10,77 @@
|
||||
#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/static_assert.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
|
||||
#ifdef BOOST_HEAP_SANITYCHECKS
|
||||
#define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
# define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
#else
|
||||
#define BOOST_HEAP_ASSERT(expression)
|
||||
# define BOOST_HEAP_ASSERT( expression )
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace detail {
|
||||
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)
|
||||
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));
|
||||
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)))));
|
||||
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)
|
||||
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);
|
||||
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)));
|
||||
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)
|
||||
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>));
|
||||
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));
|
||||
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())
|
||||
if ( Heap1::constant_time_size && Heap2::constant_time_size )
|
||||
if ( lhs.size() != rhs.size() )
|
||||
return false;
|
||||
|
||||
if (lhs.empty() && rhs.empty())
|
||||
if ( lhs.empty() && rhs.empty() )
|
||||
return true;
|
||||
|
||||
Heap1 lhs_copy(lhs);
|
||||
Heap2 rhs_copy(rhs);
|
||||
Heap1 lhs_copy( lhs );
|
||||
Heap2 rhs_copy( rhs );
|
||||
|
||||
while (true) {
|
||||
if (!value_equality(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top()))
|
||||
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())
|
||||
if ( lhs_copy.empty() && rhs_copy.empty() )
|
||||
return true;
|
||||
|
||||
if (lhs_copy.empty())
|
||||
if ( lhs_copy.empty() )
|
||||
return false;
|
||||
|
||||
if (rhs_copy.empty())
|
||||
if ( rhs_copy.empty() )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -93,93 +89,87 @@ struct heap_equivalence_copy
|
||||
|
||||
struct heap_equivalence_iteration
|
||||
{
|
||||
template <typename Heap1, typename Heap2>
|
||||
bool operator()(Heap1 const & lhs, Heap2 const & rhs)
|
||||
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>));
|
||||
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));
|
||||
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())
|
||||
if ( Heap1::constant_time_size && Heap2::constant_time_size )
|
||||
if ( lhs.size() != rhs.size() )
|
||||
return false;
|
||||
|
||||
if (lhs.empty() && rhs.empty())
|
||||
if ( lhs.empty() && rhs.empty() )
|
||||
return true;
|
||||
|
||||
typename Heap1::ordered_iterator it1 = lhs.ordered_begin();
|
||||
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 = rhs.ordered_begin();
|
||||
typename Heap1::ordered_iterator it2_end = rhs.ordered_end();
|
||||
while (true) {
|
||||
if (!value_equality(lhs, rhs, *it1, *it2))
|
||||
while ( true ) {
|
||||
if ( !value_equality( lhs, rhs, *it1, *it2 ) )
|
||||
return false;
|
||||
|
||||
++it1;
|
||||
++it2;
|
||||
|
||||
if (it1 == it1_end && it2 == it2_end)
|
||||
if ( it1 == it1_end && it2 == it2_end )
|
||||
return true;
|
||||
|
||||
if (it1 == it1_end || it2 == it2_end)
|
||||
if ( it1 == it1_end || it2 == it2_end )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Heap1,
|
||||
typename Heap2
|
||||
>
|
||||
bool heap_equality(Heap1 const & lhs, Heap2 const & rhs)
|
||||
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;
|
||||
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);
|
||||
return eq_check( lhs, rhs );
|
||||
}
|
||||
|
||||
|
||||
struct heap_compare_iteration
|
||||
{
|
||||
template <typename Heap1,
|
||||
typename Heap2
|
||||
>
|
||||
bool operator()(Heap1 const & lhs, Heap2 const & rhs)
|
||||
template < typename Heap1, typename Heap2 >
|
||||
bool operator()( Heap1 const& lhs, Heap2 const& rhs )
|
||||
{
|
||||
typename Heap1::size_type left_size = lhs.size();
|
||||
typename Heap1::size_type left_size = lhs.size();
|
||||
typename Heap2::size_type right_size = rhs.size();
|
||||
if (left_size < right_size)
|
||||
if ( left_size < right_size )
|
||||
return true;
|
||||
|
||||
if (left_size > right_size)
|
||||
if ( left_size > right_size )
|
||||
return false;
|
||||
|
||||
typename Heap1::ordered_iterator it1 = lhs.ordered_begin();
|
||||
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 = rhs.ordered_begin();
|
||||
typename Heap1::ordered_iterator it2_end = rhs.ordered_end();
|
||||
while (true) {
|
||||
if (value_compare(lhs, rhs, *it1, *it2))
|
||||
while ( true ) {
|
||||
if ( value_compare( lhs, rhs, *it1, *it2 ) )
|
||||
return true;
|
||||
|
||||
if (value_compare(lhs, rhs, *it2, *it1))
|
||||
if ( value_compare( lhs, rhs, *it2, *it1 ) )
|
||||
return false;
|
||||
|
||||
++it1;
|
||||
++it2;
|
||||
|
||||
if (it1 == it1_end && it2 == it2_end)
|
||||
if ( it1 == it1_end && it2 == it2_end )
|
||||
return true;
|
||||
|
||||
if (it1 == it1_end || it2 == it2_end)
|
||||
if ( it1 == it1_end || it2 == it2_end )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -187,58 +177,50 @@ struct heap_compare_iteration
|
||||
|
||||
struct heap_compare_copy
|
||||
{
|
||||
template <typename Heap1,
|
||||
typename Heap2
|
||||
>
|
||||
bool operator()(Heap1 const & lhs, Heap2 const & rhs)
|
||||
template < typename Heap1, typename Heap2 >
|
||||
bool operator()( Heap1 const& lhs, Heap2 const& rhs )
|
||||
{
|
||||
typename Heap1::size_type left_size = lhs.size();
|
||||
typename Heap1::size_type left_size = lhs.size();
|
||||
typename Heap2::size_type right_size = rhs.size();
|
||||
if (left_size < right_size)
|
||||
if ( left_size < right_size )
|
||||
return true;
|
||||
|
||||
if (left_size > right_size)
|
||||
if ( left_size > right_size )
|
||||
return false;
|
||||
|
||||
Heap1 lhs_copy(lhs);
|
||||
Heap2 rhs_copy(rhs);
|
||||
Heap1 lhs_copy( lhs );
|
||||
Heap2 rhs_copy( rhs );
|
||||
|
||||
while (true) {
|
||||
if (value_compare(lhs_copy, rhs_copy, lhs_copy.top(), rhs_copy.top()))
|
||||
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()))
|
||||
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())
|
||||
if ( lhs_copy.empty() && rhs_copy.empty() )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Heap1,
|
||||
typename Heap2
|
||||
>
|
||||
bool heap_compare(Heap1 const & lhs, Heap2 const & rhs)
|
||||
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;
|
||||
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);
|
||||
return check_object( lhs, rhs );
|
||||
}
|
||||
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}}} // namespace boost::heap::detail
|
||||
|
||||
|
||||
#undef BOOST_HEAP_ASSERT
|
||||
|
||||
@@ -10,81 +10,76 @@
|
||||
#define BOOST_HEAP_DETAIL_HEAP_NODE_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
|
||||
#ifdef BOOST_HEAP_SANITYCHECKS
|
||||
#define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
# define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
#else
|
||||
#define BOOST_HEAP_ASSERT(expression)
|
||||
# define BOOST_HEAP_ASSERT( expression )
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace detail {
|
||||
namespace boost { namespace heap { namespace detail {
|
||||
|
||||
namespace bi = boost::intrusive;
|
||||
|
||||
template <bool auto_unlink = false>
|
||||
struct heap_node_base:
|
||||
bi::list_base_hook<typename boost::conditional<auto_unlink,
|
||||
bi::link_mode<bi::auto_unlink>,
|
||||
bi::link_mode<bi::safe_link>
|
||||
>::type
|
||||
>
|
||||
template < bool auto_unlink = false >
|
||||
struct heap_node_base :
|
||||
bi::list_base_hook<
|
||||
typename boost::conditional< auto_unlink, bi::link_mode< bi::auto_unlink >, bi::link_mode< bi::safe_link > >::type >
|
||||
{};
|
||||
|
||||
typedef bi::list<heap_node_base<false> > heap_node_list;
|
||||
typedef bi::list< heap_node_base< false > > heap_node_list;
|
||||
|
||||
struct nop_disposer
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(T * n)
|
||||
template < typename T >
|
||||
void operator()( T* n )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(false);
|
||||
BOOST_HEAP_ASSERT( false );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Node, typename HeapBase>
|
||||
bool is_heap(const Node * n, typename HeapBase::value_compare const & cmp)
|
||||
template < typename Node, typename HeapBase >
|
||||
bool is_heap( const Node* n, typename HeapBase::value_compare const& cmp )
|
||||
{
|
||||
for (typename Node::const_child_iterator it = n->children.begin(); it != n->children.end(); ++it) {
|
||||
Node const & this_node = static_cast<Node const &>(*it);
|
||||
const Node * child = static_cast<const Node*>(&this_node);
|
||||
for ( typename Node::const_child_iterator it = n->children.begin(); it != n->children.end(); ++it ) {
|
||||
Node const& this_node = static_cast< Node const& >( *it );
|
||||
const Node* child = static_cast< const Node* >( &this_node );
|
||||
|
||||
if (cmp(HeapBase::get_value(n->value), HeapBase::get_value(child->value)) ||
|
||||
!is_heap<Node, HeapBase>(child, cmp))
|
||||
if ( cmp( HeapBase::get_value( n->value ), HeapBase::get_value( child->value ) )
|
||||
|| !is_heap< Node, HeapBase >( child, cmp ) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Node>
|
||||
std::size_t count_nodes(const Node * n);
|
||||
template < typename Node >
|
||||
std::size_t count_nodes( const Node* n );
|
||||
|
||||
template <typename Node, typename List>
|
||||
std::size_t count_list_nodes(List const & node_list)
|
||||
template < typename Node, typename List >
|
||||
std::size_t count_list_nodes( List const& node_list )
|
||||
{
|
||||
std::size_t ret = 0;
|
||||
|
||||
for (typename List::const_iterator it = node_list.begin(); it != node_list.end(); ++it) {
|
||||
const Node * child = static_cast<const Node*>(&*it);
|
||||
ret += count_nodes<Node>(child);
|
||||
for ( typename List::const_iterator it = node_list.begin(); it != node_list.end(); ++it ) {
|
||||
const Node* child = static_cast< const Node* >( &*it );
|
||||
ret += count_nodes< Node >( child );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Node>
|
||||
std::size_t count_nodes(const Node * n)
|
||||
template < typename Node >
|
||||
std::size_t count_nodes( const Node* n )
|
||||
{
|
||||
return 1 + count_list_nodes<Node, typename Node::child_list>(n->children);
|
||||
return 1 + count_list_nodes< Node, typename Node::child_list >( n->children );
|
||||
}
|
||||
|
||||
template<class Node>
|
||||
void destroy_node(Node& node)
|
||||
template < class Node >
|
||||
void destroy_node( Node& node )
|
||||
{
|
||||
node.~Node();
|
||||
}
|
||||
@@ -100,31 +95,29 @@ void destroy_node(Node& node)
|
||||
* Node::Node(Node const &, Alloc &, Node * parent)
|
||||
*
|
||||
* */
|
||||
template <typename Node,
|
||||
typename NodeBase,
|
||||
typename Alloc>
|
||||
template < typename Node, typename NodeBase, typename Alloc >
|
||||
struct node_cloner
|
||||
{
|
||||
node_cloner(Alloc & allocator):
|
||||
allocator(allocator)
|
||||
node_cloner( Alloc& allocator ) :
|
||||
allocator( allocator )
|
||||
{}
|
||||
|
||||
Node * operator() (NodeBase const & node)
|
||||
Node* operator()( NodeBase const& node )
|
||||
{
|
||||
Node * ret = allocator.allocate(1);
|
||||
new (ret) Node(static_cast<Node const &>(node), allocator);
|
||||
Node* ret = allocator.allocate( 1 );
|
||||
new ( ret ) Node( static_cast< Node const& >( node ), allocator );
|
||||
return ret;
|
||||
}
|
||||
|
||||
Node * operator() (NodeBase const & node, Node * parent)
|
||||
Node* operator()( NodeBase const& node, Node* parent )
|
||||
{
|
||||
Node * ret = allocator.allocate(1);
|
||||
new (ret) Node(static_cast<Node const &>(node), allocator, parent);
|
||||
Node* ret = allocator.allocate( 1 );
|
||||
new ( ret ) Node( static_cast< Node const& >( node ), allocator, parent );
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
Alloc & allocator;
|
||||
Alloc& allocator;
|
||||
};
|
||||
|
||||
/* node disposer
|
||||
@@ -133,241 +126,238 @@ private:
|
||||
* Node::clear_subtree(Alloc &) clears the subtree via allocator
|
||||
*
|
||||
* */
|
||||
template <typename Node,
|
||||
typename NodeBase,
|
||||
typename Alloc>
|
||||
template < typename Node, typename NodeBase, typename Alloc >
|
||||
struct node_disposer
|
||||
{
|
||||
typedef typename boost::allocator_pointer<Alloc>::type node_pointer;
|
||||
typedef typename boost::allocator_pointer< Alloc >::type node_pointer;
|
||||
|
||||
node_disposer(Alloc & alloc):
|
||||
alloc_(alloc)
|
||||
node_disposer( Alloc& alloc ) :
|
||||
alloc_( alloc )
|
||||
{}
|
||||
|
||||
void operator()(NodeBase * base)
|
||||
void operator()( NodeBase* base )
|
||||
{
|
||||
node_pointer n = static_cast<node_pointer>(base);
|
||||
n->clear_subtree(alloc_);
|
||||
boost::heap::detail::destroy_node(*n);
|
||||
alloc_.deallocate(n, 1);
|
||||
node_pointer n = static_cast< node_pointer >( base );
|
||||
n->clear_subtree( alloc_ );
|
||||
boost::heap::detail::destroy_node( *n );
|
||||
alloc_.deallocate( n, 1 );
|
||||
}
|
||||
|
||||
Alloc & alloc_;
|
||||
Alloc& alloc_;
|
||||
};
|
||||
|
||||
|
||||
template <typename ValueType,
|
||||
bool constant_time_child_size = true
|
||||
>
|
||||
struct heap_node:
|
||||
heap_node_base<!constant_time_child_size>
|
||||
template < typename ValueType, bool constant_time_child_size = true >
|
||||
struct heap_node : heap_node_base< !constant_time_child_size >
|
||||
{
|
||||
typedef heap_node_base<!constant_time_child_size> node_base;
|
||||
typedef heap_node_base< !constant_time_child_size > node_base;
|
||||
|
||||
public:
|
||||
typedef ValueType value_type;
|
||||
|
||||
typedef bi::list<node_base,
|
||||
bi::constant_time_size<constant_time_child_size> > child_list;
|
||||
typedef bi::list< node_base, bi::constant_time_size< constant_time_child_size > > child_list;
|
||||
|
||||
typedef typename child_list::iterator child_iterator;
|
||||
typedef typename child_list::iterator child_iterator;
|
||||
typedef typename child_list::const_iterator const_child_iterator;
|
||||
typedef typename child_list::size_type size_type;
|
||||
typedef typename child_list::size_type size_type;
|
||||
|
||||
heap_node(ValueType const & v):
|
||||
value(v)
|
||||
heap_node( ValueType const& v ) :
|
||||
value( v )
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
heap_node(Args&&... args):
|
||||
value(std::forward<Args>(args)...)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
heap_node( Args&&... args ) :
|
||||
value( std::forward< Args >( args )... )
|
||||
{}
|
||||
#endif
|
||||
|
||||
/* protected: */
|
||||
heap_node(heap_node const & rhs):
|
||||
value(rhs.value)
|
||||
/* protected: */
|
||||
heap_node( heap_node const& rhs ) :
|
||||
value( rhs.value )
|
||||
{
|
||||
/* we don't copy the child list, but clone it later */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template <typename Alloc>
|
||||
heap_node (heap_node const & rhs, Alloc & allocator):
|
||||
value(rhs.value)
|
||||
template < typename Alloc >
|
||||
heap_node( heap_node const& rhs, Alloc& allocator ) :
|
||||
value( rhs.value )
|
||||
{
|
||||
children.clone_from(rhs.children, node_cloner<heap_node, node_base, Alloc>(allocator), nop_disposer());
|
||||
children.clone_from( rhs.children, node_cloner< heap_node, node_base, Alloc >( allocator ), nop_disposer() );
|
||||
}
|
||||
|
||||
size_type child_count(void) const
|
||||
size_type child_count( void ) const
|
||||
{
|
||||
BOOST_STATIC_ASSERT(constant_time_child_size);
|
||||
BOOST_STATIC_ASSERT( constant_time_child_size );
|
||||
return children.size();
|
||||
}
|
||||
|
||||
void add_child(heap_node * n)
|
||||
void add_child( heap_node* n )
|
||||
{
|
||||
children.push_back(*n);
|
||||
children.push_back( *n );
|
||||
}
|
||||
|
||||
template <typename Alloc>
|
||||
void clear_subtree(Alloc & alloc)
|
||||
template < typename Alloc >
|
||||
void clear_subtree( Alloc& alloc )
|
||||
{
|
||||
children.clear_and_dispose(node_disposer<heap_node, node_base, Alloc>(alloc));
|
||||
children.clear_and_dispose( node_disposer< heap_node, node_base, Alloc >( alloc ) );
|
||||
}
|
||||
|
||||
void swap_children(heap_node * rhs)
|
||||
void swap_children( heap_node* rhs )
|
||||
{
|
||||
children.swap(rhs->children);
|
||||
children.swap( rhs->children );
|
||||
}
|
||||
|
||||
ValueType value;
|
||||
ValueType value;
|
||||
child_list children;
|
||||
};
|
||||
|
||||
template <typename value_type>
|
||||
struct parent_pointing_heap_node:
|
||||
heap_node<value_type>
|
||||
template < typename value_type >
|
||||
struct parent_pointing_heap_node : heap_node< value_type >
|
||||
{
|
||||
typedef heap_node<value_type> super_t;
|
||||
typedef heap_node< value_type > super_t;
|
||||
|
||||
parent_pointing_heap_node(value_type const & v):
|
||||
super_t(v), parent(NULL)
|
||||
parent_pointing_heap_node( value_type const& v ) :
|
||||
super_t( v ),
|
||||
parent( NULL )
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
parent_pointing_heap_node(Args&&... args):
|
||||
super_t(std::forward<Args>(args)...), parent(NULL)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
parent_pointing_heap_node( Args&&... args ) :
|
||||
super_t( std::forward< Args >( args )... ),
|
||||
parent( NULL )
|
||||
{}
|
||||
#endif
|
||||
|
||||
template <typename Alloc>
|
||||
template < typename Alloc >
|
||||
struct node_cloner
|
||||
{
|
||||
node_cloner(Alloc & allocator, parent_pointing_heap_node * parent):
|
||||
allocator(allocator), parent_(parent)
|
||||
node_cloner( Alloc& allocator, parent_pointing_heap_node* parent ) :
|
||||
allocator( allocator ),
|
||||
parent_( parent )
|
||||
{}
|
||||
|
||||
parent_pointing_heap_node * operator() (typename super_t::node_base const & node)
|
||||
parent_pointing_heap_node* operator()( typename super_t::node_base const& node )
|
||||
{
|
||||
parent_pointing_heap_node * ret = allocator.allocate(1);
|
||||
new (ret) parent_pointing_heap_node(static_cast<parent_pointing_heap_node const &>(node), allocator, parent_);
|
||||
parent_pointing_heap_node* ret = allocator.allocate( 1 );
|
||||
new ( ret )
|
||||
parent_pointing_heap_node( static_cast< parent_pointing_heap_node const& >( node ), allocator, parent_ );
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
Alloc & allocator;
|
||||
parent_pointing_heap_node * parent_;
|
||||
Alloc& allocator;
|
||||
parent_pointing_heap_node* parent_;
|
||||
};
|
||||
|
||||
template <typename Alloc>
|
||||
parent_pointing_heap_node (parent_pointing_heap_node const & rhs, Alloc & allocator, parent_pointing_heap_node * parent):
|
||||
super_t(static_cast<super_t const &>(rhs)), parent(parent)
|
||||
template < typename Alloc >
|
||||
parent_pointing_heap_node( parent_pointing_heap_node const& rhs,
|
||||
Alloc& allocator,
|
||||
parent_pointing_heap_node* parent ) :
|
||||
super_t( static_cast< super_t const& >( rhs ) ),
|
||||
parent( parent )
|
||||
{
|
||||
super_t::children.clone_from(rhs.children, node_cloner<Alloc>(allocator, this), nop_disposer());
|
||||
super_t::children.clone_from( rhs.children, node_cloner< Alloc >( allocator, this ), nop_disposer() );
|
||||
}
|
||||
|
||||
void update_children(void)
|
||||
void update_children( void )
|
||||
{
|
||||
typedef heap_node_list::iterator node_list_iterator;
|
||||
for (node_list_iterator it = super_t::children.begin(); it != super_t::children.end(); ++it) {
|
||||
parent_pointing_heap_node * child = static_cast<parent_pointing_heap_node*>(&*it);
|
||||
child->parent = this;
|
||||
for ( node_list_iterator it = super_t::children.begin(); it != super_t::children.end(); ++it ) {
|
||||
parent_pointing_heap_node* child = static_cast< parent_pointing_heap_node* >( &*it );
|
||||
child->parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void remove_from_parent(void)
|
||||
void remove_from_parent( void )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(parent);
|
||||
parent->children.erase(heap_node_list::s_iterator_to(*this));
|
||||
BOOST_HEAP_ASSERT( parent );
|
||||
parent->children.erase( heap_node_list::s_iterator_to( *this ) );
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
void add_child(parent_pointing_heap_node * n)
|
||||
void add_child( parent_pointing_heap_node* n )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(n->parent == NULL);
|
||||
BOOST_HEAP_ASSERT( n->parent == NULL );
|
||||
n->parent = this;
|
||||
super_t::add_child(n);
|
||||
super_t::add_child( n );
|
||||
}
|
||||
|
||||
parent_pointing_heap_node * get_parent(void)
|
||||
parent_pointing_heap_node* get_parent( void )
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
const parent_pointing_heap_node * get_parent(void) const
|
||||
const parent_pointing_heap_node* get_parent( void ) const
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
parent_pointing_heap_node * parent;
|
||||
parent_pointing_heap_node* parent;
|
||||
};
|
||||
|
||||
|
||||
template <typename value_type>
|
||||
struct marked_heap_node:
|
||||
parent_pointing_heap_node<value_type>
|
||||
template < typename value_type >
|
||||
struct marked_heap_node : parent_pointing_heap_node< value_type >
|
||||
{
|
||||
typedef parent_pointing_heap_node<value_type> super_t;
|
||||
typedef parent_pointing_heap_node< value_type > super_t;
|
||||
|
||||
marked_heap_node(value_type const & v):
|
||||
super_t(v), mark(false)
|
||||
marked_heap_node( value_type const& v ) :
|
||||
super_t( v ),
|
||||
mark( false )
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
marked_heap_node(Args&&... args):
|
||||
super_t(std::forward<Args>(args)...), mark(false)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
marked_heap_node( Args&&... args ) :
|
||||
super_t( std::forward< Args >( args )... ),
|
||||
mark( false )
|
||||
{}
|
||||
#endif
|
||||
|
||||
marked_heap_node * get_parent(void)
|
||||
marked_heap_node* get_parent( void )
|
||||
{
|
||||
return static_cast<marked_heap_node*>(super_t::parent);
|
||||
return static_cast< marked_heap_node* >( super_t::parent );
|
||||
}
|
||||
|
||||
const marked_heap_node * get_parent(void) const
|
||||
const marked_heap_node* get_parent( void ) const
|
||||
{
|
||||
return static_cast<marked_heap_node*>(super_t::parent);
|
||||
return static_cast< marked_heap_node* >( super_t::parent );
|
||||
}
|
||||
|
||||
bool mark;
|
||||
};
|
||||
|
||||
|
||||
template <typename Node>
|
||||
template < typename Node >
|
||||
struct cmp_by_degree
|
||||
{
|
||||
template <typename NodeBase>
|
||||
bool operator()(NodeBase const & left,
|
||||
NodeBase const & right)
|
||||
template < typename NodeBase >
|
||||
bool operator()( NodeBase const& left, NodeBase const& right )
|
||||
{
|
||||
return static_cast<const Node*>(&left)->child_count() < static_cast<const Node*>(&right)->child_count();
|
||||
return static_cast< const Node* >( &left )->child_count() < static_cast< const Node* >( &right )->child_count();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename List, typename Node, typename Cmp>
|
||||
Node * find_max_child(List const & list, Cmp const & cmp)
|
||||
template < typename List, typename Node, typename Cmp >
|
||||
Node* find_max_child( List const& list, Cmp const& cmp )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(!list.empty());
|
||||
BOOST_HEAP_ASSERT( !list.empty() );
|
||||
|
||||
const Node * ret = static_cast<const Node *> (&list.front());
|
||||
for (typename List::const_iterator it = list.begin(); it != list.end(); ++it) {
|
||||
const Node * current = static_cast<const Node *> (&*it);
|
||||
const Node* ret = static_cast< const Node* >( &list.front() );
|
||||
for ( typename List::const_iterator it = list.begin(); it != list.end(); ++it ) {
|
||||
const Node* current = static_cast< const Node* >( &*it );
|
||||
|
||||
if (cmp(ret->value, current->value))
|
||||
if ( cmp( ret->value, current->value ) )
|
||||
ret = current;
|
||||
}
|
||||
|
||||
return const_cast<Node*>(ret);
|
||||
return const_cast< Node* >( ret );
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}}} // namespace boost::heap::detail
|
||||
|
||||
#undef BOOST_HEAP_ASSERT
|
||||
#endif /* BOOST_HEAP_DETAIL_HEAP_NODE_HPP */
|
||||
|
||||
@@ -11,38 +11,37 @@
|
||||
|
||||
#include <string> // std::size_t
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
namespace detail {
|
||||
|
||||
template <typename IntType>
|
||||
template < typename IntType >
|
||||
struct log2
|
||||
{
|
||||
IntType operator()(IntType value)
|
||||
IntType operator()( IntType value )
|
||||
{
|
||||
IntType l = 0;
|
||||
while( (value >> l) > 1 )
|
||||
while ( ( value >> l ) > 1 )
|
||||
++l;
|
||||
return l;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
template<>
|
||||
struct log2<unsigned int>
|
||||
template <>
|
||||
struct log2< unsigned int >
|
||||
{
|
||||
unsigned int operator()(unsigned int value)
|
||||
unsigned int operator()( unsigned int value )
|
||||
{
|
||||
return sizeof(unsigned int)*8 - __builtin_clz(value - 1);
|
||||
return sizeof( unsigned int ) * 8 - __builtin_clz( value - 1 );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct log2<unsigned long>
|
||||
template <>
|
||||
struct log2< unsigned long >
|
||||
{
|
||||
unsigned long operator()(unsigned long value)
|
||||
unsigned long operator()( unsigned long value )
|
||||
{
|
||||
return sizeof(unsigned long)*8 - __builtin_clzl(value - 1);
|
||||
return sizeof( unsigned long ) * 8 - __builtin_clzl( value - 1 );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -51,14 +50,13 @@ struct log2<unsigned long>
|
||||
} /* namespace detail */
|
||||
|
||||
|
||||
template <typename IntType>
|
||||
IntType log2(IntType value)
|
||||
template < typename IntType >
|
||||
IntType log2( IntType value )
|
||||
{
|
||||
detail::log2<IntType> fn;
|
||||
return fn(value);
|
||||
detail::log2< IntType > fn;
|
||||
return fn( value );
|
||||
}
|
||||
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}} // namespace boost::heap
|
||||
|
||||
#endif /* BOOST_HEAP_DETAIL_ILOG2_HPP */
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
#include <list>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/heap/detail/ordered_adaptor_iterator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace detail {
|
||||
namespace boost { namespace heap { namespace detail {
|
||||
|
||||
/* wrapper for a mutable heap container adaptors
|
||||
*
|
||||
@@ -29,81 +27,81 @@ namespace detail {
|
||||
* but instead from std::list iterators. this way, the mutability is achieved
|
||||
*
|
||||
*/
|
||||
template <typename PriorityQueueType>
|
||||
template < typename PriorityQueueType >
|
||||
class priority_queue_mutable_wrapper
|
||||
{
|
||||
public:
|
||||
typedef typename PriorityQueueType::value_type value_type;
|
||||
typedef typename PriorityQueueType::size_type size_type;
|
||||
typedef typename PriorityQueueType::value_compare value_compare;
|
||||
typedef typename PriorityQueueType::value_type value_type;
|
||||
typedef typename PriorityQueueType::size_type size_type;
|
||||
typedef typename PriorityQueueType::value_compare value_compare;
|
||||
typedef typename PriorityQueueType::allocator_type allocator_type;
|
||||
|
||||
typedef typename PriorityQueueType::reference reference;
|
||||
typedef typename PriorityQueueType::reference reference;
|
||||
typedef typename PriorityQueueType::const_reference const_reference;
|
||||
typedef typename PriorityQueueType::pointer pointer;
|
||||
typedef typename PriorityQueueType::const_pointer const_pointer;
|
||||
static const bool is_stable = PriorityQueueType::is_stable;
|
||||
typedef typename PriorityQueueType::pointer pointer;
|
||||
typedef typename PriorityQueueType::const_pointer const_pointer;
|
||||
static const bool is_stable = PriorityQueueType::is_stable;
|
||||
|
||||
private:
|
||||
typedef std::pair<value_type, size_type> node_type;
|
||||
typedef std::pair< value_type, size_type > node_type;
|
||||
|
||||
typedef std::list<node_type, typename boost::allocator_rebind<allocator_type, node_type>::type> object_list;
|
||||
typedef std::list< node_type, typename boost::allocator_rebind< allocator_type, node_type >::type > object_list;
|
||||
|
||||
typedef typename object_list::iterator list_iterator;
|
||||
typedef typename object_list::iterator list_iterator;
|
||||
typedef typename object_list::const_iterator const_list_iterator;
|
||||
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
friend struct heap_merge_emulate;
|
||||
|
||||
typedef typename PriorityQueueType::super_t::stability_counter_type stability_counter_type;
|
||||
|
||||
stability_counter_type get_stability_count(void) const
|
||||
stability_counter_type get_stability_count( void ) const
|
||||
{
|
||||
return q_.get_stability_count();
|
||||
}
|
||||
|
||||
void set_stability_count(stability_counter_type new_count)
|
||||
void set_stability_count( stability_counter_type new_count )
|
||||
{
|
||||
q_.set_stability_count(new_count);
|
||||
q_.set_stability_count( new_count );
|
||||
}
|
||||
|
||||
struct index_updater
|
||||
{
|
||||
template <typename It>
|
||||
static void run(It & it, size_type new_index)
|
||||
template < typename It >
|
||||
static void run( It& it, size_type new_index )
|
||||
{
|
||||
q_type::get_value(it)->second = new_index;
|
||||
q_type::get_value( it )->second = new_index;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
struct handle_type
|
||||
{
|
||||
value_type & operator*() const
|
||||
value_type& operator*() const
|
||||
{
|
||||
return iterator->first;
|
||||
}
|
||||
|
||||
handle_type (void)
|
||||
handle_type( void )
|
||||
{}
|
||||
|
||||
handle_type(handle_type const & rhs):
|
||||
iterator(rhs.iterator)
|
||||
handle_type( handle_type const& rhs ) :
|
||||
iterator( rhs.iterator )
|
||||
{}
|
||||
|
||||
bool operator==(handle_type const & rhs) const
|
||||
bool operator==( handle_type const& rhs ) const
|
||||
{
|
||||
return iterator == rhs.iterator;
|
||||
}
|
||||
|
||||
bool operator!=(handle_type const & rhs) const
|
||||
bool operator!=( handle_type const& rhs ) const
|
||||
{
|
||||
return iterator != rhs.iterator;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit handle_type(list_iterator const & it):
|
||||
iterator(it)
|
||||
explicit handle_type( list_iterator const& it ) :
|
||||
iterator( it )
|
||||
{}
|
||||
|
||||
list_iterator iterator;
|
||||
@@ -112,93 +110,94 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
struct indirect_cmp:
|
||||
public value_compare
|
||||
struct indirect_cmp : public value_compare
|
||||
{
|
||||
indirect_cmp(value_compare const & cmp = value_compare()):
|
||||
value_compare(cmp)
|
||||
indirect_cmp( value_compare const& cmp = value_compare() ) :
|
||||
value_compare( cmp )
|
||||
{}
|
||||
|
||||
bool operator()(const_list_iterator const & lhs, const_list_iterator const & rhs) const
|
||||
bool operator()( const_list_iterator const& lhs, const_list_iterator const& rhs ) const
|
||||
{
|
||||
return value_compare::operator()(lhs->first, rhs->first);
|
||||
return value_compare::operator()( lhs->first, rhs->first );
|
||||
}
|
||||
};
|
||||
|
||||
typedef typename PriorityQueueType::template rebind<list_iterator,
|
||||
indirect_cmp,
|
||||
allocator_type, index_updater >::other q_type;
|
||||
typedef
|
||||
typename PriorityQueueType::template rebind< list_iterator, indirect_cmp, allocator_type, index_updater >::other
|
||||
q_type;
|
||||
|
||||
protected:
|
||||
q_type q_;
|
||||
q_type q_;
|
||||
object_list objects;
|
||||
|
||||
protected:
|
||||
priority_queue_mutable_wrapper(value_compare const & cmp = value_compare()):
|
||||
q_(cmp)
|
||||
priority_queue_mutable_wrapper( value_compare const& cmp = value_compare() ) :
|
||||
q_( cmp )
|
||||
{}
|
||||
|
||||
priority_queue_mutable_wrapper(priority_queue_mutable_wrapper const & rhs):
|
||||
q_(rhs.q_), objects(rhs.objects)
|
||||
priority_queue_mutable_wrapper( priority_queue_mutable_wrapper const& rhs ) :
|
||||
q_( rhs.q_ ),
|
||||
objects( rhs.objects )
|
||||
{
|
||||
for (typename object_list::iterator it = objects.begin(); it != objects.end(); ++it)
|
||||
q_.push(it);
|
||||
for ( typename object_list::iterator it = objects.begin(); it != objects.end(); ++it )
|
||||
q_.push( it );
|
||||
}
|
||||
|
||||
priority_queue_mutable_wrapper & operator=(priority_queue_mutable_wrapper const & rhs)
|
||||
priority_queue_mutable_wrapper& operator=( priority_queue_mutable_wrapper const& rhs )
|
||||
{
|
||||
q_ = rhs.q_;
|
||||
q_ = rhs.q_;
|
||||
objects = rhs.objects;
|
||||
q_.clear();
|
||||
for (typename object_list::iterator it = objects.begin(); it != objects.end(); ++it)
|
||||
q_.push(it);
|
||||
for ( typename object_list::iterator it = objects.begin(); it != objects.end(); ++it )
|
||||
q_.push( it );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
priority_queue_mutable_wrapper (priority_queue_mutable_wrapper && rhs):
|
||||
q_(std::move(rhs.q_))
|
||||
priority_queue_mutable_wrapper( priority_queue_mutable_wrapper&& rhs ) :
|
||||
q_( std::move( rhs.q_ ) )
|
||||
{
|
||||
/// FIXME: msvc seems to invalidate iterators when moving std::list
|
||||
std::swap(objects, rhs.objects);
|
||||
std::swap( objects, rhs.objects );
|
||||
}
|
||||
|
||||
priority_queue_mutable_wrapper & operator=(priority_queue_mutable_wrapper && rhs)
|
||||
priority_queue_mutable_wrapper& operator=( priority_queue_mutable_wrapper&& rhs )
|
||||
{
|
||||
q_ = std::move(rhs.q_);
|
||||
q_ = std::move( rhs.q_ );
|
||||
objects.clear();
|
||||
std::swap(objects, rhs.objects);
|
||||
std::swap( objects, rhs.objects );
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
template <typename iterator_type>
|
||||
class iterator_base:
|
||||
public boost::iterator_adaptor<iterator_base<iterator_type>,
|
||||
iterator_type,
|
||||
value_type const,
|
||||
boost::bidirectional_traversal_tag>
|
||||
template < typename iterator_type >
|
||||
class iterator_base :
|
||||
public boost::iterator_adaptor< iterator_base< iterator_type >,
|
||||
iterator_type,
|
||||
value_type const,
|
||||
boost::bidirectional_traversal_tag >
|
||||
{
|
||||
typedef boost::iterator_adaptor<iterator_base<iterator_type>,
|
||||
iterator_type,
|
||||
value_type const,
|
||||
boost::bidirectional_traversal_tag> super_t;
|
||||
typedef boost::iterator_adaptor< iterator_base< iterator_type >,
|
||||
iterator_type,
|
||||
value_type const,
|
||||
boost::bidirectional_traversal_tag >
|
||||
super_t;
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
friend class priority_queue_mutable_wrapper;
|
||||
|
||||
iterator_base(void):
|
||||
super_t(0)
|
||||
iterator_base( void ) :
|
||||
super_t( 0 )
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
explicit iterator_base(T const & it):
|
||||
super_t(it)
|
||||
template < typename T >
|
||||
explicit iterator_base( T const& it ) :
|
||||
super_t( it )
|
||||
{}
|
||||
|
||||
value_type const & dereference() const
|
||||
value_type const& dereference() const
|
||||
{
|
||||
return super_t::base()->first;
|
||||
}
|
||||
@@ -209,162 +208,163 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef iterator_base<list_iterator> iterator;
|
||||
typedef iterator_base<const_list_iterator> const_iterator;
|
||||
typedef iterator_base< list_iterator > iterator;
|
||||
typedef iterator_base< const_list_iterator > const_iterator;
|
||||
|
||||
typedef typename object_list::difference_type difference_type;
|
||||
|
||||
class ordered_iterator:
|
||||
public boost::iterator_adaptor<ordered_iterator,
|
||||
const_list_iterator,
|
||||
value_type const,
|
||||
boost::forward_traversal_tag
|
||||
>,
|
||||
class ordered_iterator :
|
||||
public boost::iterator_adaptor< ordered_iterator, const_list_iterator, value_type const, boost::forward_traversal_tag >,
|
||||
q_type::ordered_iterator_dispatcher
|
||||
{
|
||||
typedef boost::iterator_adaptor<ordered_iterator,
|
||||
const_list_iterator,
|
||||
value_type const,
|
||||
boost::forward_traversal_tag
|
||||
> adaptor_type;
|
||||
typedef boost::iterator_adaptor< ordered_iterator, const_list_iterator, value_type const, boost::forward_traversal_tag >
|
||||
adaptor_type;
|
||||
|
||||
typedef const_list_iterator iterator;
|
||||
typedef const_list_iterator iterator;
|
||||
typedef typename q_type::ordered_iterator_dispatcher ordered_iterator_dispatcher;
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
public:
|
||||
ordered_iterator(void):
|
||||
adaptor_type(0), unvisited_nodes(indirect_cmp()), q_(NULL)
|
||||
ordered_iterator( void ) :
|
||||
adaptor_type( 0 ),
|
||||
unvisited_nodes( indirect_cmp() ),
|
||||
q_( NULL )
|
||||
{}
|
||||
|
||||
ordered_iterator(const priority_queue_mutable_wrapper * q, indirect_cmp const & cmp):
|
||||
adaptor_type(0), unvisited_nodes(cmp), q_(q)
|
||||
ordered_iterator( const priority_queue_mutable_wrapper* q, indirect_cmp const& cmp ) :
|
||||
adaptor_type( 0 ),
|
||||
unvisited_nodes( cmp ),
|
||||
q_( q )
|
||||
{}
|
||||
|
||||
ordered_iterator(const_list_iterator it, const priority_queue_mutable_wrapper * q, indirect_cmp const & cmp):
|
||||
adaptor_type(it), unvisited_nodes(cmp), q_(q)
|
||||
ordered_iterator( const_list_iterator it, const priority_queue_mutable_wrapper* q, indirect_cmp const& cmp ) :
|
||||
adaptor_type( it ),
|
||||
unvisited_nodes( cmp ),
|
||||
q_( q )
|
||||
{
|
||||
if (it != q->objects.end())
|
||||
discover_nodes(it);
|
||||
if ( it != q->objects.end() )
|
||||
discover_nodes( it );
|
||||
}
|
||||
|
||||
bool operator!=(ordered_iterator const & rhs) const
|
||||
bool operator!=( ordered_iterator const& rhs ) const
|
||||
{
|
||||
return adaptor_type::base() != rhs.base();
|
||||
}
|
||||
|
||||
bool operator==(ordered_iterator const & rhs) const
|
||||
bool operator==( ordered_iterator const& rhs ) const
|
||||
{
|
||||
return !operator!=(rhs);
|
||||
return !operator!=( rhs );
|
||||
}
|
||||
|
||||
private:
|
||||
void increment(void)
|
||||
void increment( void )
|
||||
{
|
||||
if (unvisited_nodes.empty())
|
||||
if ( unvisited_nodes.empty() )
|
||||
adaptor_type::base_reference() = q_->objects.end();
|
||||
else {
|
||||
iterator next = unvisited_nodes.top();
|
||||
unvisited_nodes.pop();
|
||||
discover_nodes(next);
|
||||
discover_nodes( next );
|
||||
adaptor_type::base_reference() = next;
|
||||
}
|
||||
}
|
||||
|
||||
value_type const & dereference() const
|
||||
value_type const& dereference() const
|
||||
{
|
||||
return adaptor_type::base()->first;
|
||||
}
|
||||
|
||||
void discover_nodes(iterator current)
|
||||
void discover_nodes( iterator current )
|
||||
{
|
||||
size_type current_index = current->second;
|
||||
const q_type * q = &(q_->q_);
|
||||
size_type current_index = current->second;
|
||||
const q_type* q = &( q_->q_ );
|
||||
|
||||
if (ordered_iterator_dispatcher::is_leaf(q, current_index))
|
||||
if ( ordered_iterator_dispatcher::is_leaf( q, current_index ) )
|
||||
return;
|
||||
|
||||
std::pair<size_type, size_type> child_range = ordered_iterator_dispatcher::get_child_nodes(q, current_index);
|
||||
std::pair< size_type, size_type > child_range
|
||||
= ordered_iterator_dispatcher::get_child_nodes( q, current_index );
|
||||
|
||||
for (size_type i = child_range.first; i <= child_range.second; ++i) {
|
||||
typename q_type::internal_type const & internal_value_at_index = ordered_iterator_dispatcher::get_internal_value(q, i);
|
||||
typename q_type::value_type const & value_at_index = q_->q_.get_value(internal_value_at_index);
|
||||
for ( size_type i = child_range.first; i <= child_range.second; ++i ) {
|
||||
typename q_type::internal_type const& internal_value_at_index
|
||||
= ordered_iterator_dispatcher::get_internal_value( q, i );
|
||||
typename q_type::value_type const& value_at_index = q_->q_.get_value( internal_value_at_index );
|
||||
|
||||
unvisited_nodes.push(value_at_index);
|
||||
unvisited_nodes.push( value_at_index );
|
||||
}
|
||||
}
|
||||
|
||||
std::priority_queue<iterator,
|
||||
std::vector<iterator, typename boost::allocator_rebind<allocator_type, iterator>::type>,
|
||||
indirect_cmp
|
||||
> unvisited_nodes;
|
||||
const priority_queue_mutable_wrapper * q_;
|
||||
std::priority_queue< iterator,
|
||||
std::vector< iterator, typename boost::allocator_rebind< allocator_type, iterator >::type >,
|
||||
indirect_cmp >
|
||||
unvisited_nodes;
|
||||
const priority_queue_mutable_wrapper* q_;
|
||||
};
|
||||
|
||||
bool empty(void) const
|
||||
bool empty( void ) const
|
||||
{
|
||||
return q_.empty();
|
||||
}
|
||||
|
||||
size_type size(void) const
|
||||
size_type size( void ) const
|
||||
{
|
||||
return q_.size();
|
||||
}
|
||||
|
||||
size_type max_size(void) const
|
||||
size_type max_size( void ) const
|
||||
{
|
||||
return objects.max_size();
|
||||
}
|
||||
|
||||
void clear(void)
|
||||
void clear( void )
|
||||
{
|
||||
q_.clear();
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
allocator_type get_allocator(void) const
|
||||
allocator_type get_allocator( void ) const
|
||||
{
|
||||
return q_.get_allocator();
|
||||
}
|
||||
|
||||
void swap(priority_queue_mutable_wrapper & rhs)
|
||||
void swap( priority_queue_mutable_wrapper& rhs )
|
||||
{
|
||||
objects.swap(rhs.objects);
|
||||
q_.swap(rhs.q_);
|
||||
objects.swap( rhs.objects );
|
||||
q_.swap( rhs.q_ );
|
||||
}
|
||||
|
||||
const_reference top(void) const
|
||||
const_reference top( void ) const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
BOOST_ASSERT( !empty() );
|
||||
return q_.top()->first;
|
||||
}
|
||||
|
||||
handle_type push(value_type const & v)
|
||||
handle_type push( value_type const& v )
|
||||
{
|
||||
objects.push_front(std::make_pair(v, 0));
|
||||
objects.push_front( std::make_pair( v, 0 ) );
|
||||
list_iterator ret = objects.begin();
|
||||
q_.push(ret);
|
||||
return handle_type(ret);
|
||||
q_.push( ret );
|
||||
return handle_type( ret );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
handle_type emplace(Args&&... args)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
handle_type emplace( Args&&... args )
|
||||
{
|
||||
objects.push_front(std::make_pair(std::forward<Args>(args)..., 0));
|
||||
objects.push_front( std::make_pair( std::forward< Args >( args )..., 0 ) );
|
||||
list_iterator ret = objects.begin();
|
||||
q_.push(ret);
|
||||
return handle_type(ret);
|
||||
q_.push( ret );
|
||||
return handle_type( ret );
|
||||
}
|
||||
#endif
|
||||
|
||||
void pop(void)
|
||||
void pop( void )
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
BOOST_ASSERT( !empty() );
|
||||
list_iterator q_top = q_.top();
|
||||
q_.pop();
|
||||
objects.erase(q_top);
|
||||
objects.erase( q_top );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,15 +373,15 @@ public:
|
||||
* \b Complexity: Logarithmic.
|
||||
*
|
||||
* */
|
||||
void update(handle_type handle, const_reference v)
|
||||
void update( handle_type handle, const_reference v )
|
||||
{
|
||||
list_iterator it = handle.iterator;
|
||||
value_type const & current_value = it->first;
|
||||
value_compare const & cmp = q_.value_comp();
|
||||
if (cmp(v, current_value))
|
||||
decrease(handle, v);
|
||||
list_iterator it = handle.iterator;
|
||||
value_type const& current_value = it->first;
|
||||
value_compare const& cmp = q_.value_comp();
|
||||
if ( cmp( v, current_value ) )
|
||||
decrease( handle, v );
|
||||
else
|
||||
increase(handle, v);
|
||||
increase( handle, v );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,25 +391,25 @@ public:
|
||||
*
|
||||
* \b Note: If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void update(handle_type handle)
|
||||
void update( handle_type handle )
|
||||
{
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.update(index);
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.update( index );
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* \b Effects: Assigns \c v to the element handled by \c handle & updates the priority queue.
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
*
|
||||
* \b Note: The new value is expected to be greater than the current one
|
||||
* */
|
||||
void increase(handle_type handle, const_reference v)
|
||||
void increase( handle_type handle, const_reference v )
|
||||
{
|
||||
BOOST_ASSERT(!value_compare()(v, handle.iterator->first));
|
||||
BOOST_ASSERT( !value_compare()( v, handle.iterator->first ) );
|
||||
handle.iterator->first = v;
|
||||
increase(handle);
|
||||
increase( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,27 +417,28 @@ public:
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
*
|
||||
* \b Note: The new value is expected to be greater than the current one. If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* \b Note: The new value is expected to be greater than the current one. If this is not called, after a handle has
|
||||
* been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void increase(handle_type handle)
|
||||
void increase( handle_type handle )
|
||||
{
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.increase(index);
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.increase( index );
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* \b Effects: Assigns \c v to the element handled by \c handle & updates the priority queue.
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
*
|
||||
* \b Note: The new value is expected to be less than the current one
|
||||
* */
|
||||
void decrease(handle_type handle, const_reference v)
|
||||
void decrease( handle_type handle, const_reference v )
|
||||
{
|
||||
BOOST_ASSERT(!value_compare()(handle.iterator->first, v));
|
||||
BOOST_ASSERT( !value_compare()( handle.iterator->first, v ) );
|
||||
handle.iterator->first = v;
|
||||
decrease(handle);
|
||||
decrease( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -445,13 +446,14 @@ public:
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
*
|
||||
* \b Note: The new value is expected to be less than the current one. If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* \b Note: The new value is expected to be less than the current one. If this is not called, after a handle has
|
||||
* been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void decrease(handle_type handle)
|
||||
void decrease( handle_type handle )
|
||||
{
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.decrease(index);
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.decrease( index );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -459,66 +461,64 @@ public:
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
* */
|
||||
void erase(handle_type handle)
|
||||
void erase( handle_type handle )
|
||||
{
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.erase(index);
|
||||
objects.erase(it);
|
||||
list_iterator it = handle.iterator;
|
||||
size_type index = it->second;
|
||||
q_.erase( index );
|
||||
objects.erase( it );
|
||||
}
|
||||
|
||||
const_iterator begin(void) const
|
||||
const_iterator begin( void ) const
|
||||
{
|
||||
return const_iterator(objects.begin());
|
||||
return const_iterator( objects.begin() );
|
||||
}
|
||||
|
||||
const_iterator end(void) const
|
||||
const_iterator end( void ) const
|
||||
{
|
||||
return const_iterator(objects.end());
|
||||
return const_iterator( objects.end() );
|
||||
}
|
||||
|
||||
iterator begin(void)
|
||||
iterator begin( void )
|
||||
{
|
||||
return iterator(objects.begin());
|
||||
return iterator( objects.begin() );
|
||||
}
|
||||
|
||||
iterator end(void)
|
||||
iterator end( void )
|
||||
{
|
||||
return iterator(objects.end());
|
||||
return iterator( objects.end() );
|
||||
}
|
||||
|
||||
ordered_iterator ordered_begin(void) const
|
||||
ordered_iterator ordered_begin( void ) const
|
||||
{
|
||||
if (!empty())
|
||||
return ordered_iterator(q_.top(), this, indirect_cmp(q_.value_comp()));
|
||||
if ( !empty() )
|
||||
return ordered_iterator( q_.top(), this, indirect_cmp( q_.value_comp() ) );
|
||||
else
|
||||
return ordered_end();
|
||||
}
|
||||
|
||||
ordered_iterator ordered_end(void) const
|
||||
ordered_iterator ordered_end( void ) const
|
||||
{
|
||||
return ordered_iterator(objects.end(), this, indirect_cmp(q_.value_comp()));
|
||||
return ordered_iterator( objects.end(), this, indirect_cmp( q_.value_comp() ) );
|
||||
}
|
||||
|
||||
static handle_type s_handle_from_iterator(iterator const & it)
|
||||
static handle_type s_handle_from_iterator( iterator const& it )
|
||||
{
|
||||
return handle_type(it.get_list_iterator());
|
||||
return handle_type( it.get_list_iterator() );
|
||||
}
|
||||
|
||||
value_compare const & value_comp(void) const
|
||||
value_compare const& value_comp( void ) const
|
||||
{
|
||||
return q_.value_comp();
|
||||
}
|
||||
|
||||
void reserve (size_type element_count)
|
||||
void reserve( size_type element_count )
|
||||
{
|
||||
q_.reserve(element_count);
|
||||
q_.reserve( element_count );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}}} // namespace boost::heap::detail
|
||||
|
||||
#endif /* BOOST_HEAP_DETAIL_MUTABLE_HEAP_HPP */
|
||||
|
||||
@@ -13,13 +13,11 @@
|
||||
#include <limits>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/heap/detail/tree_iterator.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace detail {
|
||||
namespace boost { namespace heap { namespace detail {
|
||||
|
||||
/* ordered iterator helper classes for container adaptors
|
||||
*
|
||||
@@ -27,120 +25,112 @@ namespace detail {
|
||||
*
|
||||
* * static size_type max_index(const ContainerType * heap); // return maximum index
|
||||
* * static bool is_leaf(const ContainerType * heap, size_type index); // return if index denotes a leaf
|
||||
* * static std::pair<size_type, size_type> get_child_nodes(const ContainerType * heap, size_type index); // get index range of child nodes
|
||||
* * static internal_type const & get_internal_value(const ContainerType * heap, size_type index); // get internal value at index
|
||||
* * static std::pair<size_type, size_type> get_child_nodes(const ContainerType * heap, size_type index); // get index
|
||||
* range of child nodes
|
||||
* * static internal_type const & get_internal_value(const ContainerType * heap, size_type index); // get internal value
|
||||
* at index
|
||||
* * static value_type const & get_value(internal_type const & arg) const; // get value_type from internal_type
|
||||
*
|
||||
* */
|
||||
template <typename ValueType,
|
||||
typename InternalType,
|
||||
typename ContainerType,
|
||||
typename Alloc,
|
||||
typename ValueCompare,
|
||||
typename Dispatcher
|
||||
>
|
||||
class ordered_adaptor_iterator:
|
||||
public boost::iterator_facade<ordered_adaptor_iterator<ValueType,
|
||||
InternalType,
|
||||
ContainerType,
|
||||
Alloc,
|
||||
ValueCompare,
|
||||
Dispatcher>,
|
||||
ValueType,
|
||||
boost::forward_traversal_tag
|
||||
>,
|
||||
template < typename ValueType, typename InternalType, typename ContainerType, typename Alloc, typename ValueCompare, typename Dispatcher >
|
||||
class ordered_adaptor_iterator :
|
||||
public boost::iterator_facade<
|
||||
ordered_adaptor_iterator< ValueType, InternalType, ContainerType, Alloc, ValueCompare, Dispatcher >,
|
||||
ValueType,
|
||||
boost::forward_traversal_tag >,
|
||||
Dispatcher
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
struct compare_by_heap_value:
|
||||
ValueCompare
|
||||
struct compare_by_heap_value : ValueCompare
|
||||
{
|
||||
const ContainerType * container;
|
||||
const ContainerType* container;
|
||||
|
||||
compare_by_heap_value (const ContainerType * container, ValueCompare const & cmp):
|
||||
ValueCompare(cmp), container(container)
|
||||
compare_by_heap_value( const ContainerType* container, ValueCompare const& cmp ) :
|
||||
ValueCompare( cmp ),
|
||||
container( container )
|
||||
{}
|
||||
|
||||
bool operator()(size_t lhs, size_t rhs)
|
||||
bool operator()( size_t lhs, size_t rhs )
|
||||
{
|
||||
BOOST_ASSERT(lhs <= Dispatcher::max_index(container));
|
||||
BOOST_ASSERT(rhs <= Dispatcher::max_index(container));
|
||||
return ValueCompare::operator()(Dispatcher::get_internal_value(container, lhs),
|
||||
Dispatcher::get_internal_value(container, rhs));
|
||||
BOOST_ASSERT( lhs <= Dispatcher::max_index( container ) );
|
||||
BOOST_ASSERT( rhs <= Dispatcher::max_index( container ) );
|
||||
return ValueCompare::operator()( Dispatcher::get_internal_value( container, lhs ),
|
||||
Dispatcher::get_internal_value( container, rhs ) );
|
||||
}
|
||||
};
|
||||
|
||||
const ContainerType * container;
|
||||
size_t current_index; // current index: special value -1 denotes `end' iterator
|
||||
const ContainerType* container;
|
||||
size_t current_index; // current index: special value -1 denotes `end' iterator
|
||||
|
||||
public:
|
||||
ordered_adaptor_iterator(void):
|
||||
container(NULL), current_index((std::numeric_limits<size_t>::max)()),
|
||||
unvisited_nodes(compare_by_heap_value(NULL, ValueCompare()))
|
||||
ordered_adaptor_iterator( void ) :
|
||||
container( NULL ),
|
||||
current_index( ( std::numeric_limits< size_t >::max )() ),
|
||||
unvisited_nodes( compare_by_heap_value( NULL, ValueCompare() ) )
|
||||
{}
|
||||
|
||||
ordered_adaptor_iterator(const ContainerType * container, ValueCompare const & cmp):
|
||||
container(container), current_index(container->size()),
|
||||
unvisited_nodes(compare_by_heap_value(container, ValueCompare()))
|
||||
ordered_adaptor_iterator( const ContainerType* container, ValueCompare const& cmp ) :
|
||||
container( container ),
|
||||
current_index( container->size() ),
|
||||
unvisited_nodes( compare_by_heap_value( container, ValueCompare() ) )
|
||||
{}
|
||||
|
||||
ordered_adaptor_iterator(size_t initial_index, const ContainerType * container, ValueCompare const & cmp):
|
||||
container(container), current_index(initial_index),
|
||||
unvisited_nodes(compare_by_heap_value(container, cmp))
|
||||
ordered_adaptor_iterator( size_t initial_index, const ContainerType* container, ValueCompare const& cmp ) :
|
||||
container( container ),
|
||||
current_index( initial_index ),
|
||||
unvisited_nodes( compare_by_heap_value( container, cmp ) )
|
||||
{
|
||||
discover_nodes(initial_index);
|
||||
discover_nodes( initial_index );
|
||||
}
|
||||
|
||||
private:
|
||||
bool equal (ordered_adaptor_iterator const & rhs) const
|
||||
bool equal( ordered_adaptor_iterator const& rhs ) const
|
||||
{
|
||||
if (current_index != rhs.current_index)
|
||||
if ( current_index != rhs.current_index )
|
||||
return false;
|
||||
|
||||
if (container != rhs.container) // less likely than first check
|
||||
if ( container != rhs.container ) // less likely than first check
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void increment(void)
|
||||
void increment( void )
|
||||
{
|
||||
if (unvisited_nodes.empty())
|
||||
current_index = Dispatcher::max_index(container) + 1;
|
||||
if ( unvisited_nodes.empty() )
|
||||
current_index = Dispatcher::max_index( container ) + 1;
|
||||
else {
|
||||
current_index = unvisited_nodes.top();
|
||||
unvisited_nodes.pop();
|
||||
discover_nodes(current_index);
|
||||
discover_nodes( current_index );
|
||||
}
|
||||
}
|
||||
|
||||
ValueType const & dereference() const
|
||||
ValueType const& dereference() const
|
||||
{
|
||||
BOOST_ASSERT(current_index <= Dispatcher::max_index(container));
|
||||
return Dispatcher::get_value(Dispatcher::get_internal_value(container, current_index));
|
||||
BOOST_ASSERT( current_index <= Dispatcher::max_index( container ) );
|
||||
return Dispatcher::get_value( Dispatcher::get_internal_value( container, current_index ) );
|
||||
}
|
||||
|
||||
void discover_nodes(size_t index)
|
||||
void discover_nodes( size_t index )
|
||||
{
|
||||
if (Dispatcher::is_leaf(container, index))
|
||||
if ( Dispatcher::is_leaf( container, index ) )
|
||||
return;
|
||||
|
||||
std::pair<size_t, size_t> child_range = Dispatcher::get_child_nodes(container, index);
|
||||
std::pair< size_t, size_t > child_range = Dispatcher::get_child_nodes( container, index );
|
||||
|
||||
for (size_t i = child_range.first; i <= child_range.second; ++i)
|
||||
unvisited_nodes.push(i);
|
||||
for ( size_t i = child_range.first; i <= child_range.second; ++i )
|
||||
unvisited_nodes.push( i );
|
||||
}
|
||||
|
||||
std::priority_queue<size_t,
|
||||
std::vector<size_t, typename boost::allocator_rebind<Alloc, size_t>::type>,
|
||||
compare_by_heap_value
|
||||
> unvisited_nodes;
|
||||
std::priority_queue< size_t,
|
||||
std::vector< size_t, typename boost::allocator_rebind< Alloc, size_t >::type >,
|
||||
compare_by_heap_value >
|
||||
unvisited_nodes;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}}} // namespace boost::heap::detail
|
||||
|
||||
#endif /* BOOST_HEAP_DETAIL_ORDERED_ADAPTOR_ITERATOR_HPP */
|
||||
|
||||
@@ -13,50 +13,45 @@
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/heap/policies.hpp>
|
||||
#include <boost/heap/heap_merge.hpp>
|
||||
#include <boost/heap/policies.hpp>
|
||||
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace detail {
|
||||
namespace boost { namespace heap { namespace detail {
|
||||
|
||||
template<bool ConstantSize, class SizeType>
|
||||
template < bool ConstantSize, class SizeType >
|
||||
struct size_holder
|
||||
{
|
||||
static const bool constant_time_size = ConstantSize;
|
||||
typedef SizeType size_type;
|
||||
|
||||
size_holder(void) BOOST_NOEXCEPT:
|
||||
size_(0)
|
||||
size_holder( void ) BOOST_NOEXCEPT : size_( 0 )
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
size_holder(size_holder && rhs) BOOST_NOEXCEPT:
|
||||
size_(rhs.size_)
|
||||
size_holder( size_holder&& rhs ) BOOST_NOEXCEPT : size_( rhs.size_ )
|
||||
{
|
||||
rhs.size_ = 0;
|
||||
}
|
||||
|
||||
size_holder(size_holder const & rhs) BOOST_NOEXCEPT:
|
||||
size_(rhs.size_)
|
||||
size_holder( size_holder const& rhs ) BOOST_NOEXCEPT : size_( rhs.size_ )
|
||||
{}
|
||||
|
||||
size_holder & operator=(size_holder && rhs) BOOST_NOEXCEPT
|
||||
size_holder& operator=( size_holder&& rhs ) BOOST_NOEXCEPT
|
||||
{
|
||||
size_ = rhs.size_;
|
||||
size_ = rhs.size_;
|
||||
rhs.size_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_holder & operator=(size_holder const & rhs) BOOST_NOEXCEPT
|
||||
size_holder& operator=( size_holder const& rhs ) BOOST_NOEXCEPT
|
||||
{
|
||||
size_ = rhs.size_;
|
||||
return *this;
|
||||
@@ -64,60 +59,76 @@ struct size_holder
|
||||
#endif
|
||||
|
||||
SizeType get_size() const BOOST_NOEXCEPT
|
||||
{ return size_; }
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
void set_size(SizeType size) BOOST_NOEXCEPT
|
||||
{ size_ = size; }
|
||||
void set_size( SizeType size ) BOOST_NOEXCEPT
|
||||
{
|
||||
size_ = size;
|
||||
}
|
||||
|
||||
void decrement() BOOST_NOEXCEPT
|
||||
{ --size_; }
|
||||
{
|
||||
--size_;
|
||||
}
|
||||
|
||||
void increment() BOOST_NOEXCEPT
|
||||
{ ++size_; }
|
||||
{
|
||||
++size_;
|
||||
}
|
||||
|
||||
void add(SizeType value) BOOST_NOEXCEPT
|
||||
{ size_ += value; }
|
||||
void add( SizeType value ) BOOST_NOEXCEPT
|
||||
{
|
||||
size_ += value;
|
||||
}
|
||||
|
||||
void sub(SizeType value) BOOST_NOEXCEPT
|
||||
{ size_ -= value; }
|
||||
void sub( SizeType value ) BOOST_NOEXCEPT
|
||||
{
|
||||
size_ -= value;
|
||||
}
|
||||
|
||||
void swap(size_holder & rhs) BOOST_NOEXCEPT
|
||||
{ std::swap(size_, rhs.size_); }
|
||||
void swap( size_holder& rhs ) BOOST_NOEXCEPT
|
||||
{
|
||||
std::swap( size_, rhs.size_ );
|
||||
}
|
||||
|
||||
SizeType size_;
|
||||
};
|
||||
|
||||
template<class SizeType>
|
||||
struct size_holder<false, SizeType>
|
||||
template < class SizeType >
|
||||
struct size_holder< false, SizeType >
|
||||
{
|
||||
static const bool constant_time_size = false;
|
||||
typedef SizeType size_type;
|
||||
|
||||
size_holder(void) BOOST_NOEXCEPT
|
||||
size_holder( void ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
size_holder(size_holder && rhs) BOOST_NOEXCEPT
|
||||
size_holder( size_holder&& rhs ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
size_holder(size_holder const & rhs) BOOST_NOEXCEPT
|
||||
size_holder( size_holder const& rhs ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
size_holder & operator=(size_holder && rhs) BOOST_NOEXCEPT
|
||||
size_holder& operator=( size_holder&& rhs ) BOOST_NOEXCEPT
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_holder & operator=(size_holder const & rhs) BOOST_NOEXCEPT
|
||||
size_holder& operator=( size_holder const& rhs ) BOOST_NOEXCEPT
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_type get_size() const BOOST_NOEXCEPT
|
||||
{ return 0; }
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_size(size_type) BOOST_NOEXCEPT
|
||||
void set_size( size_type ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
void decrement() BOOST_NOEXCEPT
|
||||
@@ -126,122 +137,119 @@ struct size_holder<false, SizeType>
|
||||
void increment() BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
void add(SizeType /*value*/) BOOST_NOEXCEPT
|
||||
void add( SizeType /*value*/ ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
void sub(SizeType /*value*/) BOOST_NOEXCEPT
|
||||
void sub( SizeType /*value*/ ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
void swap(size_holder & /*rhs*/) BOOST_NOEXCEPT
|
||||
void swap( size_holder& /*rhs*/ ) BOOST_NOEXCEPT
|
||||
{}
|
||||
};
|
||||
|
||||
// note: MSVC does not implement lookup correctly, we therefore have to place the Cmp object as member inside the
|
||||
// struct. of course, this prevents EBO and significantly reduces the readability of this code
|
||||
template <typename T,
|
||||
typename Cmp,
|
||||
bool constant_time_size,
|
||||
typename StabilityCounterType = boost::uintmax_t,
|
||||
bool stable = false
|
||||
>
|
||||
struct heap_base:
|
||||
template < typename T, typename Cmp, bool constant_time_size, typename StabilityCounterType = boost::uintmax_t, bool stable = false >
|
||||
struct heap_base :
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp,
|
||||
#endif
|
||||
size_holder<constant_time_size, size_t>
|
||||
size_holder< constant_time_size, size_t >
|
||||
{
|
||||
typedef StabilityCounterType stability_counter_type;
|
||||
typedef T value_type;
|
||||
typedef T internal_type;
|
||||
typedef size_holder<constant_time_size, size_t> size_holder_type;
|
||||
typedef Cmp value_compare;
|
||||
typedef Cmp internal_compare;
|
||||
static const bool is_stable = stable;
|
||||
typedef StabilityCounterType stability_counter_type;
|
||||
typedef T value_type;
|
||||
typedef T internal_type;
|
||||
typedef size_holder< constant_time_size, size_t > size_holder_type;
|
||||
typedef Cmp value_compare;
|
||||
typedef Cmp internal_compare;
|
||||
static const bool is_stable = stable;
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
Cmp cmp_;
|
||||
#endif
|
||||
|
||||
heap_base (Cmp const & cmp = Cmp()):
|
||||
heap_base( Cmp const& cmp = Cmp() ) :
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp(cmp)
|
||||
Cmp( cmp )
|
||||
#else
|
||||
cmp_(cmp)
|
||||
cmp_( cmp )
|
||||
#endif
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
heap_base(heap_base && rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible<Cmp>::value):
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp(std::move(static_cast<Cmp&>(rhs))),
|
||||
#endif
|
||||
size_holder_type(std::move(static_cast<size_holder_type&>(rhs)))
|
||||
#ifdef BOOST_MSVC
|
||||
, cmp_(std::move(rhs.cmp_))
|
||||
#endif
|
||||
heap_base( heap_base&& rhs ) BOOST_NOEXCEPT_IF( boost::is_nothrow_move_constructible< Cmp >::value ) :
|
||||
# ifndef BOOST_MSVC
|
||||
Cmp( std::move( static_cast< Cmp& >( rhs ) ) ),
|
||||
# endif
|
||||
size_holder_type( std::move( static_cast< size_holder_type& >( rhs ) ) )
|
||||
# ifdef BOOST_MSVC
|
||||
,
|
||||
cmp_( std::move( rhs.cmp_ ) )
|
||||
# endif
|
||||
{}
|
||||
|
||||
heap_base(heap_base const & rhs):
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp(static_cast<Cmp const &>(rhs)),
|
||||
#endif
|
||||
size_holder_type(static_cast<size_holder_type const &>(rhs))
|
||||
#ifdef BOOST_MSVC
|
||||
, cmp_(rhs.value_comp())
|
||||
#endif
|
||||
heap_base( heap_base const& rhs ) :
|
||||
# ifndef BOOST_MSVC
|
||||
Cmp( static_cast< Cmp const& >( rhs ) ),
|
||||
# endif
|
||||
size_holder_type( static_cast< size_holder_type const& >( rhs ) )
|
||||
# ifdef BOOST_MSVC
|
||||
,
|
||||
cmp_( rhs.value_comp() )
|
||||
# endif
|
||||
{}
|
||||
|
||||
heap_base & operator=(heap_base && rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_assignable<Cmp>::value)
|
||||
heap_base& operator=( heap_base&& rhs ) BOOST_NOEXCEPT_IF( boost::is_nothrow_move_assignable< Cmp >::value )
|
||||
{
|
||||
value_comp_ref().operator=(std::move(rhs.value_comp_ref()));
|
||||
size_holder_type::operator=(std::move(static_cast<size_holder_type&>(rhs)));
|
||||
value_comp_ref().operator=( std::move( rhs.value_comp_ref() ) );
|
||||
size_holder_type::operator=( std::move( static_cast< size_holder_type& >( rhs ) ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
heap_base & operator=(heap_base const & rhs)
|
||||
heap_base& operator=( heap_base const& rhs )
|
||||
{
|
||||
value_comp_ref().operator=(rhs.value_comp());
|
||||
size_holder_type::operator=(static_cast<size_holder_type const &>(rhs));
|
||||
value_comp_ref().operator=( rhs.value_comp() );
|
||||
size_holder_type::operator=( static_cast< size_holder_type const& >( rhs ) );
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator()(internal_type const & lhs, internal_type const & rhs) const
|
||||
bool operator()( internal_type const& lhs, internal_type const& rhs ) const
|
||||
{
|
||||
return value_comp().operator()(lhs, rhs);
|
||||
return value_comp().operator()( lhs, rhs );
|
||||
}
|
||||
|
||||
internal_type make_node(T const & val)
|
||||
internal_type make_node( T const& val )
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
T && make_node(T && val)
|
||||
T&& make_node( T&& val )
|
||||
{
|
||||
return std::forward<T>(val);
|
||||
return std::forward< T >( val );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
internal_type make_node(Args && ... val)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
internal_type make_node( Args&&... val )
|
||||
{
|
||||
return internal_type(std::forward<Args>(val)...);
|
||||
return internal_type( std::forward< Args >( val )... );
|
||||
}
|
||||
#endif
|
||||
|
||||
static T & get_value(internal_type & val) BOOST_NOEXCEPT
|
||||
static T& get_value( internal_type& val ) BOOST_NOEXCEPT
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
static T const & get_value(internal_type const & val) BOOST_NOEXCEPT
|
||||
static T const& get_value( internal_type const& val ) BOOST_NOEXCEPT
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
Cmp const & value_comp(void) const BOOST_NOEXCEPT
|
||||
Cmp const& value_comp( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
return *this;
|
||||
@@ -250,30 +258,31 @@ struct heap_base:
|
||||
#endif
|
||||
}
|
||||
|
||||
Cmp const & get_internal_cmp(void) const BOOST_NOEXCEPT
|
||||
Cmp const& get_internal_cmp( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return value_comp();
|
||||
}
|
||||
|
||||
void swap(heap_base & rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible<Cmp>::value && boost::is_nothrow_move_assignable<Cmp>::value)
|
||||
void swap( heap_base& rhs ) BOOST_NOEXCEPT_IF(
|
||||
boost::is_nothrow_move_constructible< Cmp >::value&& boost::is_nothrow_move_assignable< Cmp >::value )
|
||||
{
|
||||
std::swap(value_comp_ref(), rhs.value_comp_ref());
|
||||
size_holder<constant_time_size, size_t>::swap(rhs);
|
||||
std::swap( value_comp_ref(), rhs.value_comp_ref() );
|
||||
size_holder< constant_time_size, size_t >::swap( rhs );
|
||||
}
|
||||
|
||||
stability_counter_type get_stability_count(void) const BOOST_NOEXCEPT
|
||||
stability_counter_type get_stability_count( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_stability_count(stability_counter_type) BOOST_NOEXCEPT
|
||||
void set_stability_count( stability_counter_type ) BOOST_NOEXCEPT
|
||||
{}
|
||||
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
friend struct heap_merge_emulate;
|
||||
|
||||
private:
|
||||
Cmp & value_comp_ref(void)
|
||||
Cmp& value_comp_ref( void )
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
return *this;
|
||||
@@ -284,134 +293,134 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <typename T,
|
||||
typename Cmp,
|
||||
bool constant_time_size,
|
||||
typename StabilityCounterType
|
||||
>
|
||||
struct heap_base<T, Cmp, constant_time_size, StabilityCounterType, true>:
|
||||
template < typename T, typename Cmp, bool constant_time_size, typename StabilityCounterType >
|
||||
struct heap_base< T, Cmp, constant_time_size, StabilityCounterType, true > :
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp,
|
||||
#endif
|
||||
size_holder<constant_time_size, size_t>
|
||||
size_holder< constant_time_size, size_t >
|
||||
{
|
||||
typedef StabilityCounterType stability_counter_type;
|
||||
typedef T value_type;
|
||||
typedef T value_type;
|
||||
|
||||
struct internal_type
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class ...Args>
|
||||
internal_type(stability_counter_type cnt, Args && ... args):
|
||||
first(std::forward<Args>(args)...), second(cnt)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
internal_type( stability_counter_type cnt, Args&&... args ) :
|
||||
first( std::forward< Args >( args )... ),
|
||||
second( cnt )
|
||||
{}
|
||||
#endif
|
||||
|
||||
internal_type(stability_counter_type const & cnt, T const & value):
|
||||
first(value), second(cnt)
|
||||
internal_type( stability_counter_type const& cnt, T const& value ) :
|
||||
first( value ),
|
||||
second( cnt )
|
||||
{}
|
||||
|
||||
T first;
|
||||
T first;
|
||||
stability_counter_type second;
|
||||
};
|
||||
|
||||
typedef size_holder<constant_time_size, size_t> size_holder_type;
|
||||
typedef Cmp value_compare;
|
||||
typedef size_holder< constant_time_size, size_t > size_holder_type;
|
||||
typedef Cmp value_compare;
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
Cmp cmp_;
|
||||
#endif
|
||||
|
||||
heap_base (Cmp const & cmp = Cmp()):
|
||||
heap_base( Cmp const& cmp = Cmp() ) :
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp(cmp),
|
||||
Cmp( cmp ),
|
||||
#else
|
||||
cmp_(cmp),
|
||||
cmp_( cmp ),
|
||||
#endif
|
||||
counter_(0)
|
||||
counter_( 0 )
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
heap_base(heap_base && rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible<Cmp>::value):
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp(std::move(static_cast<Cmp&>(rhs))),
|
||||
#else
|
||||
cmp_(std::move(rhs.cmp_)),
|
||||
#endif
|
||||
size_holder_type(std::move(static_cast<size_holder_type&>(rhs))), counter_(rhs.counter_)
|
||||
heap_base( heap_base&& rhs ) BOOST_NOEXCEPT_IF( boost::is_nothrow_move_constructible< Cmp >::value ) :
|
||||
# ifndef BOOST_MSVC
|
||||
Cmp( std::move( static_cast< Cmp& >( rhs ) ) ),
|
||||
# else
|
||||
cmp_( std::move( rhs.cmp_ ) ),
|
||||
# endif
|
||||
size_holder_type( std::move( static_cast< size_holder_type& >( rhs ) ) ),
|
||||
counter_( rhs.counter_ )
|
||||
{
|
||||
rhs.counter_ = 0;
|
||||
}
|
||||
|
||||
heap_base(heap_base const & rhs):
|
||||
#ifndef BOOST_MSVC
|
||||
Cmp(static_cast<Cmp const&>(rhs)),
|
||||
#else
|
||||
cmp_(rhs.value_comp()),
|
||||
#endif
|
||||
size_holder_type(static_cast<size_holder_type const &>(rhs)), counter_(rhs.counter_)
|
||||
heap_base( heap_base const& rhs ) :
|
||||
# ifndef BOOST_MSVC
|
||||
Cmp( static_cast< Cmp const& >( rhs ) ),
|
||||
# else
|
||||
cmp_( rhs.value_comp() ),
|
||||
# endif
|
||||
size_holder_type( static_cast< size_holder_type const& >( rhs ) ),
|
||||
counter_( rhs.counter_ )
|
||||
{}
|
||||
|
||||
heap_base & operator=(heap_base && rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_assignable<Cmp>::value)
|
||||
heap_base& operator=( heap_base&& rhs ) BOOST_NOEXCEPT_IF( boost::is_nothrow_move_assignable< Cmp >::value )
|
||||
{
|
||||
value_comp_ref().operator=(std::move(rhs.value_comp_ref()));
|
||||
size_holder_type::operator=(std::move(static_cast<size_holder_type&>(rhs)));
|
||||
value_comp_ref().operator=( std::move( rhs.value_comp_ref() ) );
|
||||
size_holder_type::operator=( std::move( static_cast< size_holder_type& >( rhs ) ) );
|
||||
|
||||
counter_ = rhs.counter_;
|
||||
counter_ = rhs.counter_;
|
||||
rhs.counter_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
heap_base & operator=(heap_base const & rhs)
|
||||
heap_base& operator=( heap_base const& rhs )
|
||||
{
|
||||
value_comp_ref().operator=(rhs.value_comp());
|
||||
size_holder_type::operator=(static_cast<size_holder_type const &>(rhs));
|
||||
value_comp_ref().operator=( rhs.value_comp() );
|
||||
size_holder_type::operator=( static_cast< size_holder_type const& >( rhs ) );
|
||||
|
||||
counter_ = rhs.counter_;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool operator()(internal_type const & lhs, internal_type const & rhs) const
|
||||
bool operator()( internal_type const& lhs, internal_type const& rhs ) const
|
||||
{
|
||||
return get_internal_cmp()(lhs, rhs);
|
||||
return get_internal_cmp()( lhs, rhs );
|
||||
}
|
||||
|
||||
bool operator()(T const & lhs, T const & rhs) const
|
||||
bool operator()( T const& lhs, T const& rhs ) const
|
||||
{
|
||||
return value_comp()(lhs, rhs);
|
||||
return value_comp()( lhs, rhs );
|
||||
}
|
||||
|
||||
internal_type make_node(T const & val)
|
||||
internal_type make_node( T const& val )
|
||||
{
|
||||
stability_counter_type count = ++counter_;
|
||||
if (counter_ == (std::numeric_limits<stability_counter_type>::max)())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("boost::heap counter overflow"));
|
||||
return internal_type(count, val);
|
||||
if ( counter_ == ( std::numeric_limits< stability_counter_type >::max )() )
|
||||
BOOST_THROW_EXCEPTION( std::runtime_error( "boost::heap counter overflow" ) );
|
||||
return internal_type( count, val );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class... Args>
|
||||
internal_type make_node(Args&&... args)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < class... Args >
|
||||
internal_type make_node( Args&&... args )
|
||||
{
|
||||
stability_counter_type count = ++counter_;
|
||||
if (counter_ == (std::numeric_limits<stability_counter_type>::max)())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("boost::heap counter overflow"));
|
||||
return internal_type (count, std::forward<Args>(args)...);
|
||||
if ( counter_ == ( std::numeric_limits< stability_counter_type >::max )() )
|
||||
BOOST_THROW_EXCEPTION( std::runtime_error( "boost::heap counter overflow" ) );
|
||||
return internal_type( count, std::forward< Args >( args )... );
|
||||
}
|
||||
#endif
|
||||
|
||||
static T & get_value(internal_type & val) BOOST_NOEXCEPT
|
||||
static T& get_value( internal_type& val ) BOOST_NOEXCEPT
|
||||
{
|
||||
return val.first;
|
||||
}
|
||||
|
||||
static T const & get_value(internal_type const & val) BOOST_NOEXCEPT
|
||||
static T const& get_value( internal_type const& val ) BOOST_NOEXCEPT
|
||||
{
|
||||
return val.first;
|
||||
}
|
||||
|
||||
Cmp const & value_comp(void) const BOOST_NOEXCEPT
|
||||
Cmp const& value_comp( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
return *this;
|
||||
@@ -420,56 +429,56 @@ struct heap_base<T, Cmp, constant_time_size, StabilityCounterType, true>:
|
||||
#endif
|
||||
}
|
||||
|
||||
struct internal_compare:
|
||||
Cmp
|
||||
struct internal_compare : Cmp
|
||||
{
|
||||
internal_compare(Cmp const & cmp = Cmp()):
|
||||
Cmp(cmp)
|
||||
internal_compare( Cmp const& cmp = Cmp() ) :
|
||||
Cmp( cmp )
|
||||
{}
|
||||
|
||||
bool operator()(internal_type const & lhs, internal_type const & rhs) const
|
||||
bool operator()( internal_type const& lhs, internal_type const& rhs ) const
|
||||
{
|
||||
if (Cmp::operator()(lhs.first, rhs.first))
|
||||
if ( Cmp::operator()( lhs.first, rhs.first ) )
|
||||
return true;
|
||||
|
||||
if (Cmp::operator()(rhs.first, lhs.first))
|
||||
if ( Cmp::operator()( rhs.first, lhs.first ) )
|
||||
return false;
|
||||
|
||||
return lhs.second > rhs.second;
|
||||
}
|
||||
};
|
||||
|
||||
internal_compare get_internal_cmp(void) const
|
||||
internal_compare get_internal_cmp( void ) const
|
||||
{
|
||||
return internal_compare(value_comp());
|
||||
return internal_compare( value_comp() );
|
||||
}
|
||||
|
||||
void swap(heap_base & rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible<Cmp>::value && boost::is_nothrow_move_assignable<Cmp>::value)
|
||||
void swap( heap_base& rhs ) BOOST_NOEXCEPT_IF(
|
||||
boost::is_nothrow_move_constructible< Cmp >::value&& boost::is_nothrow_move_assignable< Cmp >::value )
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
std::swap(static_cast<Cmp&>(*this), static_cast<Cmp&>(rhs));
|
||||
std::swap( static_cast< Cmp& >( *this ), static_cast< Cmp& >( rhs ) );
|
||||
#else
|
||||
std::swap(cmp_, rhs.cmp_);
|
||||
std::swap( cmp_, rhs.cmp_ );
|
||||
#endif
|
||||
std::swap(counter_, rhs.counter_);
|
||||
size_holder<constant_time_size, size_t>::swap(rhs);
|
||||
std::swap( counter_, rhs.counter_ );
|
||||
size_holder< constant_time_size, size_t >::swap( rhs );
|
||||
}
|
||||
|
||||
stability_counter_type get_stability_count(void) const
|
||||
stability_counter_type get_stability_count( void ) const
|
||||
{
|
||||
return counter_;
|
||||
}
|
||||
|
||||
void set_stability_count(stability_counter_type new_count)
|
||||
void set_stability_count( stability_counter_type new_count )
|
||||
{
|
||||
counter_ = new_count;
|
||||
}
|
||||
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
friend struct heap_merge_emulate;
|
||||
|
||||
private:
|
||||
Cmp & value_comp_ref(void) BOOST_NOEXCEPT
|
||||
Cmp& value_comp_ref( void ) BOOST_NOEXCEPT
|
||||
{
|
||||
#ifndef BOOST_MSVC
|
||||
return *this;
|
||||
@@ -481,27 +490,24 @@ private:
|
||||
stability_counter_type counter_;
|
||||
};
|
||||
|
||||
template <typename node_pointer,
|
||||
typename extractor,
|
||||
typename reference
|
||||
>
|
||||
template < typename node_pointer, typename extractor, typename reference >
|
||||
struct node_handle
|
||||
{
|
||||
explicit node_handle(node_pointer n = 0):
|
||||
node_(n)
|
||||
explicit node_handle( node_pointer n = 0 ) :
|
||||
node_( n )
|
||||
{}
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
return extractor::get_value(node_->value);
|
||||
return extractor::get_value( node_->value );
|
||||
}
|
||||
|
||||
bool operator==(node_handle const & rhs) const
|
||||
bool operator==( node_handle const& rhs ) const
|
||||
{
|
||||
return node_ == rhs.node_;
|
||||
}
|
||||
|
||||
bool operator!=(node_handle const & rhs) const
|
||||
bool operator!=( node_handle const& rhs ) const
|
||||
{
|
||||
return node_ != rhs.node_;
|
||||
}
|
||||
@@ -509,77 +515,69 @@ struct node_handle
|
||||
node_pointer node_;
|
||||
};
|
||||
|
||||
template <typename value_type,
|
||||
typename internal_type,
|
||||
typename extractor
|
||||
>
|
||||
template < typename value_type, typename internal_type, typename extractor >
|
||||
struct value_extractor
|
||||
{
|
||||
value_type const & operator()(internal_type const & data) const
|
||||
value_type const& operator()( internal_type const& data ) const
|
||||
{
|
||||
return extractor::get_value(data);
|
||||
return extractor::get_value( data );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T,
|
||||
typename ContainerIterator,
|
||||
typename Extractor>
|
||||
class stable_heap_iterator:
|
||||
public boost::iterator_adaptor<stable_heap_iterator<T, ContainerIterator, Extractor>,
|
||||
ContainerIterator,
|
||||
T const,
|
||||
boost::random_access_traversal_tag>
|
||||
{
|
||||
typedef boost::iterator_adaptor<stable_heap_iterator,
|
||||
template < typename T, typename ContainerIterator, typename Extractor >
|
||||
class stable_heap_iterator :
|
||||
public boost::iterator_adaptor< stable_heap_iterator< T, ContainerIterator, Extractor >,
|
||||
ContainerIterator,
|
||||
T const,
|
||||
boost::random_access_traversal_tag> super_t;
|
||||
boost::random_access_traversal_tag >
|
||||
{
|
||||
typedef boost::iterator_adaptor< stable_heap_iterator, ContainerIterator, T const, boost::random_access_traversal_tag >
|
||||
super_t;
|
||||
|
||||
public:
|
||||
stable_heap_iterator(void):
|
||||
super_t(0)
|
||||
stable_heap_iterator( void ) :
|
||||
super_t( 0 )
|
||||
{}
|
||||
|
||||
explicit stable_heap_iterator(ContainerIterator const & it):
|
||||
super_t(it)
|
||||
explicit stable_heap_iterator( ContainerIterator const& it ) :
|
||||
super_t( it )
|
||||
{}
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
T const & dereference() const
|
||||
T const& dereference() const
|
||||
{
|
||||
return Extractor::get_value(*super_t::base());
|
||||
return Extractor::get_value( *super_t::base() );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Parspec, bool constant_time_size>
|
||||
template < typename T, typename Parspec, bool constant_time_size >
|
||||
struct make_heap_base
|
||||
{
|
||||
typedef typename parameter::binding<Parspec, tag::compare, std::less<T> >::type compare_argument;
|
||||
typedef typename parameter::binding<Parspec, tag::allocator, std::allocator<T> >::type allocator_argument;
|
||||
typedef typename parameter::binding<Parspec, tag::stability_counter_type, boost::uintmax_t >::type stability_counter_type;
|
||||
typedef typename parameter::binding< Parspec, tag::compare, std::less< T > >::type compare_argument;
|
||||
typedef typename parameter::binding< Parspec, tag::allocator, std::allocator< T > >::type allocator_argument;
|
||||
typedef
|
||||
typename parameter::binding< Parspec, tag::stability_counter_type, boost::uintmax_t >::type stability_counter_type;
|
||||
|
||||
static const bool is_stable = extract_stable<Parspec>::value;
|
||||
static const bool is_stable = extract_stable< Parspec >::value;
|
||||
|
||||
typedef heap_base<T, compare_argument, constant_time_size, stability_counter_type, is_stable> type;
|
||||
typedef heap_base< T, compare_argument, constant_time_size, stability_counter_type, is_stable > type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Alloc>
|
||||
template < typename Alloc >
|
||||
struct extract_allocator_types
|
||||
{
|
||||
typedef typename boost::allocator_size_type<Alloc>::type size_type;
|
||||
typedef typename boost::allocator_difference_type<Alloc>::type difference_type;
|
||||
typedef typename Alloc::value_type& reference;
|
||||
typedef typename Alloc::value_type const& const_reference;
|
||||
typedef typename boost::allocator_pointer<Alloc>::type pointer;
|
||||
typedef typename boost::allocator_const_pointer<Alloc>::type const_pointer;
|
||||
typedef typename boost::allocator_size_type< Alloc >::type size_type;
|
||||
typedef typename boost::allocator_difference_type< Alloc >::type difference_type;
|
||||
typedef typename Alloc::value_type& reference;
|
||||
typedef typename Alloc::value_type const& const_reference;
|
||||
typedef typename boost::allocator_pointer< Alloc >::type pointer;
|
||||
typedef typename boost::allocator_const_pointer< Alloc >::type const_pointer;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}}} // namespace boost::heap::detail
|
||||
|
||||
#endif /* BOOST_HEAP_DETAIL_STABLE_HEAP_HPP */
|
||||
|
||||
@@ -17,126 +17,118 @@
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <queue>
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace detail {
|
||||
namespace boost { namespace heap { namespace detail {
|
||||
|
||||
|
||||
template<typename type>
|
||||
template < typename type >
|
||||
struct identity
|
||||
{
|
||||
type& operator()(type& x) const BOOST_NOEXCEPT
|
||||
{ return x; }
|
||||
type& operator()( type& x ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
const type& operator()(const type& x) const BOOST_NOEXCEPT
|
||||
{ return x; }
|
||||
const type& operator()( const type& x ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
template < typename Node >
|
||||
struct dereferencer
|
||||
{
|
||||
template <typename Iterator>
|
||||
Node * operator()(Iterator const & it)
|
||||
template < typename Iterator >
|
||||
Node* operator()( Iterator const& it )
|
||||
{
|
||||
return static_cast<Node *>(*it);
|
||||
return static_cast< Node* >( *it );
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
template < typename Node >
|
||||
struct pointer_to_reference
|
||||
{
|
||||
template <typename Iterator>
|
||||
const Node * operator()(Iterator const & it)
|
||||
template < typename Iterator >
|
||||
const Node* operator()( Iterator const& it )
|
||||
{
|
||||
return static_cast<const Node *>(&*it);
|
||||
return static_cast< const Node* >( &*it );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename HandleType,
|
||||
typename Alloc,
|
||||
typename ValueCompare
|
||||
>
|
||||
template < typename HandleType, typename Alloc, typename ValueCompare >
|
||||
struct unordered_tree_iterator_storage
|
||||
{
|
||||
unordered_tree_iterator_storage(ValueCompare const & cmp)
|
||||
unordered_tree_iterator_storage( ValueCompare const& cmp )
|
||||
{}
|
||||
|
||||
void push(HandleType h)
|
||||
void push( HandleType h )
|
||||
{
|
||||
data_.push_back(h);
|
||||
data_.push_back( h );
|
||||
}
|
||||
|
||||
HandleType const & top(void)
|
||||
HandleType const& top( void )
|
||||
{
|
||||
return data_.back();
|
||||
}
|
||||
|
||||
void pop(void)
|
||||
void pop( void )
|
||||
{
|
||||
data_.pop_back();
|
||||
}
|
||||
|
||||
bool empty(void) const
|
||||
bool empty( void ) const
|
||||
{
|
||||
return data_.empty();
|
||||
}
|
||||
|
||||
std::vector<HandleType, typename boost::allocator_rebind<Alloc, HandleType>::type> data_;
|
||||
std::vector< HandleType, typename boost::allocator_rebind< Alloc, HandleType >::type > data_;
|
||||
};
|
||||
|
||||
template <typename ValueType,
|
||||
typename HandleType,
|
||||
typename Alloc,
|
||||
typename ValueCompare,
|
||||
typename ValueExtractor
|
||||
>
|
||||
struct ordered_tree_iterator_storage:
|
||||
ValueExtractor
|
||||
template < typename ValueType, typename HandleType, typename Alloc, typename ValueCompare, typename ValueExtractor >
|
||||
struct ordered_tree_iterator_storage : ValueExtractor
|
||||
{
|
||||
struct compare_values_by_handle:
|
||||
ValueExtractor,
|
||||
ValueCompare
|
||||
struct compare_values_by_handle : ValueExtractor, ValueCompare
|
||||
{
|
||||
compare_values_by_handle(ValueCompare const & cmp):
|
||||
ValueCompare(cmp)
|
||||
compare_values_by_handle( ValueCompare const& cmp ) :
|
||||
ValueCompare( cmp )
|
||||
{}
|
||||
|
||||
bool operator()(HandleType const & lhs, HandleType const & rhs) const
|
||||
bool operator()( HandleType const& lhs, HandleType const& rhs ) const
|
||||
{
|
||||
ValueType const & lhs_value = ValueExtractor::operator()(lhs->value);
|
||||
ValueType const & rhs_value = ValueExtractor::operator()(rhs->value);
|
||||
return ValueCompare::operator()(lhs_value, rhs_value);
|
||||
ValueType const& lhs_value = ValueExtractor::operator()( lhs->value );
|
||||
ValueType const& rhs_value = ValueExtractor::operator()( rhs->value );
|
||||
return ValueCompare::operator()( lhs_value, rhs_value );
|
||||
}
|
||||
};
|
||||
|
||||
ordered_tree_iterator_storage(ValueCompare const & cmp):
|
||||
data_(compare_values_by_handle(cmp))
|
||||
ordered_tree_iterator_storage( ValueCompare const& cmp ) :
|
||||
data_( compare_values_by_handle( cmp ) )
|
||||
{}
|
||||
|
||||
void push(HandleType h)
|
||||
void push( HandleType h )
|
||||
{
|
||||
data_.push(h);
|
||||
data_.push( h );
|
||||
}
|
||||
|
||||
void pop(void)
|
||||
void pop( void )
|
||||
{
|
||||
data_.pop();
|
||||
}
|
||||
|
||||
HandleType const & top(void)
|
||||
HandleType const& top( void )
|
||||
{
|
||||
return data_.top();
|
||||
}
|
||||
|
||||
bool empty(void) const BOOST_NOEXCEPT
|
||||
bool empty( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return data_.empty();
|
||||
}
|
||||
|
||||
std::priority_queue<HandleType,
|
||||
std::vector<HandleType, typename boost::allocator_rebind<Alloc, HandleType>::type>,
|
||||
compare_values_by_handle> data_;
|
||||
std::priority_queue< HandleType,
|
||||
std::vector< HandleType, typename boost::allocator_rebind< Alloc, HandleType >::type >,
|
||||
compare_values_by_handle >
|
||||
data_;
|
||||
};
|
||||
|
||||
|
||||
@@ -147,205 +139,184 @@ struct ordered_tree_iterator_storage:
|
||||
* ValueExtractor can convert Node->value to ValueType
|
||||
*
|
||||
* */
|
||||
template <typename Node,
|
||||
typename ValueType,
|
||||
typename Alloc = std::allocator<Node>,
|
||||
typename ValueExtractor = identity<typename Node::value_type>,
|
||||
typename PointerExtractor = dereferencer<Node>,
|
||||
bool check_null_pointer = false,
|
||||
bool ordered_iterator = false,
|
||||
typename ValueCompare = std::less<ValueType>
|
||||
>
|
||||
class tree_iterator:
|
||||
public boost::iterator_adaptor<tree_iterator<Node,
|
||||
ValueType,
|
||||
Alloc,
|
||||
ValueExtractor,
|
||||
PointerExtractor,
|
||||
check_null_pointer,
|
||||
ordered_iterator,
|
||||
ValueCompare
|
||||
>,
|
||||
const Node *,
|
||||
ValueType,
|
||||
boost::forward_traversal_tag
|
||||
>,
|
||||
template < typename Node,
|
||||
typename ValueType,
|
||||
typename Alloc = std::allocator< Node >,
|
||||
typename ValueExtractor = identity< typename Node::value_type >,
|
||||
typename PointerExtractor = dereferencer< Node >,
|
||||
bool check_null_pointer = false,
|
||||
bool ordered_iterator = false,
|
||||
typename ValueCompare = std::less< ValueType > >
|
||||
class tree_iterator :
|
||||
public boost::iterator_adaptor<
|
||||
tree_iterator< Node, ValueType, Alloc, ValueExtractor, PointerExtractor, check_null_pointer, ordered_iterator, ValueCompare >,
|
||||
const Node*,
|
||||
ValueType,
|
||||
boost::forward_traversal_tag >,
|
||||
ValueExtractor,
|
||||
PointerExtractor
|
||||
{
|
||||
typedef boost::iterator_adaptor<tree_iterator<Node,
|
||||
ValueType,
|
||||
Alloc,
|
||||
ValueExtractor,
|
||||
PointerExtractor,
|
||||
check_null_pointer,
|
||||
ordered_iterator,
|
||||
ValueCompare
|
||||
>,
|
||||
const Node *,
|
||||
ValueType,
|
||||
boost::forward_traversal_tag
|
||||
> adaptor_type;
|
||||
typedef boost::iterator_adaptor<
|
||||
tree_iterator< Node, ValueType, Alloc, ValueExtractor, PointerExtractor, check_null_pointer, ordered_iterator, ValueCompare >,
|
||||
const Node*,
|
||||
ValueType,
|
||||
boost::forward_traversal_tag >
|
||||
adaptor_type;
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
typedef typename boost::conditional< ordered_iterator,
|
||||
ordered_tree_iterator_storage<ValueType, const Node*, Alloc, ValueCompare, ValueExtractor>,
|
||||
unordered_tree_iterator_storage<const Node*, Alloc, ValueCompare>
|
||||
>::type
|
||||
unvisited_node_container;
|
||||
typedef typename boost::conditional<
|
||||
ordered_iterator,
|
||||
ordered_tree_iterator_storage< ValueType, const Node*, Alloc, ValueCompare, ValueExtractor >,
|
||||
unordered_tree_iterator_storage< const Node*, Alloc, ValueCompare > >::type unvisited_node_container;
|
||||
|
||||
public:
|
||||
tree_iterator(void):
|
||||
adaptor_type(0), unvisited_nodes(ValueCompare())
|
||||
tree_iterator( void ) :
|
||||
adaptor_type( 0 ),
|
||||
unvisited_nodes( ValueCompare() )
|
||||
{}
|
||||
|
||||
tree_iterator(ValueCompare const & cmp):
|
||||
adaptor_type(0), unvisited_nodes(cmp)
|
||||
tree_iterator( ValueCompare const& cmp ) :
|
||||
adaptor_type( 0 ),
|
||||
unvisited_nodes( cmp )
|
||||
{}
|
||||
|
||||
tree_iterator(const Node * it, ValueCompare const & cmp):
|
||||
adaptor_type(it), unvisited_nodes(cmp)
|
||||
tree_iterator( const Node* it, ValueCompare const& cmp ) :
|
||||
adaptor_type( it ),
|
||||
unvisited_nodes( cmp )
|
||||
{
|
||||
if (it)
|
||||
discover_nodes(it);
|
||||
if ( it )
|
||||
discover_nodes( it );
|
||||
}
|
||||
|
||||
/* fills the iterator from a list of possible top nodes */
|
||||
template <typename NodePointerIterator>
|
||||
tree_iterator(NodePointerIterator begin, NodePointerIterator end, const Node * top_node, ValueCompare const & cmp):
|
||||
adaptor_type(0), unvisited_nodes(cmp)
|
||||
template < typename NodePointerIterator >
|
||||
tree_iterator( NodePointerIterator begin, NodePointerIterator end, const Node* top_node, ValueCompare const& cmp ) :
|
||||
adaptor_type( 0 ),
|
||||
unvisited_nodes( cmp )
|
||||
{
|
||||
BOOST_STATIC_ASSERT(ordered_iterator);
|
||||
if (begin == end)
|
||||
BOOST_STATIC_ASSERT( ordered_iterator );
|
||||
if ( begin == end )
|
||||
return;
|
||||
|
||||
adaptor_type::base_reference() = top_node;
|
||||
discover_nodes(top_node);
|
||||
discover_nodes( top_node );
|
||||
|
||||
for (NodePointerIterator it = begin; it != end; ++it) {
|
||||
const Node * current_node = static_cast<const Node*>(&*it);
|
||||
if (current_node != top_node)
|
||||
unvisited_nodes.push(current_node);
|
||||
for ( NodePointerIterator it = begin; it != end; ++it ) {
|
||||
const Node* current_node = static_cast< const Node* >( &*it );
|
||||
if ( current_node != top_node )
|
||||
unvisited_nodes.push( current_node );
|
||||
}
|
||||
}
|
||||
|
||||
bool operator!=(tree_iterator const & rhs) const
|
||||
bool operator!=( tree_iterator const& rhs ) const
|
||||
{
|
||||
return adaptor_type::base() != rhs.base();
|
||||
}
|
||||
|
||||
bool operator==(tree_iterator const & rhs) const
|
||||
bool operator==( tree_iterator const& rhs ) const
|
||||
{
|
||||
return !operator!=(rhs);
|
||||
return !operator!=( rhs );
|
||||
}
|
||||
|
||||
const Node * get_node() const
|
||||
const Node* get_node() const
|
||||
{
|
||||
return adaptor_type::base_reference();
|
||||
}
|
||||
|
||||
private:
|
||||
void increment(void)
|
||||
void increment( void )
|
||||
{
|
||||
if (unvisited_nodes.empty())
|
||||
if ( unvisited_nodes.empty() )
|
||||
adaptor_type::base_reference() = 0;
|
||||
else {
|
||||
const Node * next = unvisited_nodes.top();
|
||||
const Node* next = unvisited_nodes.top();
|
||||
unvisited_nodes.pop();
|
||||
discover_nodes(next);
|
||||
discover_nodes( next );
|
||||
adaptor_type::base_reference() = next;
|
||||
}
|
||||
}
|
||||
|
||||
ValueType const & dereference() const
|
||||
ValueType const& dereference() const
|
||||
{
|
||||
return ValueExtractor::operator()(adaptor_type::base_reference()->value);
|
||||
return ValueExtractor::operator()( adaptor_type::base_reference()->value );
|
||||
}
|
||||
|
||||
void discover_nodes(const Node * n)
|
||||
void discover_nodes( const Node* n )
|
||||
{
|
||||
for (typename Node::const_child_iterator it = n->children.begin(); it != n->children.end(); ++it) {
|
||||
const Node * n = PointerExtractor::operator()(it);
|
||||
if (check_null_pointer && n == NULL)
|
||||
for ( typename Node::const_child_iterator it = n->children.begin(); it != n->children.end(); ++it ) {
|
||||
const Node* n = PointerExtractor::operator()( it );
|
||||
if ( check_null_pointer && n == NULL )
|
||||
continue;
|
||||
unvisited_nodes.push(n);
|
||||
unvisited_nodes.push( n );
|
||||
}
|
||||
}
|
||||
|
||||
unvisited_node_container unvisited_nodes;
|
||||
};
|
||||
|
||||
template <typename Node, typename NodeList>
|
||||
template < typename Node, typename NodeList >
|
||||
struct list_iterator_converter
|
||||
{
|
||||
typename NodeList::const_iterator operator()(const Node * node)
|
||||
typename NodeList::const_iterator operator()( const Node* node )
|
||||
{
|
||||
return NodeList::s_iterator_to(*node);
|
||||
return NodeList::s_iterator_to( *node );
|
||||
}
|
||||
|
||||
Node * operator()(typename NodeList::const_iterator it)
|
||||
Node* operator()( typename NodeList::const_iterator it )
|
||||
{
|
||||
return const_cast<Node*>(static_cast<const Node*>(&*it));
|
||||
return const_cast< Node* >( static_cast< const Node* >( &*it ) );
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Node,
|
||||
typename NodeIterator,
|
||||
typename ValueType,
|
||||
typename ValueExtractor = identity<typename Node::value_type>,
|
||||
typename IteratorCoverter = identity<NodeIterator>
|
||||
>
|
||||
class recursive_tree_iterator:
|
||||
public boost::iterator_adaptor<recursive_tree_iterator<Node,
|
||||
NodeIterator,
|
||||
ValueType,
|
||||
ValueExtractor,
|
||||
IteratorCoverter
|
||||
>,
|
||||
template < typename Node,
|
||||
typename NodeIterator,
|
||||
typename ValueType,
|
||||
typename ValueExtractor = identity< typename Node::value_type >,
|
||||
typename IteratorCoverter = identity< NodeIterator > >
|
||||
class recursive_tree_iterator :
|
||||
public boost::iterator_adaptor< recursive_tree_iterator< Node, NodeIterator, ValueType, ValueExtractor, IteratorCoverter >,
|
||||
NodeIterator,
|
||||
ValueType const,
|
||||
boost::bidirectional_traversal_tag>,
|
||||
ValueExtractor, IteratorCoverter
|
||||
boost::bidirectional_traversal_tag >,
|
||||
ValueExtractor,
|
||||
IteratorCoverter
|
||||
{
|
||||
typedef boost::iterator_adaptor<recursive_tree_iterator<Node,
|
||||
NodeIterator,
|
||||
ValueType,
|
||||
ValueExtractor,
|
||||
IteratorCoverter
|
||||
>,
|
||||
NodeIterator,
|
||||
ValueType const,
|
||||
boost::bidirectional_traversal_tag> adaptor_type;
|
||||
typedef boost::iterator_adaptor<
|
||||
recursive_tree_iterator< Node, NodeIterator, ValueType, ValueExtractor, IteratorCoverter >,
|
||||
NodeIterator,
|
||||
ValueType const,
|
||||
boost::bidirectional_traversal_tag >
|
||||
adaptor_type;
|
||||
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
|
||||
public:
|
||||
recursive_tree_iterator(void):
|
||||
adaptor_type(0)
|
||||
recursive_tree_iterator( void ) :
|
||||
adaptor_type( 0 )
|
||||
{}
|
||||
|
||||
explicit recursive_tree_iterator(NodeIterator const & it):
|
||||
adaptor_type(it)
|
||||
explicit recursive_tree_iterator( NodeIterator const& it ) :
|
||||
adaptor_type( it )
|
||||
{}
|
||||
|
||||
void increment(void)
|
||||
void increment( void )
|
||||
{
|
||||
NodeIterator next = adaptor_type::base_reference();
|
||||
|
||||
const Node * n = get_node(next);
|
||||
if (n->children.empty()) {
|
||||
const Node * parent = get_node(next)->get_parent();
|
||||
const Node* n = get_node( next );
|
||||
if ( n->children.empty() ) {
|
||||
const Node* parent = get_node( next )->get_parent();
|
||||
|
||||
++next;
|
||||
|
||||
while (true) {
|
||||
if (parent == NULL || next != parent->children.end())
|
||||
while ( true ) {
|
||||
if ( parent == NULL || next != parent->children.end() )
|
||||
break;
|
||||
|
||||
next = IteratorCoverter::operator()(parent);
|
||||
parent = get_node(next)->get_parent();
|
||||
next = IteratorCoverter::operator()( parent );
|
||||
parent = get_node( next )->get_parent();
|
||||
++next;
|
||||
}
|
||||
} else
|
||||
@@ -355,25 +326,23 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
ValueType const & dereference() const
|
||||
ValueType const& dereference() const
|
||||
{
|
||||
return ValueExtractor::operator()(get_node(adaptor_type::base_reference())->value);
|
||||
return ValueExtractor::operator()( get_node( adaptor_type::base_reference() )->value );
|
||||
}
|
||||
|
||||
static const Node * get_node(NodeIterator const & it)
|
||||
static const Node* get_node( NodeIterator const& it )
|
||||
{
|
||||
return static_cast<const Node *>(&*it);
|
||||
return static_cast< const Node* >( &*it );
|
||||
}
|
||||
|
||||
const Node * get_node() const
|
||||
const Node* get_node() const
|
||||
{
|
||||
return get_node(adaptor_type::base_reference());
|
||||
return get_node( adaptor_type::base_reference() );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}}} // namespace boost::heap::detail
|
||||
|
||||
#endif /* BOOST_HEAP_DETAIL_TREE_ITERATOR_HPP */
|
||||
|
||||
@@ -23,82 +23,76 @@
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_DOXYGEN_INVOKED
|
||||
#ifdef BOOST_HEAP_SANITYCHECKS
|
||||
#define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
#else
|
||||
#define BOOST_HEAP_ASSERT(expression)
|
||||
#endif
|
||||
# ifdef BOOST_HEAP_SANITYCHECKS
|
||||
# define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
# else
|
||||
# define BOOST_HEAP_ASSERT( expression )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
namespace detail {
|
||||
|
||||
typedef parameter::parameters<boost::parameter::optional<tag::allocator>,
|
||||
boost::parameter::optional<tag::compare>,
|
||||
boost::parameter::optional<tag::stable>,
|
||||
boost::parameter::optional<tag::constant_time_size>,
|
||||
boost::parameter::optional<tag::stability_counter_type>
|
||||
> fibonacci_heap_signature;
|
||||
typedef parameter::parameters< boost::parameter::optional< tag::allocator >,
|
||||
boost::parameter::optional< tag::compare >,
|
||||
boost::parameter::optional< tag::stable >,
|
||||
boost::parameter::optional< tag::constant_time_size >,
|
||||
boost::parameter::optional< tag::stability_counter_type > >
|
||||
fibonacci_heap_signature;
|
||||
|
||||
template <typename T, typename Parspec>
|
||||
template < typename T, typename Parspec >
|
||||
struct make_fibonacci_heap_base
|
||||
{
|
||||
static const bool constant_time_size = parameter::binding<Parspec,
|
||||
tag::constant_time_size,
|
||||
boost::true_type
|
||||
>::type::value;
|
||||
static const bool constant_time_size
|
||||
= parameter::binding< Parspec, tag::constant_time_size, boost::true_type >::type::value;
|
||||
|
||||
typedef typename detail::make_heap_base<T, Parspec, constant_time_size>::type base_type;
|
||||
typedef typename detail::make_heap_base<T, Parspec, constant_time_size>::allocator_argument allocator_argument;
|
||||
typedef typename detail::make_heap_base<T, Parspec, constant_time_size>::compare_argument compare_argument;
|
||||
typedef marked_heap_node<typename base_type::internal_type> node_type;
|
||||
typedef typename detail::make_heap_base< T, Parspec, constant_time_size >::type base_type;
|
||||
typedef typename detail::make_heap_base< T, Parspec, constant_time_size >::allocator_argument allocator_argument;
|
||||
typedef typename detail::make_heap_base< T, Parspec, constant_time_size >::compare_argument compare_argument;
|
||||
typedef marked_heap_node< typename base_type::internal_type > node_type;
|
||||
|
||||
typedef typename boost::allocator_rebind<allocator_argument, node_type>::type allocator_type;
|
||||
typedef typename boost::allocator_rebind< allocator_argument, node_type >::type allocator_type;
|
||||
|
||||
struct type:
|
||||
base_type,
|
||||
allocator_type
|
||||
struct type : base_type, allocator_type
|
||||
{
|
||||
type(compare_argument const & arg):
|
||||
base_type(arg)
|
||||
type( compare_argument const& arg ) :
|
||||
base_type( arg )
|
||||
{}
|
||||
|
||||
type(type const & rhs):
|
||||
base_type(static_cast<base_type const &>(rhs)),
|
||||
allocator_type(static_cast<allocator_type const &>(rhs))
|
||||
type( type const& rhs ) :
|
||||
base_type( static_cast< base_type const& >( rhs ) ),
|
||||
allocator_type( static_cast< allocator_type const& >( rhs ) )
|
||||
{}
|
||||
|
||||
type & operator=(type const & rhs)
|
||||
type& operator=( type const& rhs )
|
||||
{
|
||||
base_type::operator=(static_cast<base_type const &>(rhs));
|
||||
allocator_type::operator=(static_cast<allocator_type const &>(rhs));
|
||||
base_type::operator=( static_cast< base_type const& >( rhs ) );
|
||||
allocator_type::operator=( static_cast< allocator_type const& >( rhs ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
type(type && rhs):
|
||||
base_type(std::move(static_cast<base_type&>(rhs))),
|
||||
allocator_type(std::move(static_cast<allocator_type&>(rhs)))
|
||||
type( type&& rhs ) :
|
||||
base_type( std::move( static_cast< base_type& >( rhs ) ) ),
|
||||
allocator_type( std::move( static_cast< allocator_type& >( rhs ) ) )
|
||||
{}
|
||||
|
||||
type & operator=(type && rhs)
|
||||
type& operator=( type&& rhs )
|
||||
{
|
||||
base_type::operator=(std::move(static_cast<base_type&>(rhs)));
|
||||
allocator_type::operator=(std::move(static_cast<allocator_type&>(rhs)));
|
||||
base_type::operator=( std::move( static_cast< base_type& >( rhs ) ) );
|
||||
allocator_type::operator=( std::move( static_cast< allocator_type& >( rhs ) ) );
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/**
|
||||
@@ -117,224 +111,224 @@ struct make_fibonacci_heap_base
|
||||
*
|
||||
*/
|
||||
#ifdef BOOST_DOXYGEN_INVOKED
|
||||
template<class T, class ...Options>
|
||||
template < class T, class... Options >
|
||||
#else
|
||||
template <typename T,
|
||||
class A0 = boost::parameter::void_,
|
||||
class A1 = boost::parameter::void_,
|
||||
class A2 = boost::parameter::void_,
|
||||
class A3 = boost::parameter::void_,
|
||||
class A4 = boost::parameter::void_
|
||||
>
|
||||
template < typename T,
|
||||
class A0 = boost::parameter::void_,
|
||||
class A1 = boost::parameter::void_,
|
||||
class A2 = boost::parameter::void_,
|
||||
class A3 = boost::parameter::void_,
|
||||
class A4 = boost::parameter::void_ >
|
||||
#endif
|
||||
class fibonacci_heap:
|
||||
private detail::make_fibonacci_heap_base<T,
|
||||
typename detail::fibonacci_heap_signature::bind<A0, A1, A2, A3, A4>::type
|
||||
>::type
|
||||
class fibonacci_heap :
|
||||
private detail::
|
||||
make_fibonacci_heap_base< T, typename detail::fibonacci_heap_signature::bind< A0, A1, A2, A3, A4 >::type >::type
|
||||
{
|
||||
typedef typename detail::fibonacci_heap_signature::bind<A0, A1, A2, A3, A4>::type bound_args;
|
||||
typedef detail::make_fibonacci_heap_base<T, bound_args> base_maker;
|
||||
typedef typename base_maker::type super_t;
|
||||
typedef typename detail::fibonacci_heap_signature::bind< A0, A1, A2, A3, A4 >::type bound_args;
|
||||
typedef detail::make_fibonacci_heap_base< T, bound_args > base_maker;
|
||||
typedef typename base_maker::type super_t;
|
||||
|
||||
typedef typename super_t::size_holder_type size_holder;
|
||||
typedef typename super_t::internal_type internal_type;
|
||||
typedef typename super_t::size_holder_type size_holder;
|
||||
typedef typename super_t::internal_type internal_type;
|
||||
typedef typename base_maker::allocator_argument allocator_argument;
|
||||
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
friend struct heap_merge_emulate;
|
||||
|
||||
private:
|
||||
#ifndef BOOST_DOXYGEN_INVOKED
|
||||
struct implementation_defined:
|
||||
detail::extract_allocator_types<typename base_maker::allocator_argument>
|
||||
struct implementation_defined : detail::extract_allocator_types< typename base_maker::allocator_argument >
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef typename detail::extract_allocator_types<typename base_maker::allocator_argument>::size_type size_type;
|
||||
typedef typename detail::extract_allocator_types<typename base_maker::allocator_argument>::reference reference;
|
||||
typedef typename detail::extract_allocator_types< typename base_maker::allocator_argument >::size_type size_type;
|
||||
typedef typename detail::extract_allocator_types< typename base_maker::allocator_argument >::reference reference;
|
||||
|
||||
typedef typename base_maker::compare_argument value_compare;
|
||||
typedef typename base_maker::allocator_type allocator_type;
|
||||
typedef typename base_maker::allocator_type allocator_type;
|
||||
|
||||
typedef typename boost::allocator_pointer<allocator_type>::type node_pointer;
|
||||
typedef typename boost::allocator_const_pointer<allocator_type>::type const_node_pointer;
|
||||
typedef typename boost::allocator_pointer< allocator_type >::type node_pointer;
|
||||
typedef typename boost::allocator_const_pointer< allocator_type >::type const_node_pointer;
|
||||
|
||||
typedef detail::heap_node_list node_list_type;
|
||||
typedef typename node_list_type::iterator node_list_iterator;
|
||||
typedef detail::heap_node_list node_list_type;
|
||||
typedef typename node_list_type::iterator node_list_iterator;
|
||||
typedef typename node_list_type::const_iterator node_list_const_iterator;
|
||||
|
||||
typedef typename base_maker::node_type node;
|
||||
|
||||
typedef detail::value_extractor<value_type, internal_type, super_t> value_extractor;
|
||||
typedef typename super_t::internal_compare internal_compare;
|
||||
typedef detail::node_handle<node_pointer, super_t, reference> handle_type;
|
||||
typedef detail::value_extractor< value_type, internal_type, super_t > value_extractor;
|
||||
typedef typename super_t::internal_compare internal_compare;
|
||||
typedef detail::node_handle< node_pointer, super_t, reference > handle_type;
|
||||
|
||||
typedef detail::recursive_tree_iterator<node,
|
||||
node_list_const_iterator,
|
||||
const value_type,
|
||||
value_extractor,
|
||||
detail::list_iterator_converter<node, node_list_type>
|
||||
> iterator;
|
||||
typedef detail::recursive_tree_iterator< node,
|
||||
node_list_const_iterator,
|
||||
const value_type,
|
||||
value_extractor,
|
||||
detail::list_iterator_converter< node, node_list_type > >
|
||||
iterator;
|
||||
typedef iterator const_iterator;
|
||||
|
||||
typedef detail::tree_iterator<node,
|
||||
const value_type,
|
||||
allocator_type,
|
||||
value_extractor,
|
||||
detail::list_iterator_converter<node, node_list_type>,
|
||||
true,
|
||||
true,
|
||||
value_compare
|
||||
> ordered_iterator;
|
||||
typedef detail::tree_iterator< node,
|
||||
const value_type,
|
||||
allocator_type,
|
||||
value_extractor,
|
||||
detail::list_iterator_converter< node, node_list_type >,
|
||||
true,
|
||||
true,
|
||||
value_compare >
|
||||
ordered_iterator;
|
||||
};
|
||||
|
||||
typedef typename implementation_defined::node node;
|
||||
typedef typename implementation_defined::node_pointer node_pointer;
|
||||
typedef typename implementation_defined::node_list_type node_list_type;
|
||||
typedef typename implementation_defined::node_list_iterator node_list_iterator;
|
||||
typedef typename implementation_defined::node node;
|
||||
typedef typename implementation_defined::node_pointer node_pointer;
|
||||
typedef typename implementation_defined::node_list_type node_list_type;
|
||||
typedef typename implementation_defined::node_list_iterator node_list_iterator;
|
||||
typedef typename implementation_defined::node_list_const_iterator node_list_const_iterator;
|
||||
typedef typename implementation_defined::internal_compare internal_compare;
|
||||
typedef typename implementation_defined::internal_compare internal_compare;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::allocator_type allocator_type;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::allocator_type allocator_type;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
/// \copydoc boost::heap::priority_queue::iterator
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::ordered_iterator ordered_iterator;
|
||||
|
||||
typedef typename implementation_defined::handle_type handle_type;
|
||||
|
||||
static const bool constant_time_size = base_maker::constant_time_size;
|
||||
static const bool constant_time_size = base_maker::constant_time_size;
|
||||
static const bool has_ordered_iterators = true;
|
||||
static const bool is_mergable = true;
|
||||
static const bool is_stable = detail::extract_stable<bound_args>::value;
|
||||
static const bool has_reserve = false;
|
||||
static const bool is_mergable = true;
|
||||
static const bool is_stable = detail::extract_stable< bound_args >::value;
|
||||
static const bool has_reserve = false;
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::priority_queue(value_compare const &)
|
||||
explicit fibonacci_heap(value_compare const & cmp = value_compare()):
|
||||
super_t(cmp), top_element(0)
|
||||
explicit fibonacci_heap( value_compare const& cmp = value_compare() ) :
|
||||
super_t( cmp ),
|
||||
top_element( 0 )
|
||||
{}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::priority_queue(priority_queue const &)
|
||||
fibonacci_heap(fibonacci_heap const & rhs):
|
||||
super_t(rhs), top_element(0)
|
||||
fibonacci_heap( fibonacci_heap const& rhs ) :
|
||||
super_t( rhs ),
|
||||
top_element( 0 )
|
||||
{
|
||||
if (rhs.empty())
|
||||
if ( rhs.empty() )
|
||||
return;
|
||||
|
||||
clone_forest(rhs);
|
||||
size_holder::set_size(rhs.size());
|
||||
clone_forest( rhs );
|
||||
size_holder::set_size( rhs.size() );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
/// \copydoc boost::heap::priority_queue::priority_queue(priority_queue &&)
|
||||
fibonacci_heap(fibonacci_heap && rhs):
|
||||
super_t(std::move(rhs)), top_element(rhs.top_element)
|
||||
fibonacci_heap( fibonacci_heap&& rhs ) :
|
||||
super_t( std::move( rhs ) ),
|
||||
top_element( rhs.top_element )
|
||||
{
|
||||
roots.splice(roots.begin(), rhs.roots);
|
||||
roots.splice( roots.begin(), rhs.roots );
|
||||
rhs.top_element = NULL;
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator=(priority_queue &&)
|
||||
fibonacci_heap & operator=(fibonacci_heap && rhs)
|
||||
fibonacci_heap& operator=( fibonacci_heap&& rhs )
|
||||
{
|
||||
clear();
|
||||
|
||||
super_t::operator=(std::move(rhs));
|
||||
roots.splice(roots.begin(), rhs.roots);
|
||||
top_element = rhs.top_element;
|
||||
super_t::operator=( std::move( rhs ) );
|
||||
roots.splice( roots.begin(), rhs.roots );
|
||||
top_element = rhs.top_element;
|
||||
rhs.top_element = NULL;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator=(priority_queue const &)
|
||||
fibonacci_heap & operator=(fibonacci_heap const & rhs)
|
||||
fibonacci_heap& operator=( fibonacci_heap const& rhs )
|
||||
{
|
||||
clear();
|
||||
size_holder::set_size(rhs.size());
|
||||
static_cast<super_t&>(*this) = rhs;
|
||||
size_holder::set_size( rhs.size() );
|
||||
static_cast< super_t& >( *this ) = rhs;
|
||||
|
||||
if (rhs.empty())
|
||||
if ( rhs.empty() )
|
||||
top_element = NULL;
|
||||
else
|
||||
clone_forest(rhs);
|
||||
clone_forest( rhs );
|
||||
return *this;
|
||||
}
|
||||
|
||||
~fibonacci_heap(void)
|
||||
~fibonacci_heap( void )
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::empty
|
||||
bool empty(void) const
|
||||
bool empty( void ) const
|
||||
{
|
||||
if (constant_time_size)
|
||||
if ( constant_time_size )
|
||||
return size() == 0;
|
||||
else
|
||||
return roots.empty();
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::size
|
||||
size_type size(void) const
|
||||
size_type size( void ) const
|
||||
{
|
||||
if (constant_time_size)
|
||||
if ( constant_time_size )
|
||||
return size_holder::get_size();
|
||||
|
||||
if (empty())
|
||||
if ( empty() )
|
||||
return 0;
|
||||
else
|
||||
return detail::count_list_nodes<node, node_list_type>(roots);
|
||||
return detail::count_list_nodes< node, node_list_type >( roots );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::max_size
|
||||
size_type max_size(void) const
|
||||
size_type max_size( void ) const
|
||||
{
|
||||
const allocator_type& alloc = *this;
|
||||
return boost::allocator_max_size(alloc);
|
||||
return boost::allocator_max_size( alloc );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::clear
|
||||
void clear(void)
|
||||
void clear( void )
|
||||
{
|
||||
typedef detail::node_disposer<node, typename node_list_type::value_type, allocator_type> disposer;
|
||||
roots.clear_and_dispose(disposer(*this));
|
||||
typedef detail::node_disposer< node, typename node_list_type::value_type, allocator_type > disposer;
|
||||
roots.clear_and_dispose( disposer( *this ) );
|
||||
|
||||
size_holder::set_size(0);
|
||||
size_holder::set_size( 0 );
|
||||
top_element = NULL;
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::get_allocator
|
||||
allocator_type get_allocator(void) const
|
||||
allocator_type get_allocator( void ) const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::swap
|
||||
void swap(fibonacci_heap & rhs)
|
||||
void swap( fibonacci_heap& rhs )
|
||||
{
|
||||
super_t::swap(rhs);
|
||||
std::swap(top_element, rhs.top_element);
|
||||
roots.swap(rhs.roots);
|
||||
super_t::swap( rhs );
|
||||
std::swap( top_element, rhs.top_element );
|
||||
roots.swap( rhs.roots );
|
||||
}
|
||||
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::top
|
||||
value_type const & top(void) const
|
||||
value_type const& top( void ) const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
BOOST_ASSERT( !empty() );
|
||||
|
||||
return super_t::get_value(top_element->value);
|
||||
return super_t::get_value( top_element->value );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,42 +339,43 @@ public:
|
||||
* \b Note: Does not invalidate iterators.
|
||||
*
|
||||
* */
|
||||
handle_type push(value_type const & v)
|
||||
handle_type push( value_type const& v )
|
||||
{
|
||||
size_holder::increment();
|
||||
|
||||
allocator_type& alloc = *this;
|
||||
node_pointer n = alloc.allocate(1);
|
||||
new(n) node(super_t::make_node(v));
|
||||
roots.push_front(*n);
|
||||
node_pointer n = alloc.allocate( 1 );
|
||||
new ( n ) node( super_t::make_node( v ) );
|
||||
roots.push_front( *n );
|
||||
|
||||
if (!top_element || super_t::operator()(top_element->value, n->value))
|
||||
if ( !top_element || super_t::operator()( top_element->value, n->value ) )
|
||||
top_element = n;
|
||||
return handle_type(n);
|
||||
return handle_type( n );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
/**
|
||||
* \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place. Returns handle to element.
|
||||
* \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place. Returns
|
||||
* handle to element.
|
||||
*
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* \b Note: Does not invalidate iterators.
|
||||
*
|
||||
* */
|
||||
template <class... Args>
|
||||
handle_type emplace(Args&&... args)
|
||||
template < class... Args >
|
||||
handle_type emplace( Args&&... args )
|
||||
{
|
||||
size_holder::increment();
|
||||
|
||||
allocator_type& alloc = *this;
|
||||
node_pointer n = alloc.allocate(1);
|
||||
new(n) node(super_t::make_node(std::forward<Args>(args)...));
|
||||
roots.push_front(*n);
|
||||
node_pointer n = alloc.allocate( 1 );
|
||||
new ( n ) node( super_t::make_node( std::forward< Args >( args )... ) );
|
||||
roots.push_front( *n );
|
||||
|
||||
if (!top_element || super_t::operator()(top_element->value, n->value))
|
||||
if ( !top_element || super_t::operator()( top_element->value, n->value ) )
|
||||
top_element = n;
|
||||
return handle_type(n);
|
||||
return handle_type( n );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -390,14 +385,14 @@ public:
|
||||
* \b Complexity: Logarithmic (amortized). Linear (worst case).
|
||||
*
|
||||
* */
|
||||
void pop(void)
|
||||
void pop( void )
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
BOOST_ASSERT( !empty() );
|
||||
|
||||
node_pointer element = top_element;
|
||||
roots.erase(node_list_type::s_iterator_to(*element));
|
||||
roots.erase( node_list_type::s_iterator_to( *element ) );
|
||||
|
||||
finish_erase_or_pop(element);
|
||||
finish_erase_or_pop( element );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,12 +401,12 @@ public:
|
||||
* \b Complexity: Logarithmic if current value < v, Constant otherwise.
|
||||
*
|
||||
* */
|
||||
void update (handle_type handle, const_reference v)
|
||||
void update( handle_type handle, const_reference v )
|
||||
{
|
||||
if (super_t::operator()(super_t::get_value(handle.node_->value), v))
|
||||
increase(handle, v);
|
||||
if ( super_t::operator()( super_t::get_value( handle.node_->value ), v ) )
|
||||
increase( handle, v );
|
||||
else
|
||||
decrease(handle, v);
|
||||
decrease( handle, v );
|
||||
}
|
||||
|
||||
/** \copydoc boost::heap::fibonacci_heap::update(handle_type, const_reference)
|
||||
@@ -419,10 +414,10 @@ public:
|
||||
* \b Rationale: The lazy update function is a modification of the traditional update, that just invalidates
|
||||
* the iterator to the object referred to by the handle.
|
||||
* */
|
||||
void update_lazy(handle_type handle, const_reference v)
|
||||
void update_lazy( handle_type handle, const_reference v )
|
||||
{
|
||||
handle.node_->value = super_t::make_node(v);
|
||||
update_lazy(handle);
|
||||
handle.node_->value = super_t::make_node( v );
|
||||
update_lazy( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,9 +427,9 @@ public:
|
||||
*
|
||||
* \b Note: If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void update (handle_type handle)
|
||||
void update( handle_type handle )
|
||||
{
|
||||
update_lazy(handle);
|
||||
update_lazy( handle );
|
||||
consolidate();
|
||||
}
|
||||
|
||||
@@ -443,33 +438,33 @@ public:
|
||||
* \b Rationale: The lazy update function is a modification of the traditional update, that just invalidates
|
||||
* the iterator to the object referred to by the handle.
|
||||
* */
|
||||
void update_lazy (handle_type handle)
|
||||
void update_lazy( handle_type handle )
|
||||
{
|
||||
node_pointer n = handle.node_;
|
||||
node_pointer n = handle.node_;
|
||||
node_pointer parent = n->get_parent();
|
||||
|
||||
if (parent) {
|
||||
if ( parent ) {
|
||||
n->parent = NULL;
|
||||
roots.splice(roots.begin(), parent->children, node_list_type::s_iterator_to(*n));
|
||||
roots.splice( roots.begin(), parent->children, node_list_type::s_iterator_to( *n ) );
|
||||
}
|
||||
add_children_to_root(n);
|
||||
add_children_to_root( n );
|
||||
|
||||
if (super_t::operator()(top_element->value, n->value))
|
||||
if ( super_t::operator()( top_element->value, n->value ) )
|
||||
top_element = n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* \b Effects: Assigns \c v to the element handled by \c handle & updates the priority queue.
|
||||
*
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* \b Note: The new value is expected to be greater than the current one
|
||||
* */
|
||||
void increase (handle_type handle, const_reference v)
|
||||
void increase( handle_type handle, const_reference v )
|
||||
{
|
||||
handle.node_->value = super_t::make_node(v);
|
||||
increase(handle);
|
||||
handle.node_->value = super_t::make_node( v );
|
||||
increase( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -479,19 +474,19 @@ public:
|
||||
*
|
||||
* \b Note: If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void increase (handle_type handle)
|
||||
void increase( handle_type handle )
|
||||
{
|
||||
node_pointer n = handle.node_;
|
||||
|
||||
if (n->parent) {
|
||||
if (super_t::operator()(n->get_parent()->value, n->value)) {
|
||||
if ( n->parent ) {
|
||||
if ( super_t::operator()( n->get_parent()->value, n->value ) ) {
|
||||
node_pointer parent = n->get_parent();
|
||||
cut(n);
|
||||
cascading_cut(parent);
|
||||
cut( n );
|
||||
cascading_cut( parent );
|
||||
}
|
||||
}
|
||||
|
||||
if (super_t::operator()(top_element->value, n->value)) {
|
||||
if ( super_t::operator()( top_element->value, n->value ) ) {
|
||||
top_element = n;
|
||||
return;
|
||||
}
|
||||
@@ -504,10 +499,10 @@ public:
|
||||
*
|
||||
* \b Note: The new value is expected to be less than the current one
|
||||
* */
|
||||
void decrease (handle_type handle, const_reference v)
|
||||
void decrease( handle_type handle, const_reference v )
|
||||
{
|
||||
handle.node_->value = super_t::make_node(v);
|
||||
decrease(handle);
|
||||
handle.node_->value = super_t::make_node( v );
|
||||
decrease( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -515,11 +510,12 @@ public:
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
*
|
||||
* \b Note: The new value is expected to be less than the current one. If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* \b Note: The new value is expected to be less than the current one. If this is not called, after a handle has
|
||||
* been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void decrease (handle_type handle)
|
||||
void decrease( handle_type handle )
|
||||
{
|
||||
update(handle);
|
||||
update( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,29 +523,29 @@ public:
|
||||
*
|
||||
* \b Complexity: Logarithmic.
|
||||
* */
|
||||
void erase(handle_type const & handle)
|
||||
void erase( handle_type const& handle )
|
||||
{
|
||||
node_pointer element = handle.node_;
|
||||
node_pointer parent = element->get_parent();
|
||||
node_pointer parent = element->get_parent();
|
||||
|
||||
if (parent)
|
||||
parent->children.erase(node_list_type::s_iterator_to(*element));
|
||||
if ( parent )
|
||||
parent->children.erase( node_list_type::s_iterator_to( *element ) );
|
||||
else
|
||||
roots.erase(node_list_type::s_iterator_to(*element));
|
||||
roots.erase( node_list_type::s_iterator_to( *element ) );
|
||||
|
||||
finish_erase_or_pop(element);
|
||||
finish_erase_or_pop( element );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::begin
|
||||
iterator begin(void) const
|
||||
iterator begin( void ) const
|
||||
{
|
||||
return iterator(roots.begin());
|
||||
return iterator( roots.begin() );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::end
|
||||
iterator end(void) const
|
||||
iterator end( void ) const
|
||||
{
|
||||
return iterator(roots.end());
|
||||
return iterator( roots.end() );
|
||||
}
|
||||
|
||||
|
||||
@@ -558,9 +554,9 @@ public:
|
||||
*
|
||||
* \b Note: Ordered iterators traverse the priority queue in heap order.
|
||||
* */
|
||||
ordered_iterator ordered_begin(void) const
|
||||
ordered_iterator ordered_begin( void ) const
|
||||
{
|
||||
return ordered_iterator(roots.begin(), roots.end(), top_element, super_t::value_comp());
|
||||
return ordered_iterator( roots.begin(), roots.end(), top_element, super_t::value_comp() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -568,9 +564,9 @@ public:
|
||||
*
|
||||
* \b Note: Ordered iterators traverse the priority queue in heap order.
|
||||
* */
|
||||
ordered_iterator ordered_end(void) const
|
||||
ordered_iterator ordered_end( void ) const
|
||||
{
|
||||
return ordered_iterator(NULL, super_t::value_comp());
|
||||
return ordered_iterator( NULL, super_t::value_comp() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -579,188 +575,187 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
void merge(fibonacci_heap & rhs)
|
||||
void merge( fibonacci_heap& rhs )
|
||||
{
|
||||
size_holder::add(rhs.get_size());
|
||||
size_holder::add( rhs.get_size() );
|
||||
|
||||
if (!top_element ||
|
||||
(rhs.top_element && super_t::operator()(top_element->value, rhs.top_element->value)))
|
||||
if ( !top_element || ( rhs.top_element && super_t::operator()( top_element->value, rhs.top_element->value ) ) )
|
||||
top_element = rhs.top_element;
|
||||
|
||||
roots.splice(roots.end(), rhs.roots);
|
||||
roots.splice( roots.end(), rhs.roots );
|
||||
|
||||
rhs.top_element = NULL;
|
||||
rhs.set_size(0);
|
||||
rhs.set_size( 0 );
|
||||
|
||||
super_t::set_stability_count((std::max)(super_t::get_stability_count(),
|
||||
rhs.get_stability_count()));
|
||||
rhs.set_stability_count(0);
|
||||
super_t::set_stability_count( ( std::max )( super_t::get_stability_count(), rhs.get_stability_count() ) );
|
||||
rhs.set_stability_count( 0 );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::d_ary_heap_mutable::s_handle_from_iterator
|
||||
static handle_type s_handle_from_iterator(iterator const & it)
|
||||
static handle_type s_handle_from_iterator( iterator const& it )
|
||||
{
|
||||
node * ptr = const_cast<node *>(it.get_node());
|
||||
return handle_type(ptr);
|
||||
node* ptr = const_cast< node* >( it.get_node() );
|
||||
return handle_type( ptr );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::value_comp
|
||||
value_compare const & value_comp(void) const
|
||||
value_compare const& value_comp( void ) const
|
||||
{
|
||||
return super_t::value_comp();
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator<(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator<(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator<( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_compare(*this, rhs);
|
||||
return detail::heap_compare( *this, rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator>(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator>(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator>( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_compare(rhs, *this);
|
||||
return detail::heap_compare( rhs, *this );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator>=(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator>=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator>=( HeapType const& rhs ) const
|
||||
{
|
||||
return !operator<(rhs);
|
||||
return !operator<( rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator<=(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator<=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator<=( HeapType const& rhs ) const
|
||||
{
|
||||
return !operator>(rhs);
|
||||
return !operator>( rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator==(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator==(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator==( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_equality(*this, rhs);
|
||||
return detail::heap_equality( *this, rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator!=(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator!=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator!=( HeapType const& rhs ) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
return !( *this == rhs );
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_DOXYGEN_INVOKED)
|
||||
void clone_forest(fibonacci_heap const & rhs)
|
||||
#if !defined( BOOST_DOXYGEN_INVOKED )
|
||||
void clone_forest( fibonacci_heap const& rhs )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(roots.empty());
|
||||
typedef typename node::template node_cloner<allocator_type> node_cloner;
|
||||
roots.clone_from(rhs.roots, node_cloner(*this, NULL), detail::nop_disposer());
|
||||
BOOST_HEAP_ASSERT( roots.empty() );
|
||||
typedef typename node::template node_cloner< allocator_type > node_cloner;
|
||||
roots.clone_from( rhs.roots, node_cloner( *this, NULL ), detail::nop_disposer() );
|
||||
|
||||
top_element = detail::find_max_child<node_list_type, node, internal_compare>(roots, super_t::get_internal_cmp());
|
||||
top_element
|
||||
= detail::find_max_child< node_list_type, node, internal_compare >( roots, super_t::get_internal_cmp() );
|
||||
}
|
||||
|
||||
void cut(node_pointer n)
|
||||
void cut( node_pointer n )
|
||||
{
|
||||
node_pointer parent = n->get_parent();
|
||||
roots.splice(roots.begin(), parent->children, node_list_type::s_iterator_to(*n));
|
||||
roots.splice( roots.begin(), parent->children, node_list_type::s_iterator_to( *n ) );
|
||||
n->parent = 0;
|
||||
n->mark = false;
|
||||
n->mark = false;
|
||||
}
|
||||
|
||||
void cascading_cut(node_pointer n)
|
||||
void cascading_cut( node_pointer n )
|
||||
{
|
||||
node_pointer parent = n->get_parent();
|
||||
|
||||
if (parent) {
|
||||
if (!parent->mark)
|
||||
if ( parent ) {
|
||||
if ( !parent->mark )
|
||||
parent->mark = true;
|
||||
else {
|
||||
cut(n);
|
||||
cascading_cut(parent);
|
||||
cut( n );
|
||||
cascading_cut( parent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_children_to_root(node_pointer n)
|
||||
void add_children_to_root( node_pointer n )
|
||||
{
|
||||
for (node_list_iterator it = n->children.begin(); it != n->children.end(); ++it) {
|
||||
node_pointer child = static_cast<node_pointer>(&*it);
|
||||
child->parent = 0;
|
||||
for ( node_list_iterator it = n->children.begin(); it != n->children.end(); ++it ) {
|
||||
node_pointer child = static_cast< node_pointer >( &*it );
|
||||
child->parent = 0;
|
||||
}
|
||||
|
||||
roots.splice(roots.end(), n->children);
|
||||
roots.splice( roots.end(), n->children );
|
||||
}
|
||||
|
||||
void consolidate(void)
|
||||
void consolidate( void )
|
||||
{
|
||||
if (roots.empty())
|
||||
if ( roots.empty() )
|
||||
return;
|
||||
|
||||
static const size_type max_log2 = sizeof(size_type) * 8;
|
||||
boost::array<node_pointer, max_log2> aux;
|
||||
aux.assign(NULL);
|
||||
static const size_type max_log2 = sizeof( size_type ) * 8;
|
||||
boost::array< node_pointer, max_log2 > aux;
|
||||
aux.assign( NULL );
|
||||
|
||||
node_list_iterator it = roots.begin();
|
||||
top_element = static_cast<node_pointer>(&*it);
|
||||
top_element = static_cast< node_pointer >( &*it );
|
||||
|
||||
do {
|
||||
node_pointer n = static_cast<node_pointer>(&*it);
|
||||
node_pointer n = static_cast< node_pointer >( &*it );
|
||||
++it;
|
||||
size_type node_rank = n->child_count();
|
||||
|
||||
if (aux[node_rank] == NULL)
|
||||
aux[node_rank] = n;
|
||||
if ( aux[ node_rank ] == NULL )
|
||||
aux[ node_rank ] = n;
|
||||
else {
|
||||
do {
|
||||
node_pointer other = aux[node_rank];
|
||||
if (super_t::operator()(n->value, other->value))
|
||||
std::swap(n, other);
|
||||
node_pointer other = aux[ node_rank ];
|
||||
if ( super_t::operator()( n->value, other->value ) )
|
||||
std::swap( n, other );
|
||||
|
||||
if (other->parent)
|
||||
n->children.splice(n->children.end(), other->parent->children, node_list_type::s_iterator_to(*other));
|
||||
if ( other->parent )
|
||||
n->children.splice( n->children.end(),
|
||||
other->parent->children,
|
||||
node_list_type::s_iterator_to( *other ) );
|
||||
else
|
||||
n->children.splice(n->children.end(), roots, node_list_type::s_iterator_to(*other));
|
||||
n->children.splice( n->children.end(), roots, node_list_type::s_iterator_to( *other ) );
|
||||
|
||||
other->parent = n;
|
||||
|
||||
aux[node_rank] = NULL;
|
||||
node_rank = n->child_count();
|
||||
} while (aux[node_rank] != NULL);
|
||||
aux[node_rank] = n;
|
||||
aux[ node_rank ] = NULL;
|
||||
node_rank = n->child_count();
|
||||
} while ( aux[ node_rank ] != NULL );
|
||||
aux[ node_rank ] = n;
|
||||
}
|
||||
|
||||
if (!super_t::operator()(n->value, top_element->value))
|
||||
if ( !super_t::operator()( n->value, top_element->value ) )
|
||||
top_element = n;
|
||||
}
|
||||
while (it != roots.end());
|
||||
} while ( it != roots.end() );
|
||||
}
|
||||
|
||||
void finish_erase_or_pop(node_pointer erased_node)
|
||||
void finish_erase_or_pop( node_pointer erased_node )
|
||||
{
|
||||
add_children_to_root(erased_node);
|
||||
add_children_to_root( erased_node );
|
||||
|
||||
erased_node->~node();
|
||||
allocator_type& alloc = *this;
|
||||
alloc.deallocate(erased_node, 1);
|
||||
alloc.deallocate( erased_node, 1 );
|
||||
|
||||
size_holder::decrement();
|
||||
if (!empty())
|
||||
if ( !empty() )
|
||||
consolidate();
|
||||
else
|
||||
top_element = NULL;
|
||||
}
|
||||
|
||||
mutable node_pointer top_element;
|
||||
node_list_type roots;
|
||||
node_list_type roots;
|
||||
#endif
|
||||
};
|
||||
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}} // namespace boost::heap
|
||||
|
||||
#undef BOOST_HEAP_ASSERT
|
||||
|
||||
|
||||
@@ -11,37 +11,35 @@
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
|
||||
|
||||
template <class C>
|
||||
struct PriorityQueue:
|
||||
boost::ForwardContainer<C>
|
||||
template < class C >
|
||||
struct PriorityQueue : boost::ForwardContainer< C >
|
||||
{
|
||||
typedef typename C::iterator iterator;
|
||||
typedef typename C::const_iterator const_iterator;
|
||||
typedef typename C::allocator_type allocator_type;
|
||||
typedef typename C::value_compare value_compare;
|
||||
typedef typename C::value_type value_type;
|
||||
typedef typename C::iterator iterator;
|
||||
typedef typename C::const_iterator const_iterator;
|
||||
typedef typename C::allocator_type allocator_type;
|
||||
typedef typename C::value_compare value_compare;
|
||||
typedef typename C::value_type value_type;
|
||||
typedef typename C::const_reference const_reference;
|
||||
|
||||
|
||||
BOOST_CONCEPT_USAGE(PriorityQueue)
|
||||
BOOST_CONCEPT_USAGE( PriorityQueue )
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost::Assignable<value_type>));
|
||||
BOOST_CONCEPT_ASSERT((boost::Container<C>));
|
||||
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<C>));
|
||||
BOOST_CONCEPT_ASSERT((boost::Comparable<C>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::Assignable< value_type >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::Container< C >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::EqualityComparable< C >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::Comparable< C >));
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::Const_BinaryPredicate<value_compare, value_type, value_type>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::Const_BinaryPredicate< value_compare, value_type, value_type >));
|
||||
|
||||
c.swap(c2);
|
||||
c.swap( c2 );
|
||||
c.clear();
|
||||
a = c.get_allocator();
|
||||
|
||||
typename PriorityQueue::value_type v;
|
||||
c.push(v);
|
||||
c.push( v );
|
||||
|
||||
v = c.top();
|
||||
c.pop();
|
||||
@@ -50,61 +48,59 @@ struct PriorityQueue:
|
||||
|
||||
// verify tags
|
||||
has_ordered_iterators = C::has_ordered_iterators;
|
||||
is_mergable = C::is_mergable;
|
||||
is_stable = C::is_stable;
|
||||
is_mergable = C::is_mergable;
|
||||
is_stable = C::is_stable;
|
||||
}
|
||||
|
||||
private:
|
||||
C c, c2;
|
||||
allocator_type a;
|
||||
C c, c2;
|
||||
allocator_type a;
|
||||
typename C::value_type v;
|
||||
value_compare cmp;
|
||||
bool has_ordered_iterators, is_mergable, is_stable;
|
||||
value_compare cmp;
|
||||
bool has_ordered_iterators, is_mergable, is_stable;
|
||||
};
|
||||
|
||||
template <class C>
|
||||
struct MergablePriorityQueue:
|
||||
PriorityQueue<C>
|
||||
template < class C >
|
||||
struct MergablePriorityQueue : PriorityQueue< C >
|
||||
{
|
||||
BOOST_CONCEPT_USAGE(MergablePriorityQueue)
|
||||
BOOST_CONCEPT_USAGE( MergablePriorityQueue )
|
||||
{
|
||||
C c, c2;
|
||||
c.merge(c2);
|
||||
c.merge( c2 );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class C>
|
||||
struct MutablePriorityQueue:
|
||||
PriorityQueue<C>
|
||||
template < class C >
|
||||
struct MutablePriorityQueue : PriorityQueue< C >
|
||||
{
|
||||
typedef typename C::handle_type handle_type;
|
||||
|
||||
BOOST_CONCEPT_USAGE(MutablePriorityQueue)
|
||||
BOOST_CONCEPT_USAGE( MutablePriorityQueue )
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost::Assignable<typename MutablePriorityQueue::handle_type>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::Assignable< typename MutablePriorityQueue::handle_type >));
|
||||
|
||||
typename MutablePriorityQueue::value_type v;
|
||||
typename MutablePriorityQueue::handle_type h = c.push(v);
|
||||
typename MutablePriorityQueue::handle_type h2 = c.push(v);
|
||||
c.update(h, v);
|
||||
c.increase(h, v);
|
||||
c.decrease(h, v);
|
||||
typename MutablePriorityQueue::value_type v;
|
||||
typename MutablePriorityQueue::handle_type h = c.push( v );
|
||||
typename MutablePriorityQueue::handle_type h2 = c.push( v );
|
||||
c.update( h, v );
|
||||
c.increase( h, v );
|
||||
c.decrease( h, v );
|
||||
|
||||
c.update(h);
|
||||
c.increase(h);
|
||||
c.decrease(h);
|
||||
c.update( h );
|
||||
c.increase( h );
|
||||
c.decrease( h );
|
||||
|
||||
equal = (h == h2);
|
||||
not_equal = (h != h2);
|
||||
equal = ( h == h2 );
|
||||
not_equal = ( h != h2 );
|
||||
|
||||
h2 = h;
|
||||
}
|
||||
|
||||
C c;
|
||||
C c;
|
||||
bool equal, not_equal;
|
||||
};
|
||||
|
||||
}}
|
||||
}} // namespace boost::heap
|
||||
|
||||
#endif /* BOOST_HEAP_CONCEPTS_HPP */
|
||||
|
||||
@@ -17,83 +17,78 @@
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
namespace detail {
|
||||
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
struct heap_merge_emulate
|
||||
{
|
||||
struct dummy_reserver
|
||||
{
|
||||
static void reserve (Heap1 & lhs, std::size_t required_size)
|
||||
static void reserve( Heap1& lhs, std::size_t required_size )
|
||||
{}
|
||||
};
|
||||
|
||||
struct reserver
|
||||
{
|
||||
static void reserve (Heap1 & lhs, std::size_t required_size)
|
||||
static void reserve( Heap1& lhs, std::size_t required_size )
|
||||
{
|
||||
lhs.reserve(required_size);
|
||||
lhs.reserve( required_size );
|
||||
}
|
||||
};
|
||||
|
||||
typedef typename boost::conditional<Heap1::has_reserve,
|
||||
reserver,
|
||||
dummy_reserver>::type space_reserver;
|
||||
typedef typename boost::conditional< Heap1::has_reserve, reserver, dummy_reserver >::type space_reserver;
|
||||
|
||||
static void merge(Heap1 & lhs, Heap2 & rhs)
|
||||
static void merge( Heap1& lhs, Heap2& rhs )
|
||||
{
|
||||
if (Heap1::constant_time_size && Heap2::constant_time_size) {
|
||||
if (Heap1::has_reserve) {
|
||||
if ( Heap1::constant_time_size && Heap2::constant_time_size ) {
|
||||
if ( Heap1::has_reserve ) {
|
||||
std::size_t required_size = lhs.size() + rhs.size();
|
||||
space_reserver::reserve(lhs, required_size);
|
||||
space_reserver::reserve( lhs, required_size );
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: container adaptors could benefit from first appending all elements and then restoring the heap order
|
||||
// FIXME: optimize: if we have ordered iterators and we can efficiently insert keys with a below the lowest key in the heap
|
||||
// FIXME: optimize: if we have ordered iterators and we can efficiently insert keys with a below the lowest key
|
||||
// in the heap
|
||||
// d-ary, b and fibonacci heaps fall into this category
|
||||
|
||||
while (!rhs.empty()) {
|
||||
lhs.push(rhs.top());
|
||||
while ( !rhs.empty() ) {
|
||||
lhs.push( rhs.top() );
|
||||
rhs.pop();
|
||||
}
|
||||
|
||||
lhs.set_stability_count((std::max)(lhs.get_stability_count(),
|
||||
rhs.get_stability_count()));
|
||||
rhs.set_stability_count(0);
|
||||
lhs.set_stability_count( ( std::max )( lhs.get_stability_count(), rhs.get_stability_count() ) );
|
||||
rhs.set_stability_count( 0 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename Heap>
|
||||
template < typename Heap >
|
||||
struct heap_merge_same_mergable
|
||||
{
|
||||
static void merge(Heap & lhs, Heap & rhs)
|
||||
static void merge( Heap& lhs, Heap& rhs )
|
||||
{
|
||||
lhs.merge(rhs);
|
||||
lhs.merge( rhs );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Heap>
|
||||
template < typename Heap >
|
||||
struct heap_merge_same
|
||||
{
|
||||
static const bool is_mergable = Heap::is_mergable;
|
||||
typedef typename boost::conditional<is_mergable,
|
||||
heap_merge_same_mergable<Heap>,
|
||||
heap_merge_emulate<Heap, Heap>
|
||||
>::type heap_merger;
|
||||
typedef
|
||||
typename boost::conditional< is_mergable, heap_merge_same_mergable< Heap >, heap_merge_emulate< Heap, Heap > >::type
|
||||
heap_merger;
|
||||
|
||||
static void merge(Heap & lhs, Heap & rhs)
|
||||
static void merge( Heap& lhs, Heap& rhs )
|
||||
{
|
||||
heap_merger::merge(lhs, rhs);
|
||||
heap_merger::merge( lhs, rhs );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -105,29 +100,25 @@ struct heap_merge_same
|
||||
* \b Effect: lhs contains all elements that have been part of rhs, rhs is empty.
|
||||
*
|
||||
* */
|
||||
template <typename Heap1,
|
||||
typename Heap2
|
||||
>
|
||||
void heap_merge(Heap1 & lhs, Heap2 & rhs)
|
||||
template < typename Heap1, typename Heap2 >
|
||||
void heap_merge( Heap1& lhs, Heap2& rhs )
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap1>));
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<Heap2>));
|
||||
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));
|
||||
BOOST_STATIC_ASSERT( ( boost::is_same< typename Heap1::value_compare, typename Heap2::value_compare >::value ) );
|
||||
|
||||
const bool same_heaps = boost::is_same<Heap1, Heap2>::value;
|
||||
const bool same_heaps = boost::is_same< Heap1, Heap2 >::value;
|
||||
|
||||
typedef typename boost::conditional<same_heaps,
|
||||
detail::heap_merge_same<Heap1>,
|
||||
detail::heap_merge_emulate<Heap1, Heap2>
|
||||
>::type heap_merger;
|
||||
typedef typename boost::conditional< same_heaps,
|
||||
detail::heap_merge_same< Heap1 >,
|
||||
detail::heap_merge_emulate< Heap1, Heap2 > >::type heap_merger;
|
||||
|
||||
heap_merger::merge(lhs, rhs);
|
||||
heap_merger::merge( lhs, rhs );
|
||||
}
|
||||
|
||||
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}} // namespace boost::heap
|
||||
|
||||
#endif /* BOOST_HEAP_MERGE_HPP */
|
||||
|
||||
@@ -17,86 +17,82 @@
|
||||
|
||||
#include <boost/heap/detail/heap_comparison.hpp>
|
||||
#include <boost/heap/detail/heap_node.hpp>
|
||||
#include <boost/heap/policies.hpp>
|
||||
#include <boost/heap/detail/stable_heap.hpp>
|
||||
#include <boost/heap/detail/tree_iterator.hpp>
|
||||
#include <boost/heap/policies.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_DOXYGEN_INVOKED
|
||||
#ifdef BOOST_HEAP_SANITYCHECKS
|
||||
#define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
#else
|
||||
#define BOOST_HEAP_ASSERT(expression)
|
||||
#endif
|
||||
# ifdef BOOST_HEAP_SANITYCHECKS
|
||||
# define BOOST_HEAP_ASSERT BOOST_ASSERT
|
||||
# else
|
||||
# define BOOST_HEAP_ASSERT( expression )
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
namespace detail {
|
||||
|
||||
typedef parameter::parameters<boost::parameter::optional<tag::allocator>,
|
||||
boost::parameter::optional<tag::compare>,
|
||||
boost::parameter::optional<tag::stable>,
|
||||
boost::parameter::optional<tag::constant_time_size>,
|
||||
boost::parameter::optional<tag::stability_counter_type>
|
||||
> pairing_heap_signature;
|
||||
typedef parameter::parameters< boost::parameter::optional< tag::allocator >,
|
||||
boost::parameter::optional< tag::compare >,
|
||||
boost::parameter::optional< tag::stable >,
|
||||
boost::parameter::optional< tag::constant_time_size >,
|
||||
boost::parameter::optional< tag::stability_counter_type > >
|
||||
pairing_heap_signature;
|
||||
|
||||
template <typename T, typename Parspec>
|
||||
template < typename T, typename Parspec >
|
||||
struct make_pairing_heap_base
|
||||
{
|
||||
static const bool constant_time_size = parameter::binding<Parspec,
|
||||
tag::constant_time_size,
|
||||
boost::true_type
|
||||
>::type::value;
|
||||
typedef typename detail::make_heap_base<T, Parspec, constant_time_size>::type base_type;
|
||||
typedef typename detail::make_heap_base<T, Parspec, constant_time_size>::allocator_argument allocator_argument;
|
||||
typedef typename detail::make_heap_base<T, Parspec, constant_time_size>::compare_argument compare_argument;
|
||||
static const bool constant_time_size
|
||||
= parameter::binding< Parspec, tag::constant_time_size, boost::true_type >::type::value;
|
||||
typedef typename detail::make_heap_base< T, Parspec, constant_time_size >::type base_type;
|
||||
typedef typename detail::make_heap_base< T, Parspec, constant_time_size >::allocator_argument allocator_argument;
|
||||
typedef typename detail::make_heap_base< T, Parspec, constant_time_size >::compare_argument compare_argument;
|
||||
|
||||
typedef heap_node<typename base_type::internal_type, false> node_type;
|
||||
typedef heap_node< typename base_type::internal_type, false > node_type;
|
||||
|
||||
typedef typename boost::allocator_rebind<allocator_argument, node_type>::type allocator_type;
|
||||
typedef typename boost::allocator_rebind< allocator_argument, node_type >::type allocator_type;
|
||||
|
||||
struct type:
|
||||
base_type,
|
||||
allocator_type
|
||||
struct type : base_type, allocator_type
|
||||
{
|
||||
type(compare_argument const & arg):
|
||||
base_type(arg)
|
||||
type( compare_argument const& arg ) :
|
||||
base_type( arg )
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
type(type const & rhs):
|
||||
base_type(rhs), allocator_type(rhs)
|
||||
type( type const& rhs ) :
|
||||
base_type( rhs ),
|
||||
allocator_type( rhs )
|
||||
{}
|
||||
|
||||
type(type && rhs):
|
||||
base_type(std::move(static_cast<base_type&>(rhs))),
|
||||
allocator_type(std::move(static_cast<allocator_type&>(rhs)))
|
||||
type( type&& rhs ) :
|
||||
base_type( std::move( static_cast< base_type& >( rhs ) ) ),
|
||||
allocator_type( std::move( static_cast< allocator_type& >( rhs ) ) )
|
||||
{}
|
||||
|
||||
type & operator=(type && rhs)
|
||||
type& operator=( type&& rhs )
|
||||
{
|
||||
base_type::operator=(std::move(static_cast<base_type&>(rhs)));
|
||||
allocator_type::operator=(std::move(static_cast<allocator_type&>(rhs)));
|
||||
base_type::operator=( std::move( static_cast< base_type& >( rhs ) ) );
|
||||
allocator_type::operator=( std::move( static_cast< allocator_type& >( rhs ) ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
type & operator=(type const & rhs)
|
||||
type& operator=( type const& rhs )
|
||||
{
|
||||
base_type::operator=(static_cast<base_type const &>(rhs));
|
||||
allocator_type::operator=(static_cast<const allocator_type&>(rhs));
|
||||
base_type::operator=( static_cast< base_type const& >( rhs ) );
|
||||
allocator_type::operator=( static_cast< const allocator_type& >( rhs ) );
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* \class pairing_heap
|
||||
@@ -121,226 +117,224 @@ struct make_pairing_heap_base
|
||||
*
|
||||
*/
|
||||
#ifdef BOOST_DOXYGEN_INVOKED
|
||||
template<class T, class ...Options>
|
||||
template < class T, class... Options >
|
||||
#else
|
||||
template <typename T,
|
||||
class A0 = boost::parameter::void_,
|
||||
class A1 = boost::parameter::void_,
|
||||
class A2 = boost::parameter::void_,
|
||||
class A3 = boost::parameter::void_,
|
||||
class A4 = boost::parameter::void_
|
||||
>
|
||||
template < typename T,
|
||||
class A0 = boost::parameter::void_,
|
||||
class A1 = boost::parameter::void_,
|
||||
class A2 = boost::parameter::void_,
|
||||
class A3 = boost::parameter::void_,
|
||||
class A4 = boost::parameter::void_ >
|
||||
#endif
|
||||
class pairing_heap:
|
||||
private detail::make_pairing_heap_base<T,
|
||||
typename detail::pairing_heap_signature::bind<A0, A1, A2, A3, A4>::type
|
||||
>::type
|
||||
class pairing_heap :
|
||||
private detail::make_pairing_heap_base< T, typename detail::pairing_heap_signature::bind< A0, A1, A2, A3, A4 >::type >::type
|
||||
{
|
||||
typedef typename detail::pairing_heap_signature::bind<A0, A1, A2, A3, A4>::type bound_args;
|
||||
typedef detail::make_pairing_heap_base<T, bound_args> base_maker;
|
||||
typedef typename base_maker::type super_t;
|
||||
typedef typename detail::pairing_heap_signature::bind< A0, A1, A2, A3, A4 >::type bound_args;
|
||||
typedef detail::make_pairing_heap_base< T, bound_args > base_maker;
|
||||
typedef typename base_maker::type super_t;
|
||||
|
||||
typedef typename super_t::internal_type internal_type;
|
||||
typedef typename super_t::size_holder_type size_holder;
|
||||
typedef typename super_t::internal_type internal_type;
|
||||
typedef typename super_t::size_holder_type size_holder;
|
||||
typedef typename base_maker::allocator_argument allocator_argument;
|
||||
|
||||
private:
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
friend struct heap_merge_emulate;
|
||||
|
||||
#ifndef BOOST_DOXYGEN_INVOKED
|
||||
struct implementation_defined:
|
||||
detail::extract_allocator_types<typename base_maker::allocator_argument>
|
||||
struct implementation_defined : detail::extract_allocator_types< typename base_maker::allocator_argument >
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef typename detail::extract_allocator_types<typename base_maker::allocator_argument>::size_type size_type;
|
||||
typedef typename detail::extract_allocator_types<typename base_maker::allocator_argument>::reference reference;
|
||||
typedef typename detail::extract_allocator_types< typename base_maker::allocator_argument >::size_type size_type;
|
||||
typedef typename detail::extract_allocator_types< typename base_maker::allocator_argument >::reference reference;
|
||||
|
||||
typedef typename base_maker::compare_argument value_compare;
|
||||
typedef typename base_maker::allocator_type allocator_type;
|
||||
typedef typename base_maker::allocator_type allocator_type;
|
||||
|
||||
typedef typename boost::allocator_pointer<allocator_type>::type node_pointer;
|
||||
typedef typename boost::allocator_const_pointer<allocator_type>::type const_node_pointer;
|
||||
typedef typename boost::allocator_pointer< allocator_type >::type node_pointer;
|
||||
typedef typename boost::allocator_const_pointer< allocator_type >::type const_node_pointer;
|
||||
|
||||
typedef detail::heap_node_list node_list_type;
|
||||
typedef typename node_list_type::iterator node_list_iterator;
|
||||
typedef detail::heap_node_list node_list_type;
|
||||
typedef typename node_list_type::iterator node_list_iterator;
|
||||
typedef typename node_list_type::const_iterator node_list_const_iterator;
|
||||
|
||||
typedef typename base_maker::node_type node;
|
||||
|
||||
typedef detail::value_extractor<value_type, internal_type, super_t> value_extractor;
|
||||
typedef typename super_t::internal_compare internal_compare;
|
||||
typedef detail::node_handle<node_pointer, super_t, reference> handle_type;
|
||||
typedef detail::value_extractor< value_type, internal_type, super_t > value_extractor;
|
||||
typedef typename super_t::internal_compare internal_compare;
|
||||
typedef detail::node_handle< node_pointer, super_t, reference > handle_type;
|
||||
|
||||
typedef detail::tree_iterator<node,
|
||||
const value_type,
|
||||
allocator_type,
|
||||
value_extractor,
|
||||
detail::pointer_to_reference<node>,
|
||||
false,
|
||||
false,
|
||||
value_compare
|
||||
> iterator;
|
||||
typedef detail::tree_iterator< node,
|
||||
const value_type,
|
||||
allocator_type,
|
||||
value_extractor,
|
||||
detail::pointer_to_reference< node >,
|
||||
false,
|
||||
false,
|
||||
value_compare >
|
||||
iterator;
|
||||
|
||||
typedef iterator const_iterator;
|
||||
|
||||
typedef detail::tree_iterator<node,
|
||||
const value_type,
|
||||
allocator_type,
|
||||
value_extractor,
|
||||
detail::pointer_to_reference<node>,
|
||||
false,
|
||||
true,
|
||||
value_compare
|
||||
> ordered_iterator;
|
||||
typedef detail::tree_iterator< node,
|
||||
const value_type,
|
||||
allocator_type,
|
||||
value_extractor,
|
||||
detail::pointer_to_reference< node >,
|
||||
false,
|
||||
true,
|
||||
value_compare >
|
||||
ordered_iterator;
|
||||
};
|
||||
|
||||
typedef typename implementation_defined::node node;
|
||||
typedef typename implementation_defined::node_pointer node_pointer;
|
||||
typedef typename implementation_defined::node_list_type node_list_type;
|
||||
typedef typename implementation_defined::node_list_iterator node_list_iterator;
|
||||
typedef typename implementation_defined::node node;
|
||||
typedef typename implementation_defined::node_pointer node_pointer;
|
||||
typedef typename implementation_defined::node_list_type node_list_type;
|
||||
typedef typename implementation_defined::node_list_iterator node_list_iterator;
|
||||
typedef typename implementation_defined::node_list_const_iterator node_list_const_iterator;
|
||||
typedef typename implementation_defined::internal_compare internal_compare;
|
||||
typedef typename implementation_defined::internal_compare internal_compare;
|
||||
|
||||
typedef boost::intrusive::list<detail::heap_node_base<true>,
|
||||
boost::intrusive::constant_time_size<false>
|
||||
> node_child_list;
|
||||
typedef boost::intrusive::list< detail::heap_node_base< true >, boost::intrusive::constant_time_size< false > >
|
||||
node_child_list;
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::allocator_type allocator_type;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::allocator_type allocator_type;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
/// \copydoc boost::heap::priority_queue::iterator
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::ordered_iterator ordered_iterator;
|
||||
|
||||
typedef typename implementation_defined::handle_type handle_type;
|
||||
|
||||
static const bool constant_time_size = super_t::constant_time_size;
|
||||
static const bool constant_time_size = super_t::constant_time_size;
|
||||
static const bool has_ordered_iterators = true;
|
||||
static const bool is_mergable = true;
|
||||
static const bool is_stable = detail::extract_stable<bound_args>::value;
|
||||
static const bool has_reserve = false;
|
||||
static const bool is_mergable = true;
|
||||
static const bool is_stable = detail::extract_stable< bound_args >::value;
|
||||
static const bool has_reserve = false;
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::priority_queue(value_compare const &)
|
||||
explicit pairing_heap(value_compare const & cmp = value_compare()):
|
||||
super_t(cmp), root(NULL)
|
||||
explicit pairing_heap( value_compare const& cmp = value_compare() ) :
|
||||
super_t( cmp ),
|
||||
root( NULL )
|
||||
{}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::priority_queue(priority_queue const &)
|
||||
pairing_heap(pairing_heap const & rhs):
|
||||
super_t(rhs), root(NULL)
|
||||
pairing_heap( pairing_heap const& rhs ) :
|
||||
super_t( rhs ),
|
||||
root( NULL )
|
||||
{
|
||||
if (rhs.empty())
|
||||
if ( rhs.empty() )
|
||||
return;
|
||||
|
||||
clone_tree(rhs);
|
||||
size_holder::set_size(rhs.get_size());
|
||||
clone_tree( rhs );
|
||||
size_holder::set_size( rhs.get_size() );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
/// \copydoc boost::heap::priority_queue::priority_queue(priority_queue &&)
|
||||
pairing_heap(pairing_heap && rhs):
|
||||
super_t(std::move(rhs)), root(rhs.root)
|
||||
pairing_heap( pairing_heap&& rhs ) :
|
||||
super_t( std::move( rhs ) ),
|
||||
root( rhs.root )
|
||||
{
|
||||
rhs.root = NULL;
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator=(priority_queue &&)
|
||||
pairing_heap & operator=(pairing_heap && rhs)
|
||||
pairing_heap& operator=( pairing_heap&& rhs )
|
||||
{
|
||||
super_t::operator=(std::move(rhs));
|
||||
root = rhs.root;
|
||||
super_t::operator=( std::move( rhs ) );
|
||||
root = rhs.root;
|
||||
rhs.root = NULL;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator=(priority_queue const & rhs)
|
||||
pairing_heap & operator=(pairing_heap const & rhs)
|
||||
pairing_heap& operator=( pairing_heap const& rhs )
|
||||
{
|
||||
clear();
|
||||
size_holder::set_size(rhs.get_size());
|
||||
static_cast<super_t&>(*this) = rhs;
|
||||
size_holder::set_size( rhs.get_size() );
|
||||
static_cast< super_t& >( *this ) = rhs;
|
||||
|
||||
clone_tree(rhs);
|
||||
clone_tree( rhs );
|
||||
return *this;
|
||||
}
|
||||
|
||||
~pairing_heap(void)
|
||||
~pairing_heap( void )
|
||||
{
|
||||
while (!empty())
|
||||
while ( !empty() )
|
||||
pop();
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::empty
|
||||
bool empty(void) const
|
||||
bool empty( void ) const
|
||||
{
|
||||
return root == NULL;
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::binomial_heap::size
|
||||
size_type size(void) const
|
||||
size_type size( void ) const
|
||||
{
|
||||
if (constant_time_size)
|
||||
if ( constant_time_size )
|
||||
return size_holder::get_size();
|
||||
|
||||
if (root == NULL)
|
||||
if ( root == NULL )
|
||||
return 0;
|
||||
else
|
||||
return detail::count_nodes(root);
|
||||
return detail::count_nodes( root );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::max_size
|
||||
size_type max_size(void) const
|
||||
size_type max_size( void ) const
|
||||
{
|
||||
const allocator_type& alloc = *this;
|
||||
return boost::allocator_max_size(alloc);
|
||||
return boost::allocator_max_size( alloc );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::clear
|
||||
void clear(void)
|
||||
void clear( void )
|
||||
{
|
||||
if (empty())
|
||||
if ( empty() )
|
||||
return;
|
||||
|
||||
root->template clear_subtree<allocator_type>(*this);
|
||||
root->template clear_subtree< allocator_type >( *this );
|
||||
root->~node();
|
||||
allocator_type& alloc = *this;
|
||||
alloc.deallocate(root, 1);
|
||||
alloc.deallocate( root, 1 );
|
||||
root = NULL;
|
||||
size_holder::set_size(0);
|
||||
size_holder::set_size( 0 );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::get_allocator
|
||||
allocator_type get_allocator(void) const
|
||||
allocator_type get_allocator( void ) const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::swap
|
||||
void swap(pairing_heap & rhs)
|
||||
void swap( pairing_heap& rhs )
|
||||
{
|
||||
super_t::swap(rhs);
|
||||
std::swap(root, rhs.root);
|
||||
super_t::swap( rhs );
|
||||
std::swap( root, rhs.root );
|
||||
}
|
||||
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::top
|
||||
const_reference top(void) const
|
||||
const_reference top( void ) const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
BOOST_ASSERT( !empty() );
|
||||
|
||||
return super_t::get_value(root->value);
|
||||
return super_t::get_value( root->value );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -353,20 +347,21 @@ public:
|
||||
* \b Complexity: 2**2*log(log(N)) (amortized).
|
||||
*
|
||||
* */
|
||||
handle_type push(value_type const & v)
|
||||
handle_type push( value_type const& v )
|
||||
{
|
||||
size_holder::increment();
|
||||
|
||||
allocator_type& alloc = *this;
|
||||
node_pointer n = alloc.allocate(1);
|
||||
new(n) node(super_t::make_node(v));
|
||||
merge_node(n);
|
||||
return handle_type(n);
|
||||
node_pointer n = alloc.allocate( 1 );
|
||||
new ( n ) node( super_t::make_node( v ) );
|
||||
merge_node( n );
|
||||
return handle_type( n );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
/**
|
||||
* \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place. Returns handle to element.
|
||||
* \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place. Returns
|
||||
* handle to element.
|
||||
*
|
||||
* \cond
|
||||
* \b Complexity: \f$2^2log(log(N))\f$ (amortized).
|
||||
@@ -375,16 +370,16 @@ public:
|
||||
* \b Complexity: 2**2*log(log(N)) (amortized).
|
||||
*
|
||||
* */
|
||||
template <class... Args>
|
||||
handle_type emplace(Args&&... args)
|
||||
template < class... Args >
|
||||
handle_type emplace( Args&&... args )
|
||||
{
|
||||
size_holder::increment();
|
||||
|
||||
allocator_type& alloc = *this;
|
||||
node_pointer n = alloc.allocate(1);
|
||||
new(n) node(super_t::make_node(std::forward<Args>(args)...));
|
||||
merge_node(n);
|
||||
return handle_type(n);
|
||||
node_pointer n = alloc.allocate( 1 );
|
||||
new ( n ) node( super_t::make_node( std::forward< Args >( args )... ) );
|
||||
merge_node( n );
|
||||
return handle_type( n );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -394,11 +389,11 @@ public:
|
||||
* \b Complexity: Logarithmic (amortized).
|
||||
*
|
||||
* */
|
||||
void pop(void)
|
||||
void pop( void )
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
BOOST_ASSERT( !empty() );
|
||||
|
||||
erase(handle_type(root));
|
||||
erase( handle_type( root ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,10 +406,10 @@ public:
|
||||
* \b Complexity: 2**2*log(log(N)) (amortized).
|
||||
*
|
||||
* */
|
||||
void update (handle_type handle, const_reference v)
|
||||
void update( handle_type handle, const_reference v )
|
||||
{
|
||||
handle.node_->value = super_t::make_node(v);
|
||||
update(handle);
|
||||
handle.node_->value = super_t::make_node( v );
|
||||
update( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,19 +423,19 @@ public:
|
||||
*
|
||||
* \b Note: If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void update (handle_type handle)
|
||||
void update( handle_type handle )
|
||||
{
|
||||
node_pointer n = handle.node_;
|
||||
|
||||
n->unlink();
|
||||
if (!n->children.empty())
|
||||
n = merge_nodes(n, merge_node_list(n->children));
|
||||
if ( !n->children.empty() )
|
||||
n = merge_nodes( n, merge_node_list( n->children ) );
|
||||
|
||||
if (n != root)
|
||||
merge_node(n);
|
||||
if ( n != root )
|
||||
merge_node( n );
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* \b Effects: Assigns \c v to the element handled by \c handle & updates the priority queue.
|
||||
*
|
||||
* \cond
|
||||
@@ -451,9 +446,9 @@ public:
|
||||
*
|
||||
* \b Note: The new value is expected to be greater than the current one
|
||||
* */
|
||||
void increase (handle_type handle, const_reference v)
|
||||
void increase( handle_type handle, const_reference v )
|
||||
{
|
||||
update(handle, v);
|
||||
update( handle, v );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -467,9 +462,9 @@ public:
|
||||
*
|
||||
* \b Note: If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void increase (handle_type handle)
|
||||
void increase( handle_type handle )
|
||||
{
|
||||
update(handle);
|
||||
update( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -483,9 +478,9 @@ public:
|
||||
*
|
||||
* \b Note: The new value is expected to be less than the current one
|
||||
* */
|
||||
void decrease (handle_type handle, const_reference v)
|
||||
void decrease( handle_type handle, const_reference v )
|
||||
{
|
||||
update(handle, v);
|
||||
update( handle, v );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,11 +492,12 @@ public:
|
||||
*
|
||||
* \b Complexity: 2**2*log(log(N)) (amortized).
|
||||
*
|
||||
* \b Note: The new value is expected to be less than the current one. If this is not called, after a handle has been updated, the behavior of the data structure is undefined!
|
||||
* \b Note: The new value is expected to be less than the current one. If this is not called, after a handle has
|
||||
* been updated, the behavior of the data structure is undefined!
|
||||
* */
|
||||
void decrease (handle_type handle)
|
||||
void decrease( handle_type handle )
|
||||
{
|
||||
update(handle);
|
||||
update( handle );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -513,16 +509,16 @@ public:
|
||||
*
|
||||
* \b Complexity: 2**2*log(log(N)) (amortized).
|
||||
* */
|
||||
void erase(handle_type handle)
|
||||
void erase( handle_type handle )
|
||||
{
|
||||
node_pointer n = handle.node_;
|
||||
if (n != root) {
|
||||
if ( n != root ) {
|
||||
n->unlink();
|
||||
if (!n->children.empty())
|
||||
merge_node(merge_node_list(n->children));
|
||||
if ( !n->children.empty() )
|
||||
merge_node( merge_node_list( n->children ) );
|
||||
} else {
|
||||
if (!n->children.empty())
|
||||
root = merge_node_list(n->children);
|
||||
if ( !n->children.empty() )
|
||||
root = merge_node_list( n->children );
|
||||
else
|
||||
root = NULL;
|
||||
}
|
||||
@@ -530,39 +526,39 @@ public:
|
||||
size_holder::decrement();
|
||||
n->~node();
|
||||
allocator_type& alloc = *this;
|
||||
alloc.deallocate(n, 1);
|
||||
alloc.deallocate( n, 1 );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::begin
|
||||
iterator begin(void) const
|
||||
iterator begin( void ) const
|
||||
{
|
||||
return iterator(root, super_t::value_comp());
|
||||
return iterator( root, super_t::value_comp() );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::end
|
||||
iterator end(void) const
|
||||
iterator end( void ) const
|
||||
{
|
||||
return iterator(super_t::value_comp());
|
||||
return iterator( super_t::value_comp() );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::fibonacci_heap::ordered_begin
|
||||
ordered_iterator ordered_begin(void) const
|
||||
ordered_iterator ordered_begin( void ) const
|
||||
{
|
||||
return ordered_iterator(root, super_t::value_comp());
|
||||
return ordered_iterator( root, super_t::value_comp() );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::fibonacci_heap::ordered_begin
|
||||
ordered_iterator ordered_end(void) const
|
||||
ordered_iterator ordered_end( void ) const
|
||||
{
|
||||
return ordered_iterator(NULL, super_t::value_comp());
|
||||
return ordered_iterator( NULL, super_t::value_comp() );
|
||||
}
|
||||
|
||||
|
||||
/// \copydoc boost::heap::d_ary_heap_mutable::s_handle_from_iterator
|
||||
static handle_type s_handle_from_iterator(iterator const & it)
|
||||
static handle_type s_handle_from_iterator( iterator const& it )
|
||||
{
|
||||
node * ptr = const_cast<node *>(it.get_node());
|
||||
return handle_type(ptr);
|
||||
node* ptr = const_cast< node* >( it.get_node() );
|
||||
return handle_type( ptr );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -575,131 +571,130 @@ public:
|
||||
* \b Complexity: 2**2*log(log(N)) (amortized).
|
||||
*
|
||||
* */
|
||||
void merge(pairing_heap & rhs)
|
||||
void merge( pairing_heap& rhs )
|
||||
{
|
||||
if (rhs.empty())
|
||||
if ( rhs.empty() )
|
||||
return;
|
||||
|
||||
merge_node(rhs.root);
|
||||
merge_node( rhs.root );
|
||||
|
||||
size_holder::add(rhs.get_size());
|
||||
rhs.set_size(0);
|
||||
size_holder::add( rhs.get_size() );
|
||||
rhs.set_size( 0 );
|
||||
rhs.root = NULL;
|
||||
|
||||
super_t::set_stability_count((std::max)(super_t::get_stability_count(),
|
||||
rhs.get_stability_count()));
|
||||
rhs.set_stability_count(0);
|
||||
super_t::set_stability_count( ( std::max )( super_t::get_stability_count(), rhs.get_stability_count() ) );
|
||||
rhs.set_stability_count( 0 );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::value_comp
|
||||
value_compare const & value_comp(void) const
|
||||
value_compare const& value_comp( void ) const
|
||||
{
|
||||
return super_t::value_comp();
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator<(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator<(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator<( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_compare(*this, rhs);
|
||||
return detail::heap_compare( *this, rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator>(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator>(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator>( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_compare(rhs, *this);
|
||||
return detail::heap_compare( rhs, *this );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator>=(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator>=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator>=( HeapType const& rhs ) const
|
||||
{
|
||||
return !operator<(rhs);
|
||||
return !operator<( rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator<=(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator<=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator<=( HeapType const& rhs ) const
|
||||
{
|
||||
return !operator>(rhs);
|
||||
return !operator>( rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator==(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator==(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator==( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_equality(*this, rhs);
|
||||
return detail::heap_equality( *this, rhs );
|
||||
}
|
||||
|
||||
/// \copydoc boost::heap::priority_queue::operator!=(HeapType const & rhs) const
|
||||
template <typename HeapType>
|
||||
bool operator!=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator!=( HeapType const& rhs ) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
return !( *this == rhs );
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(BOOST_DOXYGEN_INVOKED)
|
||||
void clone_tree(pairing_heap const & rhs)
|
||||
#if !defined( BOOST_DOXYGEN_INVOKED )
|
||||
void clone_tree( pairing_heap const& rhs )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(root == NULL);
|
||||
if (rhs.empty())
|
||||
BOOST_HEAP_ASSERT( root == NULL );
|
||||
if ( rhs.empty() )
|
||||
return;
|
||||
|
||||
root = allocator_type::allocate(1);
|
||||
root = allocator_type::allocate( 1 );
|
||||
|
||||
new(root) node(static_cast<node const &>(*rhs.root), static_cast<allocator_type&>(*this));
|
||||
new ( root ) node( static_cast< node const& >( *rhs.root ), static_cast< allocator_type& >( *this ) );
|
||||
}
|
||||
|
||||
void merge_node(node_pointer other)
|
||||
void merge_node( node_pointer other )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(other);
|
||||
if (root != NULL)
|
||||
root = merge_nodes(root, other);
|
||||
BOOST_HEAP_ASSERT( other );
|
||||
if ( root != NULL )
|
||||
root = merge_nodes( root, other );
|
||||
else
|
||||
root = other;
|
||||
}
|
||||
|
||||
node_pointer merge_node_list(node_child_list & children)
|
||||
node_pointer merge_node_list( node_child_list& children )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(!children.empty());
|
||||
node_pointer merged = merge_first_pair(children);
|
||||
if (children.empty())
|
||||
BOOST_HEAP_ASSERT( !children.empty() );
|
||||
node_pointer merged = merge_first_pair( children );
|
||||
if ( children.empty() )
|
||||
return merged;
|
||||
|
||||
node_child_list node_list;
|
||||
node_list.push_back(*merged);
|
||||
node_list.push_back( *merged );
|
||||
|
||||
do {
|
||||
node_pointer next_merged = merge_first_pair(children);
|
||||
node_list.push_back(*next_merged);
|
||||
} while (!children.empty());
|
||||
node_pointer next_merged = merge_first_pair( children );
|
||||
node_list.push_back( *next_merged );
|
||||
} while ( !children.empty() );
|
||||
|
||||
return merge_node_list(node_list);
|
||||
return merge_node_list( node_list );
|
||||
}
|
||||
|
||||
node_pointer merge_first_pair(node_child_list & children)
|
||||
node_pointer merge_first_pair( node_child_list& children )
|
||||
{
|
||||
BOOST_HEAP_ASSERT(!children.empty());
|
||||
node_pointer first_child = static_cast<node_pointer>(&children.front());
|
||||
BOOST_HEAP_ASSERT( !children.empty() );
|
||||
node_pointer first_child = static_cast< node_pointer >( &children.front() );
|
||||
children.pop_front();
|
||||
if (children.empty())
|
||||
if ( children.empty() )
|
||||
return first_child;
|
||||
|
||||
node_pointer second_child = static_cast<node_pointer>(&children.front());
|
||||
node_pointer second_child = static_cast< node_pointer >( &children.front() );
|
||||
children.pop_front();
|
||||
|
||||
return merge_nodes(first_child, second_child);
|
||||
return merge_nodes( first_child, second_child );
|
||||
}
|
||||
|
||||
node_pointer merge_nodes(node_pointer node1, node_pointer node2)
|
||||
node_pointer merge_nodes( node_pointer node1, node_pointer node2 )
|
||||
{
|
||||
if (super_t::operator()(node1->value, node2->value))
|
||||
std::swap(node1, node2);
|
||||
if ( super_t::operator()( node1->value, node2->value ) )
|
||||
std::swap( node1, node2 );
|
||||
|
||||
node2->unlink();
|
||||
node1->children.push_front(*node2);
|
||||
node1->children.push_front( *node2 );
|
||||
return node1;
|
||||
}
|
||||
|
||||
@@ -708,8 +703,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}} // namespace boost::heap
|
||||
|
||||
#undef BOOST_HEAP_ASSERT
|
||||
#endif /* BOOST_HEAP_PAIRING_HEAP_HPP */
|
||||
|
||||
@@ -10,165 +10,177 @@
|
||||
#define BOOST_HEAP_POLICIES_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/parameter/template_keyword.hpp>
|
||||
#include <boost/parameter/aux_/void.hpp>
|
||||
#include <boost/parameter/binding.hpp>
|
||||
#include <boost/parameter/name.hpp>
|
||||
#include <boost/parameter/parameters.hpp>
|
||||
#include <boost/parameter/template_keyword.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_void.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
|
||||
#ifndef BOOST_DOXYGEN_INVOKED
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD(allocator)
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD(compare)
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD( allocator )
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD( compare )
|
||||
|
||||
namespace tag { struct stable; }
|
||||
namespace tag {
|
||||
struct stable;
|
||||
} // namespace tag
|
||||
|
||||
template <bool T>
|
||||
struct stable:
|
||||
boost::parameter::template_keyword<tag::stable, boost::integral_constant<bool, T> >
|
||||
template < bool T >
|
||||
struct stable : boost::parameter::template_keyword< tag::stable, boost::integral_constant< bool, T > >
|
||||
{};
|
||||
|
||||
namespace tag { struct mutable_; }
|
||||
namespace tag {
|
||||
struct mutable_;
|
||||
} // namespace tag
|
||||
|
||||
template <bool T>
|
||||
struct mutable_:
|
||||
boost::parameter::template_keyword<tag::mutable_, boost::integral_constant<bool, T> >
|
||||
template < bool T >
|
||||
struct mutable_ : boost::parameter::template_keyword< tag::mutable_, boost::integral_constant< bool, T > >
|
||||
{};
|
||||
|
||||
|
||||
namespace tag { struct constant_time_size; }
|
||||
namespace tag {
|
||||
struct constant_time_size;
|
||||
} // namespace tag
|
||||
|
||||
template <bool T>
|
||||
struct constant_time_size:
|
||||
boost::parameter::template_keyword<tag::constant_time_size, boost::integral_constant<bool, T> >
|
||||
template < bool T >
|
||||
struct constant_time_size :
|
||||
boost::parameter::template_keyword< tag::constant_time_size, boost::integral_constant< bool, T > >
|
||||
{};
|
||||
|
||||
namespace tag { struct store_parent_pointer; }
|
||||
namespace tag {
|
||||
struct store_parent_pointer;
|
||||
} // namespace tag
|
||||
|
||||
template <bool T>
|
||||
struct store_parent_pointer:
|
||||
boost::parameter::template_keyword<tag::store_parent_pointer, boost::integral_constant<bool, T> >
|
||||
template < bool T >
|
||||
struct store_parent_pointer :
|
||||
boost::parameter::template_keyword< tag::store_parent_pointer, boost::integral_constant< bool, T > >
|
||||
{};
|
||||
|
||||
namespace tag { struct arity; }
|
||||
namespace tag {
|
||||
struct arity;
|
||||
} // namespace tag
|
||||
|
||||
template <unsigned int T>
|
||||
struct arity:
|
||||
boost::parameter::template_keyword<tag::arity, boost::integral_constant<int, T> >
|
||||
template < unsigned int T >
|
||||
struct arity : boost::parameter::template_keyword< tag::arity, boost::integral_constant< int, T > >
|
||||
{};
|
||||
|
||||
namespace tag { struct objects_per_page; }
|
||||
namespace tag {
|
||||
struct objects_per_page;
|
||||
} // namespace tag
|
||||
|
||||
template <unsigned int T>
|
||||
struct objects_per_page:
|
||||
boost::parameter::template_keyword<tag::objects_per_page, boost::integral_constant<int, T> >
|
||||
template < unsigned int T >
|
||||
struct objects_per_page : boost::parameter::template_keyword< tag::objects_per_page, boost::integral_constant< int, T > >
|
||||
{};
|
||||
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD(stability_counter_type)
|
||||
BOOST_PARAMETER_TEMPLATE_KEYWORD( stability_counter_type )
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename bound_args, typename tag_type>
|
||||
template < typename bound_args, typename tag_type >
|
||||
struct has_arg
|
||||
{
|
||||
typedef typename boost::parameter::binding<bound_args, tag_type, void>::type type;
|
||||
static const bool value = !boost::is_void<type>::value;
|
||||
typedef typename boost::parameter::binding< bound_args, tag_type, void >::type type;
|
||||
static const bool value = !boost::is_void< type >::value;
|
||||
};
|
||||
|
||||
template <typename bound_args>
|
||||
template < typename bound_args >
|
||||
struct extract_stable
|
||||
{
|
||||
static const bool has_stable = has_arg<bound_args, tag::stable>::value;
|
||||
static const bool has_stable = has_arg< bound_args, tag::stable >::value;
|
||||
|
||||
typedef typename boost::conditional<has_stable,
|
||||
typename has_arg<bound_args, tag::stable>::type,
|
||||
boost::false_type
|
||||
>::type stable_t;
|
||||
typedef
|
||||
typename boost::conditional< has_stable, typename has_arg< bound_args, tag::stable >::type, boost::false_type >::type
|
||||
stable_t;
|
||||
|
||||
static const bool value = stable_t::value;
|
||||
};
|
||||
|
||||
template <typename bound_args>
|
||||
template < typename bound_args >
|
||||
struct extract_mutable
|
||||
{
|
||||
static const bool has_mutable = has_arg<bound_args, tag::mutable_>::value;
|
||||
static const bool has_mutable = has_arg< bound_args, tag::mutable_ >::value;
|
||||
|
||||
typedef typename boost::conditional<has_mutable,
|
||||
typename has_arg<bound_args, tag::mutable_>::type,
|
||||
boost::false_type
|
||||
>::type mutable_t;
|
||||
typedef typename boost::conditional< has_mutable,
|
||||
typename has_arg< bound_args, tag::mutable_ >::type,
|
||||
boost::false_type >::type mutable_t;
|
||||
|
||||
static const bool value = mutable_t::value;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
#else
|
||||
|
||||
/** \brief Specifies the predicate for the heap order
|
||||
*/
|
||||
template <typename T>
|
||||
struct compare{};
|
||||
template < typename T >
|
||||
struct compare
|
||||
{};
|
||||
|
||||
/** \brief Configure heap as mutable
|
||||
*
|
||||
* Certain heaps need to be configured specifically do be mutable.
|
||||
*
|
||||
* */
|
||||
template <bool T>
|
||||
struct mutable_{};
|
||||
template < bool T >
|
||||
struct mutable_
|
||||
{};
|
||||
|
||||
/** \brief Specifies allocator for the internal memory management
|
||||
*/
|
||||
template <typename T>
|
||||
struct allocator{};
|
||||
template < typename T >
|
||||
struct allocator
|
||||
{};
|
||||
|
||||
/** \brief Configure a heap as \b stable
|
||||
*
|
||||
* A priority queue is stable, if elements with the same priority are popped from the heap, in the same order as
|
||||
* they are inserted.
|
||||
* */
|
||||
template <bool T>
|
||||
struct stable{};
|
||||
template < bool T >
|
||||
struct stable
|
||||
{};
|
||||
|
||||
/** \brief Specifies the type for stability counter
|
||||
*
|
||||
* */
|
||||
template <typename IntType>
|
||||
struct stability_counter_type{};
|
||||
template < typename IntType >
|
||||
struct stability_counter_type
|
||||
{};
|
||||
|
||||
/** \brief Configures complexity of <tt> size() </tt>
|
||||
*
|
||||
* Specifies, whether size() should have linear or constant complexity.
|
||||
* */
|
||||
template <bool T>
|
||||
struct constant_time_size{};
|
||||
template < bool T >
|
||||
struct constant_time_size
|
||||
{};
|
||||
|
||||
/** \brief Store parent pointer in heap node.
|
||||
*
|
||||
* Maintaining a parent pointer adds some maintenance and size overhead, but iterating a heap is more efficient.
|
||||
* */
|
||||
template <bool T>
|
||||
struct store_parent_pointer{};
|
||||
template < bool T >
|
||||
struct store_parent_pointer
|
||||
{};
|
||||
|
||||
/** \brief Specify arity.
|
||||
*
|
||||
* Specifies the arity of a D-ary heap
|
||||
* */
|
||||
template <unsigned int T>
|
||||
struct arity{};
|
||||
template < unsigned int T >
|
||||
struct arity
|
||||
{};
|
||||
#endif
|
||||
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}} // namespace boost::heap
|
||||
|
||||
#endif /* BOOST_HEAP_POLICIES_HPP */
|
||||
|
||||
@@ -20,20 +20,19 @@
|
||||
#include <boost/heap/detail/stable_heap.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace heap {
|
||||
namespace boost { namespace heap {
|
||||
namespace detail {
|
||||
|
||||
typedef parameter::parameters<boost::parameter::optional<tag::allocator>,
|
||||
boost::parameter::optional<tag::compare>,
|
||||
boost::parameter::optional<tag::stable>,
|
||||
boost::parameter::optional<tag::stability_counter_type>
|
||||
> priority_queue_signature;
|
||||
}
|
||||
typedef parameter::parameters< boost::parameter::optional< tag::allocator >,
|
||||
boost::parameter::optional< tag::compare >,
|
||||
boost::parameter::optional< tag::stable >,
|
||||
boost::parameter::optional< tag::stability_counter_type > >
|
||||
priority_queue_signature;
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* \class priority_queue
|
||||
@@ -51,62 +50,62 @@ typedef parameter::parameters<boost::parameter::optional<tag::allocator>,
|
||||
*
|
||||
*/
|
||||
#ifdef BOOST_DOXYGEN_INVOKED
|
||||
template<class T, class ...Options>
|
||||
template < class T, class... Options >
|
||||
#else
|
||||
template <typename T,
|
||||
class A0 = boost::parameter::void_,
|
||||
class A1 = boost::parameter::void_,
|
||||
class A2 = boost::parameter::void_,
|
||||
class A3 = boost::parameter::void_
|
||||
>
|
||||
template < typename T,
|
||||
class A0 = boost::parameter::void_,
|
||||
class A1 = boost::parameter::void_,
|
||||
class A2 = boost::parameter::void_,
|
||||
class A3 = boost::parameter::void_ >
|
||||
#endif
|
||||
class priority_queue:
|
||||
private detail::make_heap_base<T, typename detail::priority_queue_signature::bind<A0, A1, A2, A3>::type, false>::type
|
||||
class priority_queue :
|
||||
private detail::make_heap_base< T, typename detail::priority_queue_signature::bind< A0, A1, A2, A3 >::type, false >::type
|
||||
{
|
||||
typedef detail::make_heap_base<T, typename detail::priority_queue_signature::bind<A0, A1, A2, A3>::type, false> heap_base_maker;
|
||||
typedef detail::make_heap_base< T, typename detail::priority_queue_signature::bind< A0, A1, A2, A3 >::type, false >
|
||||
heap_base_maker;
|
||||
|
||||
typedef typename heap_base_maker::type super_t;
|
||||
typedef typename heap_base_maker::type super_t;
|
||||
typedef typename super_t::internal_type internal_type;
|
||||
typedef typename boost::allocator_rebind<typename heap_base_maker::allocator_argument, internal_type>::type internal_type_allocator;
|
||||
typedef std::vector<internal_type, internal_type_allocator> container_type;
|
||||
typedef typename boost::allocator_rebind< typename heap_base_maker::allocator_argument, internal_type >::type
|
||||
internal_type_allocator;
|
||||
typedef std::vector< internal_type, internal_type_allocator > container_type;
|
||||
|
||||
template <typename Heap1, typename Heap2>
|
||||
template < typename Heap1, typename Heap2 >
|
||||
friend struct detail::heap_merge_emulate;
|
||||
|
||||
container_type q_;
|
||||
|
||||
#ifndef BOOST_DOXYGEN_INVOKED
|
||||
struct implementation_defined:
|
||||
detail::extract_allocator_types<typename heap_base_maker::allocator_argument>
|
||||
struct implementation_defined : detail::extract_allocator_types< typename heap_base_maker::allocator_argument >
|
||||
{
|
||||
typedef typename heap_base_maker::compare_argument value_compare;
|
||||
typedef detail::stable_heap_iterator<T, typename container_type::const_iterator, super_t> iterator;
|
||||
typedef iterator const_iterator;
|
||||
typedef typename container_type::allocator_type allocator_type;
|
||||
typedef typename heap_base_maker::compare_argument value_compare;
|
||||
typedef detail::stable_heap_iterator< T, typename container_type::const_iterator, super_t > iterator;
|
||||
typedef iterator const_iterator;
|
||||
typedef typename container_type::allocator_type allocator_type;
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef T value_type;
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::allocator_type allocator_type;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::allocator_type allocator_type;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
/**
|
||||
* \b Note: The iterator does not traverse the priority queue in order of the priorities.
|
||||
* */
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
|
||||
static const bool constant_time_size = true;
|
||||
static const bool constant_time_size = true;
|
||||
static const bool has_ordered_iterators = false;
|
||||
static const bool is_mergable = false;
|
||||
static const bool is_stable = heap_base_maker::is_stable;
|
||||
static const bool has_reserve = true;
|
||||
static const bool is_mergable = false;
|
||||
static const bool is_stable = heap_base_maker::is_stable;
|
||||
static const bool has_reserve = true;
|
||||
|
||||
/**
|
||||
* \b Effects: constructs an empty priority queue.
|
||||
@@ -114,8 +113,8 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
explicit priority_queue(value_compare const & cmp = value_compare()):
|
||||
super_t(cmp)
|
||||
explicit priority_queue( value_compare const& cmp = value_compare() ) :
|
||||
super_t( cmp )
|
||||
{}
|
||||
|
||||
/**
|
||||
@@ -124,8 +123,9 @@ public:
|
||||
* \b Complexity: Linear.
|
||||
*
|
||||
* */
|
||||
priority_queue (priority_queue const & rhs):
|
||||
super_t(rhs), q_(rhs.q_)
|
||||
priority_queue( priority_queue const& rhs ) :
|
||||
super_t( rhs ),
|
||||
q_( rhs.q_ )
|
||||
{}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
@@ -136,8 +136,9 @@ public:
|
||||
*
|
||||
* \b Note: Only available, if BOOST_NO_CXX11_RVALUE_REFERENCES is not defined
|
||||
* */
|
||||
priority_queue(priority_queue && rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible<super_t>::value):
|
||||
super_t(std::move(rhs)), q_(std::move(rhs.q_))
|
||||
priority_queue( priority_queue&& rhs ) BOOST_NOEXCEPT_IF( boost::is_nothrow_move_constructible< super_t >::value ) :
|
||||
super_t( std::move( rhs ) ),
|
||||
q_( std::move( rhs.q_ ) )
|
||||
{}
|
||||
|
||||
/**
|
||||
@@ -147,10 +148,11 @@ public:
|
||||
*
|
||||
* \b Note: Only available, if BOOST_NO_CXX11_RVALUE_REFERENCES is not defined
|
||||
* */
|
||||
priority_queue & operator=(priority_queue && rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_assignable<super_t>::value)
|
||||
priority_queue& operator=( priority_queue&& rhs )
|
||||
BOOST_NOEXCEPT_IF( boost::is_nothrow_move_assignable< super_t >::value )
|
||||
{
|
||||
super_t::operator=(std::move(rhs));
|
||||
q_ = std::move(rhs.q_);
|
||||
super_t::operator=( std::move( rhs ) );
|
||||
q_ = std::move( rhs.q_ );
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@@ -161,10 +163,10 @@ public:
|
||||
* \b Complexity: Linear.
|
||||
*
|
||||
* */
|
||||
priority_queue & operator=(priority_queue const & rhs)
|
||||
priority_queue& operator=( priority_queue const& rhs )
|
||||
{
|
||||
static_cast<super_t&>(*this) = static_cast<super_t const &>(rhs);
|
||||
q_ = rhs.q_;
|
||||
static_cast< super_t& >( *this ) = static_cast< super_t const& >( rhs );
|
||||
q_ = rhs.q_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -174,7 +176,7 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
bool empty(void) const BOOST_NOEXCEPT
|
||||
bool empty( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return q_.empty();
|
||||
}
|
||||
@@ -185,7 +187,7 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
size_type size(void) const BOOST_NOEXCEPT
|
||||
size_type size( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return q_.size();
|
||||
}
|
||||
@@ -196,7 +198,7 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
size_type max_size(void) const BOOST_NOEXCEPT
|
||||
size_type max_size( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return q_.max_size();
|
||||
}
|
||||
@@ -207,7 +209,7 @@ public:
|
||||
* \b Complexity: Linear.
|
||||
*
|
||||
* */
|
||||
void clear(void) BOOST_NOEXCEPT
|
||||
void clear( void ) BOOST_NOEXCEPT
|
||||
{
|
||||
q_.clear();
|
||||
}
|
||||
@@ -218,7 +220,7 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
allocator_type get_allocator(void) const
|
||||
allocator_type get_allocator( void ) const
|
||||
{
|
||||
return q_.get_allocator();
|
||||
}
|
||||
@@ -229,10 +231,10 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
const_reference top(void) const
|
||||
const_reference top( void ) const
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
return super_t::get_value(q_.front());
|
||||
BOOST_ASSERT( !empty() );
|
||||
return super_t::get_value( q_.front() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,24 +243,24 @@ public:
|
||||
* \b Complexity: Logarithmic (amortized). Linear (worst case).
|
||||
*
|
||||
* */
|
||||
void push(value_type const & v)
|
||||
void push( value_type const& v )
|
||||
{
|
||||
q_.push_back(super_t::make_node(v));
|
||||
std::push_heap(q_.begin(), q_.end(), static_cast<super_t const &>(*this));
|
||||
q_.push_back( super_t::make_node( v ) );
|
||||
std::push_heap( q_.begin(), q_.end(), static_cast< super_t const& >( *this ) );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
/**
|
||||
* \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place.
|
||||
*
|
||||
* \b Complexity: Logarithmic (amortized). Linear (worst case).
|
||||
*
|
||||
* */
|
||||
template <class... Args>
|
||||
void emplace(Args&&... args)
|
||||
template < class... Args >
|
||||
void emplace( Args&&... args )
|
||||
{
|
||||
q_.emplace_back(super_t::make_node(std::forward<Args>(args)...));
|
||||
std::push_heap(q_.begin(), q_.end(), static_cast<super_t const &>(*this));
|
||||
q_.emplace_back( super_t::make_node( std::forward< Args >( args )... ) );
|
||||
std::push_heap( q_.begin(), q_.end(), static_cast< super_t const& >( *this ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -268,10 +270,10 @@ public:
|
||||
* \b Complexity: Logarithmic (amortized). Linear (worst case).
|
||||
*
|
||||
* */
|
||||
void pop(void)
|
||||
void pop( void )
|
||||
{
|
||||
BOOST_ASSERT(!empty());
|
||||
std::pop_heap(q_.begin(), q_.end(), static_cast<super_t const &>(*this));
|
||||
BOOST_ASSERT( !empty() );
|
||||
std::pop_heap( q_.begin(), q_.end(), static_cast< super_t const& >( *this ) );
|
||||
q_.pop_back();
|
||||
}
|
||||
|
||||
@@ -281,10 +283,11 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
void swap(priority_queue & rhs) BOOST_NOEXCEPT_IF(boost::is_nothrow_move_constructible<super_t>::value && boost::is_nothrow_move_assignable<super_t>::value)
|
||||
void swap( priority_queue& rhs ) BOOST_NOEXCEPT_IF(
|
||||
boost::is_nothrow_move_constructible< super_t >::value&& boost::is_nothrow_move_assignable< super_t >::value )
|
||||
{
|
||||
super_t::swap(rhs);
|
||||
q_.swap(rhs.q_);
|
||||
super_t::swap( rhs );
|
||||
q_.swap( rhs.q_ );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,9 +296,9 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
iterator begin(void) const BOOST_NOEXCEPT
|
||||
iterator begin( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return iterator(q_.begin());
|
||||
return iterator( q_.begin() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -304,9 +307,9 @@ public:
|
||||
* \b Complexity: Constant.
|
||||
*
|
||||
* */
|
||||
iterator end(void) const BOOST_NOEXCEPT
|
||||
iterator end( void ) const BOOST_NOEXCEPT
|
||||
{
|
||||
return iterator(q_.end());
|
||||
return iterator( q_.end() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,16 +320,16 @@ public:
|
||||
* \b Node: Invalidates iterators
|
||||
*
|
||||
* */
|
||||
void reserve(size_type element_count)
|
||||
void reserve( size_type element_count )
|
||||
{
|
||||
q_.reserve(element_count);
|
||||
q_.reserve( element_count );
|
||||
}
|
||||
|
||||
/**
|
||||
* \b Effect: Returns the value_compare object used by the priority queue
|
||||
*
|
||||
* */
|
||||
value_compare const & value_comp(void) const
|
||||
value_compare const& value_comp( void ) const
|
||||
{
|
||||
return super_t::value_comp();
|
||||
}
|
||||
@@ -337,10 +340,10 @@ public:
|
||||
* \b Requirement: the \c value_compare object of both heaps must match.
|
||||
*
|
||||
* */
|
||||
template <typename HeapType>
|
||||
bool operator<(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator<( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_compare(*this, rhs);
|
||||
return detail::heap_compare( *this, rhs );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,10 +352,10 @@ public:
|
||||
* \b Requirement: the \c value_compare object of both heaps must match.
|
||||
*
|
||||
* */
|
||||
template <typename HeapType>
|
||||
bool operator>(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator>( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_compare(rhs, *this);
|
||||
return detail::heap_compare( rhs, *this );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,10 +364,10 @@ public:
|
||||
* \b Requirement: the \c value_compare object of both heaps must match.
|
||||
*
|
||||
* */
|
||||
template <typename HeapType>
|
||||
bool operator>=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator>=( HeapType const& rhs ) const
|
||||
{
|
||||
return !operator<(rhs);
|
||||
return !operator<( rhs );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,10 +376,10 @@ public:
|
||||
* \b Requirement: the \c value_compare object of both heaps must match.
|
||||
*
|
||||
* */
|
||||
template <typename HeapType>
|
||||
bool operator<=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator<=( HeapType const& rhs ) const
|
||||
{
|
||||
return !operator>(rhs);
|
||||
return !operator>( rhs );
|
||||
}
|
||||
|
||||
/** \brief Equivalent comparison
|
||||
@@ -385,10 +388,10 @@ public:
|
||||
* \b Requirement: the \c value_compare object of both heaps must match.
|
||||
*
|
||||
* */
|
||||
template <typename HeapType>
|
||||
bool operator==(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator==( HeapType const& rhs ) const
|
||||
{
|
||||
return detail::heap_equality(*this, rhs);
|
||||
return detail::heap_equality( *this, rhs );
|
||||
}
|
||||
|
||||
/** \brief Equivalent comparison
|
||||
@@ -397,14 +400,13 @@ public:
|
||||
* \b Requirement: the \c value_compare object of both heaps must match.
|
||||
*
|
||||
* */
|
||||
template <typename HeapType>
|
||||
bool operator!=(HeapType const & rhs) const
|
||||
template < typename HeapType >
|
||||
bool operator!=( HeapType const& rhs ) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
return !( *this == rhs );
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace heap */
|
||||
} /* namespace boost */
|
||||
}} // namespace boost::heap
|
||||
|
||||
#endif /* BOOST_HEAP_PRIORITY_QUEUE_HPP */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@
|
||||
Automatic redirection failed, please go to
|
||||
<a href="../../doc/html/heap.html">../../doc/html/heap.html</a> <hr>
|
||||
<p>© Copyright Beman Dawes, 2001</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
||||
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -12,59 +12,63 @@
|
||||
#include <boost/heap/binomial_heap.hpp>
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "merge_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
|
||||
template <bool stable, bool constant_time_size>
|
||||
void run_binomial_heap_test(void)
|
||||
template < bool stable, bool constant_time_size >
|
||||
void run_binomial_heap_test( void )
|
||||
{
|
||||
typedef boost::heap::binomial_heap<int, boost::heap::stable<stable>,
|
||||
boost::heap::compare<std::less<int> >,
|
||||
boost::heap::allocator<std::allocator<int> >,
|
||||
boost::heap::constant_time_size<constant_time_size> > pri_queue;
|
||||
typedef boost::heap::binomial_heap< int,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::compare< std::less< int > >,
|
||||
boost::heap::allocator< std::allocator< int > >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MutablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MergablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MutablePriorityQueue< pri_queue >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MergablePriorityQueue< pri_queue >));
|
||||
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
|
||||
run_merge_tests<pri_queue>();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
run_mutable_heap_tests<pri_queue >();
|
||||
run_ordered_iterator_tests<pri_queue>();
|
||||
run_mutable_heap_tests< pri_queue >();
|
||||
run_ordered_iterator_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::binomial_heap<q_tester, boost::heap::stable<stable>,
|
||||
boost::heap::constant_time_size<constant_time_size> > stable_pri_queue;
|
||||
if ( stable ) {
|
||||
typedef boost::heap::binomial_heap< q_tester,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
stable_pri_queue;
|
||||
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( binomial_heap_test )
|
||||
{
|
||||
run_binomial_heap_test<false, false>();
|
||||
run_binomial_heap_test<false, true>();
|
||||
run_binomial_heap_test<true, false>();
|
||||
run_binomial_heap_test<true, true>();
|
||||
run_binomial_heap_test< false, false >();
|
||||
run_binomial_heap_test< false, true >();
|
||||
run_binomial_heap_test< true, false >();
|
||||
run_binomial_heap_test< true, true >();
|
||||
|
||||
RUN_EMPLACE_TEST(binomial_heap);
|
||||
RUN_EMPLACE_TEST( binomial_heap );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( binomial_heap_compare_lookup_test )
|
||||
{
|
||||
typedef boost::heap::binomial_heap<int,
|
||||
boost::heap::compare<less_with_T>,
|
||||
boost::heap::allocator<std::allocator<int> > > pri_queue;
|
||||
run_common_heap_tests<pri_queue>();
|
||||
typedef boost::heap::
|
||||
binomial_heap< int, boost::heap::compare< less_with_T >, boost::heap::allocator< std::allocator< int > > >
|
||||
pri_queue;
|
||||
run_common_heap_tests< pri_queue >();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( binomial_heap_leak_test )
|
||||
{
|
||||
typedef boost::heap::binomial_heap<boost::shared_ptr<int> > pri_queue;
|
||||
run_leak_check_test<pri_queue>();
|
||||
typedef boost::heap::binomial_heap< boost::shared_ptr< int > > pri_queue;
|
||||
run_leak_check_test< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -19,501 +19,492 @@
|
||||
#include <boost/heap/heap_concepts.hpp>
|
||||
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
# include <cstdlib>
|
||||
# include <iterator>
|
||||
|
||||
template<class RandomIt>
|
||||
void random_shuffle(RandomIt first, RandomIt last)
|
||||
template < class RandomIt >
|
||||
void random_shuffle( RandomIt first, RandomIt last )
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomIt>::difference_type difference_type;
|
||||
difference_type n = last - first;
|
||||
for (difference_type i = n-1; i > 0; --i) {
|
||||
difference_type j = std::rand() % (i + 1);
|
||||
if (j != i) {
|
||||
using std::swap;
|
||||
swap(first[i], first[j]);
|
||||
typedef typename std::iterator_traits< RandomIt >::difference_type difference_type;
|
||||
difference_type n = last - first;
|
||||
for ( difference_type i = n - 1; i > 0; --i ) {
|
||||
difference_type j = std::rand() % ( i + 1 );
|
||||
if ( j != i ) {
|
||||
using std::swap;
|
||||
swap( first[ i ], first[ j ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
using std::random_shuffle;
|
||||
|
||||
#endif
|
||||
|
||||
typedef boost::default_constructible_archetype<
|
||||
boost::less_than_comparable_archetype<
|
||||
boost::copy_constructible_archetype<
|
||||
boost::assignable_archetype<
|
||||
> > > > test_value_type;
|
||||
boost::less_than_comparable_archetype< boost::copy_constructible_archetype< boost::assignable_archetype<> > > >
|
||||
test_value_type;
|
||||
|
||||
|
||||
typedef std::vector<int> test_data;
|
||||
const int test_size = 32;
|
||||
typedef std::vector< int > test_data;
|
||||
const int test_size = 32;
|
||||
|
||||
struct dummy_run
|
||||
{
|
||||
static void run(void)
|
||||
static void run( void )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
test_data make_test_data(int size, int offset = 0, int strive = 1)
|
||||
test_data make_test_data( int size, int offset = 0, int strive = 1 )
|
||||
{
|
||||
test_data ret;
|
||||
|
||||
for (int i = 0; i != size; ++i)
|
||||
ret.push_back(i * strive + offset);
|
||||
for ( int i = 0; i != size; ++i )
|
||||
ret.push_back( i * strive + offset );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue, typename data_container>
|
||||
void check_q(pri_queue & q, data_container const & expected)
|
||||
template < typename pri_queue, typename data_container >
|
||||
void check_q( pri_queue& q, data_container const& expected )
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(q.size(), expected.size());
|
||||
BOOST_REQUIRE_EQUAL( q.size(), expected.size() );
|
||||
|
||||
for (unsigned int i = 0; i != expected.size(); ++i)
|
||||
{
|
||||
BOOST_REQUIRE_EQUAL(q.size(), expected.size() - i);
|
||||
BOOST_REQUIRE_EQUAL(q.top(), expected[expected.size()-1-i]);
|
||||
for ( unsigned int i = 0; i != expected.size(); ++i ) {
|
||||
BOOST_REQUIRE_EQUAL( q.size(), expected.size() - i );
|
||||
BOOST_REQUIRE_EQUAL( q.top(), expected[ expected.size() - 1 - i ] );
|
||||
q.pop();
|
||||
}
|
||||
|
||||
BOOST_REQUIRE(q.empty());
|
||||
BOOST_REQUIRE( q.empty() );
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue, typename data_container>
|
||||
void fill_q(pri_queue & q, data_container const & data)
|
||||
template < typename pri_queue, typename data_container >
|
||||
void fill_q( pri_queue& q, data_container const& data )
|
||||
{
|
||||
for (unsigned int i = 0; i != data.size(); ++i)
|
||||
q.push(data[i]);
|
||||
for ( unsigned int i = 0; i != data.size(); ++i )
|
||||
q.push( data[ i ] );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <typename pri_queue, typename data_container>
|
||||
void fill_emplace_q(pri_queue & q, data_container const & data)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
template < typename pri_queue, typename data_container >
|
||||
void fill_emplace_q( pri_queue& q, data_container const& data )
|
||||
{
|
||||
for (unsigned int i = 0; i != data.size(); ++i) {
|
||||
typename pri_queue::value_type value = data[i];
|
||||
q.emplace(std::move(value));
|
||||
for ( unsigned int i = 0; i != data.size(); ++i ) {
|
||||
typename pri_queue::value_type value = data[ i ];
|
||||
q.emplace( std::move( value ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_sequential_push(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_sequential_push( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
fill_q(q, data);
|
||||
check_q(q, data);
|
||||
test_data data = make_test_data( i );
|
||||
fill_q( q, data );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_sequential_reverse_push(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_sequential_reverse_push( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
std::reverse(data.begin(), data.end());
|
||||
fill_q(q, data);
|
||||
std::reverse(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
test_data data = make_test_data( i );
|
||||
std::reverse( data.begin(), data.end() );
|
||||
fill_q( q, data );
|
||||
std::reverse( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_emplace(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_emplace( void )
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
std::reverse(data.begin(), data.end());
|
||||
fill_emplace_q(q, data);
|
||||
std::reverse(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
test_data data = make_test_data( i );
|
||||
std::reverse( data.begin(), data.end() );
|
||||
fill_emplace_q( q, data );
|
||||
std::reverse( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_random_push(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_random_push( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
test_data data = make_test_data( i );
|
||||
|
||||
test_data shuffled (data);
|
||||
random_shuffle(shuffled.begin(), shuffled.end());
|
||||
test_data shuffled( data );
|
||||
random_shuffle( shuffled.begin(), shuffled.end() );
|
||||
|
||||
fill_q(q, shuffled);
|
||||
fill_q( q, shuffled );
|
||||
|
||||
check_q(q, data);
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_copyconstructor(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_copyconstructor( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
fill_q(q, data);
|
||||
test_data data = make_test_data( i );
|
||||
fill_q( q, data );
|
||||
|
||||
pri_queue r(q);
|
||||
pri_queue r( q );
|
||||
|
||||
check_q(r, data);
|
||||
check_q( r, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_assignment(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_assignment( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
fill_q(q, data);
|
||||
test_data data = make_test_data( i );
|
||||
fill_q( q, data );
|
||||
|
||||
pri_queue r;
|
||||
r = q;
|
||||
|
||||
check_q(r, data);
|
||||
check_q( r, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_moveconstructor(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_moveconstructor( void )
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
fill_q(q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
fill_q( q, data );
|
||||
|
||||
pri_queue r(std::move(q));
|
||||
pri_queue r( std::move( q ) );
|
||||
|
||||
check_q(r, data);
|
||||
BOOST_REQUIRE(q.empty());
|
||||
check_q( r, data );
|
||||
BOOST_REQUIRE( q.empty() );
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_move_assignment(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_move_assignment( void )
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
fill_q(q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
fill_q( q, data );
|
||||
|
||||
pri_queue r;
|
||||
r = std::move(q);
|
||||
r = std::move( q );
|
||||
|
||||
check_q(r, data);
|
||||
BOOST_REQUIRE(q.empty());
|
||||
check_q( r, data );
|
||||
BOOST_REQUIRE( q.empty() );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_swap(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_swap( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
test_data shuffled (data);
|
||||
random_shuffle(shuffled.begin(), shuffled.end());
|
||||
fill_q(q, shuffled);
|
||||
test_data data = make_test_data( i );
|
||||
test_data shuffled( data );
|
||||
random_shuffle( shuffled.begin(), shuffled.end() );
|
||||
fill_q( q, shuffled );
|
||||
|
||||
pri_queue r;
|
||||
|
||||
q.swap(r);
|
||||
check_q(r, data);
|
||||
BOOST_REQUIRE(q.empty());
|
||||
q.swap( r );
|
||||
check_q( r, data );
|
||||
BOOST_REQUIRE( q.empty() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_iterators(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_iterators( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
test_data data = make_test_data(test_size);
|
||||
test_data shuffled (data);
|
||||
random_shuffle(shuffled.begin(), shuffled.end());
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
test_data data = make_test_data( test_size );
|
||||
test_data shuffled( data );
|
||||
random_shuffle( shuffled.begin(), shuffled.end() );
|
||||
pri_queue q;
|
||||
BOOST_REQUIRE(q.begin() == q.end());
|
||||
fill_q(q, shuffled);
|
||||
BOOST_REQUIRE( q.begin() == q.end() );
|
||||
fill_q( q, shuffled );
|
||||
|
||||
for (unsigned long j = 0; j != data.size(); ++j)
|
||||
BOOST_REQUIRE(std::find(q.begin(), q.end(), data[j]) != q.end());
|
||||
for ( unsigned long j = 0; j != data.size(); ++j )
|
||||
BOOST_REQUIRE( std::find( q.begin(), q.end(), data[ j ] ) != q.end() );
|
||||
|
||||
for (unsigned long j = 0; j != data.size(); ++j)
|
||||
BOOST_REQUIRE(std::find(q.begin(), q.end(), data[j] + data.size()) == q.end());
|
||||
for ( unsigned long j = 0; j != data.size(); ++j )
|
||||
BOOST_REQUIRE( std::find( q.begin(), q.end(), data[ j ] + data.size() ) == q.end() );
|
||||
|
||||
test_data data_from_queue(q.begin(), q.end());
|
||||
std::sort(data_from_queue.begin(), data_from_queue.end());
|
||||
test_data data_from_queue( q.begin(), q.end() );
|
||||
std::sort( data_from_queue.begin(), data_from_queue.end() );
|
||||
|
||||
BOOST_REQUIRE(data == data_from_queue);
|
||||
BOOST_REQUIRE( data == data_from_queue );
|
||||
|
||||
for (unsigned long j = 0; j != data.size(); ++j) {
|
||||
BOOST_REQUIRE_EQUAL((long)std::distance(q.begin(), q.end()), (long)(data.size() - j));
|
||||
for ( unsigned long j = 0; j != data.size(); ++j ) {
|
||||
BOOST_REQUIRE_EQUAL( (long)std::distance( q.begin(), q.end() ), (long)( data.size() - j ) );
|
||||
q.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_ordered_iterators(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_ordered_iterators( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
test_data data = make_test_data(i);
|
||||
test_data shuffled (data);
|
||||
random_shuffle(shuffled.begin(), shuffled.end());
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
test_data data = make_test_data( i );
|
||||
test_data shuffled( data );
|
||||
random_shuffle( shuffled.begin(), shuffled.end() );
|
||||
pri_queue q;
|
||||
BOOST_REQUIRE(q.ordered_begin() == q.ordered_end());
|
||||
fill_q(q, shuffled);
|
||||
BOOST_REQUIRE( q.ordered_begin() == q.ordered_end() );
|
||||
fill_q( q, shuffled );
|
||||
|
||||
test_data data_from_queue(q.ordered_begin(), q.ordered_end());
|
||||
std::reverse(data_from_queue.begin(), data_from_queue.end());
|
||||
BOOST_REQUIRE(data == data_from_queue);
|
||||
test_data data_from_queue( q.ordered_begin(), q.ordered_end() );
|
||||
std::reverse( data_from_queue.begin(), data_from_queue.end() );
|
||||
BOOST_REQUIRE( data == data_from_queue );
|
||||
|
||||
for (unsigned long j = 0; j != data.size(); ++j)
|
||||
BOOST_REQUIRE(std::find(q.ordered_begin(), q.ordered_end(), data[j]) != q.ordered_end());
|
||||
for ( unsigned long j = 0; j != data.size(); ++j )
|
||||
BOOST_REQUIRE( std::find( q.ordered_begin(), q.ordered_end(), data[ j ] ) != q.ordered_end() );
|
||||
|
||||
for (unsigned long j = 0; j != data.size(); ++j)
|
||||
BOOST_REQUIRE(std::find(q.ordered_begin(), q.ordered_end(), data[j] + data.size()) == q.ordered_end());
|
||||
for ( unsigned long j = 0; j != data.size(); ++j )
|
||||
BOOST_REQUIRE( std::find( q.ordered_begin(), q.ordered_end(), data[ j ] + data.size() ) == q.ordered_end() );
|
||||
|
||||
for (unsigned long j = 0; j != data.size(); ++j) {
|
||||
BOOST_REQUIRE_EQUAL((long)std::distance(q.begin(), q.end()), (long)(data.size() - j));
|
||||
for ( unsigned long j = 0; j != data.size(); ++j ) {
|
||||
BOOST_REQUIRE_EQUAL( (long)std::distance( q.begin(), q.end() ), (long)( data.size() - j ) );
|
||||
q.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_equality(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_equality( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
test_data data = make_test_data(i);
|
||||
fill_q(q, data);
|
||||
std::reverse(data.begin(), data.end());
|
||||
fill_q(r, data);
|
||||
test_data data = make_test_data( i );
|
||||
fill_q( q, data );
|
||||
std::reverse( data.begin(), data.end() );
|
||||
fill_q( r, data );
|
||||
|
||||
BOOST_REQUIRE(r == q);
|
||||
BOOST_REQUIRE( r == q );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_inequality(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_inequality( void )
|
||||
{
|
||||
for (int i = 1; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 1; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
test_data data = make_test_data(i);
|
||||
fill_q(q, data);
|
||||
data[0] = data.back() + 1;
|
||||
fill_q(r, data);
|
||||
test_data data = make_test_data( i );
|
||||
fill_q( q, data );
|
||||
data[ 0 ] = data.back() + 1;
|
||||
fill_q( r, data );
|
||||
|
||||
BOOST_REQUIRE(r != q);
|
||||
BOOST_REQUIRE( r != q );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_less(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_less( void )
|
||||
{
|
||||
for (int i = 1; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 1; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
test_data data = make_test_data(i);
|
||||
test_data r_data(data);
|
||||
test_data data = make_test_data( i );
|
||||
test_data r_data( data );
|
||||
r_data.pop_back();
|
||||
|
||||
fill_q(q, data);
|
||||
fill_q(r, r_data);
|
||||
fill_q( q, data );
|
||||
fill_q( r, r_data );
|
||||
|
||||
BOOST_REQUIRE(r < q);
|
||||
BOOST_REQUIRE( r < q );
|
||||
}
|
||||
|
||||
for (int i = 1; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 1; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
test_data data = make_test_data(i);
|
||||
test_data r_data(data);
|
||||
data.push_back(data.back() + 1);
|
||||
test_data data = make_test_data( i );
|
||||
test_data r_data( data );
|
||||
data.push_back( data.back() + 1 );
|
||||
|
||||
fill_q(q, data);
|
||||
fill_q(r, r_data);
|
||||
fill_q( q, data );
|
||||
fill_q( r, r_data );
|
||||
|
||||
BOOST_REQUIRE(r < q);
|
||||
BOOST_REQUIRE( r < q );
|
||||
}
|
||||
|
||||
for (int i = 1; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 1; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
test_data data = make_test_data(i);
|
||||
test_data r_data(data);
|
||||
test_data data = make_test_data( i );
|
||||
test_data r_data( data );
|
||||
|
||||
data.back() += 1;
|
||||
|
||||
fill_q(q, data);
|
||||
fill_q(r, r_data);
|
||||
fill_q( q, data );
|
||||
fill_q( r, r_data );
|
||||
|
||||
BOOST_REQUIRE(r < q);
|
||||
BOOST_REQUIRE( r < q );
|
||||
}
|
||||
|
||||
for (int i = 1; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 1; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
test_data data = make_test_data(i);
|
||||
test_data r_data(data);
|
||||
test_data data = make_test_data( i );
|
||||
test_data r_data( data );
|
||||
|
||||
r_data.front() -= 1;
|
||||
|
||||
fill_q(q, data);
|
||||
fill_q(r, r_data);
|
||||
fill_q( q, data );
|
||||
fill_q( r, r_data );
|
||||
|
||||
BOOST_REQUIRE(r < q);
|
||||
BOOST_REQUIRE( r < q );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_clear(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_clear( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(i);
|
||||
fill_q(q, data);
|
||||
test_data data = make_test_data( i );
|
||||
fill_q( q, data );
|
||||
|
||||
q.clear();
|
||||
BOOST_REQUIRE(q.size() == 0);
|
||||
BOOST_REQUIRE(q.empty());
|
||||
BOOST_REQUIRE( q.size() == 0 );
|
||||
BOOST_REQUIRE( q.empty() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_concept_check(void)
|
||||
template < typename pri_queue >
|
||||
void run_concept_check( void )
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::PriorityQueue< pri_queue >));
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_common_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_common_heap_tests( void )
|
||||
{
|
||||
pri_queue_test_sequential_push<pri_queue>();
|
||||
pri_queue_test_sequential_reverse_push<pri_queue>();
|
||||
pri_queue_test_random_push<pri_queue>();
|
||||
pri_queue_test_equality<pri_queue>();
|
||||
pri_queue_test_inequality<pri_queue>();
|
||||
pri_queue_test_less<pri_queue>();
|
||||
pri_queue_test_clear<pri_queue>();
|
||||
pri_queue_test_sequential_push< pri_queue >();
|
||||
pri_queue_test_sequential_reverse_push< pri_queue >();
|
||||
pri_queue_test_random_push< pri_queue >();
|
||||
pri_queue_test_equality< pri_queue >();
|
||||
pri_queue_test_inequality< pri_queue >();
|
||||
pri_queue_test_less< pri_queue >();
|
||||
pri_queue_test_clear< pri_queue >();
|
||||
|
||||
pri_queue_test_emplace<pri_queue>();
|
||||
pri_queue_test_emplace< pri_queue >();
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_iterator_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_iterator_heap_tests( void )
|
||||
{
|
||||
pri_queue_test_iterators<pri_queue>();
|
||||
pri_queue_test_iterators< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_copyable_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_copyable_heap_tests( void )
|
||||
{
|
||||
pri_queue_test_copyconstructor <pri_queue>();
|
||||
pri_queue_test_assignment<pri_queue>();
|
||||
pri_queue_test_swap<pri_queue>();
|
||||
pri_queue_test_copyconstructor< pri_queue >();
|
||||
pri_queue_test_assignment< pri_queue >();
|
||||
pri_queue_test_swap< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_moveable_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_moveable_heap_tests( void )
|
||||
{
|
||||
pri_queue_test_moveconstructor <pri_queue>();
|
||||
pri_queue_test_move_assignment <pri_queue>();
|
||||
pri_queue_test_moveconstructor< pri_queue >();
|
||||
pri_queue_test_move_assignment< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_reserve_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_reserve_heap_tests( void )
|
||||
{
|
||||
test_data data = make_test_data(test_size);
|
||||
test_data data = make_test_data( test_size );
|
||||
pri_queue q;
|
||||
q.reserve(6);
|
||||
fill_q(q, data);
|
||||
q.reserve( 6 );
|
||||
fill_q( q, data );
|
||||
|
||||
check_q(q, data);
|
||||
check_q( q, data );
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_leak_check_test(void)
|
||||
template < typename pri_queue >
|
||||
void run_leak_check_test( void )
|
||||
{
|
||||
pri_queue q;
|
||||
q.push(boost::shared_ptr<int>(new int(0)));
|
||||
q.push( boost::shared_ptr< int >( new int( 0 ) ) );
|
||||
}
|
||||
|
||||
|
||||
struct less_with_T
|
||||
{
|
||||
typedef int T;
|
||||
bool operator()(const int& a, const int& b) const
|
||||
bool operator()( const int& a, const int& b ) const
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
|
||||
class thing {
|
||||
class thing
|
||||
{
|
||||
public:
|
||||
thing( int a_, int b_, int c_ ) : a(a_), b(b_), c(c_) {}
|
||||
thing( int a_, int b_, int c_ ) :
|
||||
a( a_ ),
|
||||
b( b_ ),
|
||||
c( c_ )
|
||||
{}
|
||||
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
};
|
||||
|
||||
class cmpthings {
|
||||
class cmpthings
|
||||
{
|
||||
public:
|
||||
bool operator() ( const thing& lhs, const thing& rhs ) const {
|
||||
bool operator()( const thing& lhs, const thing& rhs ) const
|
||||
{
|
||||
return lhs.a > rhs.a;
|
||||
}
|
||||
bool operator() ( const thing& lhs, const thing& rhs ) {
|
||||
bool operator()( const thing& lhs, const thing& rhs )
|
||||
{
|
||||
return lhs.a > rhs.a;
|
||||
}
|
||||
};
|
||||
|
||||
#define RUN_EMPLACE_TEST(HEAP_TYPE) \
|
||||
do { \
|
||||
cmpthings ord; \
|
||||
boost::heap::HEAP_TYPE<thing, boost::heap::compare<cmpthings> > vpq(ord); \
|
||||
vpq.emplace(5, 6, 7); \
|
||||
boost::heap::HEAP_TYPE<thing, boost::heap::compare<cmpthings>, boost::heap::stable<true> > vpq2(ord); \
|
||||
vpq2.emplace(5, 6, 7); \
|
||||
} while(0);
|
||||
# define RUN_EMPLACE_TEST( HEAP_TYPE ) \
|
||||
do { \
|
||||
cmpthings ord; \
|
||||
boost::heap::HEAP_TYPE< thing, boost::heap::compare< cmpthings > > vpq( ord ); \
|
||||
vpq.emplace( 5, 6, 7 ); \
|
||||
boost::heap::HEAP_TYPE< thing, boost::heap::compare< cmpthings >, boost::heap::stable< true > > vpq2( ord ); \
|
||||
vpq2.emplace( 5, 6, 7 ); \
|
||||
} while ( 0 );
|
||||
|
||||
#else
|
||||
#define RUN_EMPLACE_TEST(HEAP_TYPE)
|
||||
# define RUN_EMPLACE_TEST( HEAP_TYPE )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#ifdef BOOST_HEAP_INCLUDE_TESTS
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
# include <boost/test/included/unit_test.hpp>
|
||||
#else
|
||||
#include <boost/test/unit_test.hpp>
|
||||
# include <boost/test/unit_test.hpp>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
@@ -18,118 +18,118 @@
|
||||
#include <boost/heap/d_ary_heap.hpp>
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "merge_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
|
||||
|
||||
template <int D, bool stable>
|
||||
void run_d_ary_heap_test(void)
|
||||
template < int D, bool stable >
|
||||
void run_d_ary_heap_test( void )
|
||||
{
|
||||
typedef boost::heap::d_ary_heap<int, boost::heap::arity<D>,
|
||||
boost::heap::stable<stable>,
|
||||
boost::heap::compare<std::less<int> >,
|
||||
boost::heap::allocator<std::allocator<int> > > pri_queue;
|
||||
typedef boost::heap::d_ary_heap< int,
|
||||
boost::heap::arity< D >,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::compare< std::less< int > >,
|
||||
boost::heap::allocator< std::allocator< int > > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::PriorityQueue< pri_queue >));
|
||||
|
||||
run_concept_check<pri_queue>();
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_reserve_heap_tests<pri_queue>();
|
||||
run_merge_tests<pri_queue>();
|
||||
run_concept_check< pri_queue >();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
run_reserve_heap_tests< pri_queue >();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
run_ordered_iterator_tests<pri_queue>();
|
||||
run_ordered_iterator_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::d_ary_heap<q_tester, boost::heap::arity<D>,
|
||||
boost::heap::stable<stable>
|
||||
> stable_pri_queue;
|
||||
if ( stable ) {
|
||||
typedef boost::heap::d_ary_heap< q_tester, boost::heap::arity< D >, boost::heap::stable< stable > > stable_pri_queue;
|
||||
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) && !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES )
|
||||
cmpthings ord;
|
||||
boost::heap::d_ary_heap<thing, boost::heap::arity<D>, boost::heap::compare<cmpthings>, boost::heap::stable<stable> > vpq(ord);
|
||||
vpq.emplace(5, 6, 7);
|
||||
boost::heap::d_ary_heap< thing, boost::heap::arity< D >, boost::heap::compare< cmpthings >, boost::heap::stable< stable > >
|
||||
vpq( ord );
|
||||
vpq.emplace( 5, 6, 7 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_ary_heap_test )
|
||||
{
|
||||
run_d_ary_heap_test<2, false>();
|
||||
run_d_ary_heap_test<3, false>();
|
||||
run_d_ary_heap_test<4, false>();
|
||||
run_d_ary_heap_test<5, false>();
|
||||
run_d_ary_heap_test< 2, false >();
|
||||
run_d_ary_heap_test< 3, false >();
|
||||
run_d_ary_heap_test< 4, false >();
|
||||
run_d_ary_heap_test< 5, false >();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_ary_heap_stable_test )
|
||||
{
|
||||
run_d_ary_heap_test<2, true>();
|
||||
run_d_ary_heap_test<3, true>();
|
||||
run_d_ary_heap_test<4, true>();
|
||||
run_d_ary_heap_test<5, true>();
|
||||
run_d_ary_heap_test< 2, true >();
|
||||
run_d_ary_heap_test< 3, true >();
|
||||
run_d_ary_heap_test< 4, true >();
|
||||
run_d_ary_heap_test< 5, true >();
|
||||
}
|
||||
|
||||
template <int D, bool stable>
|
||||
void run_d_ary_heap_mutable_test(void)
|
||||
template < int D, bool stable >
|
||||
void run_d_ary_heap_mutable_test( void )
|
||||
{
|
||||
typedef boost::heap::d_ary_heap<int, boost::heap::mutable_<true>,
|
||||
boost::heap::arity<D>,
|
||||
boost::heap::stable<stable>
|
||||
> pri_queue;
|
||||
typedef boost::heap::d_ary_heap< int, boost::heap::mutable_< true >, boost::heap::arity< D >, boost::heap::stable< stable > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MutablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MutablePriorityQueue< pri_queue >));
|
||||
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_reserve_heap_tests<pri_queue>();
|
||||
run_mutable_heap_tests<pri_queue>();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
run_reserve_heap_tests< pri_queue >();
|
||||
run_mutable_heap_tests< pri_queue >();
|
||||
|
||||
run_merge_tests<pri_queue>();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
run_ordered_iterator_tests<pri_queue>();
|
||||
run_ordered_iterator_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::d_ary_heap<q_tester, boost::heap::mutable_<true>,
|
||||
boost::heap::arity<D>,
|
||||
boost::heap::stable<stable>
|
||||
> stable_pri_queue;
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
if ( stable ) {
|
||||
typedef boost::heap::
|
||||
d_ary_heap< q_tester, boost::heap::mutable_< true >, boost::heap::arity< D >, boost::heap::stable< stable > >
|
||||
stable_pri_queue;
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_ary_heap_mutable_test )
|
||||
{
|
||||
run_d_ary_heap_mutable_test<2, false>();
|
||||
run_d_ary_heap_mutable_test<3, false>();
|
||||
run_d_ary_heap_mutable_test<4, false>();
|
||||
run_d_ary_heap_mutable_test<5, false>();
|
||||
run_d_ary_heap_mutable_test< 2, false >();
|
||||
run_d_ary_heap_mutable_test< 3, false >();
|
||||
run_d_ary_heap_mutable_test< 4, false >();
|
||||
run_d_ary_heap_mutable_test< 5, false >();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_ary_heap_mutable_stable_test )
|
||||
{
|
||||
run_d_ary_heap_mutable_test<2, true>();
|
||||
run_d_ary_heap_mutable_test<3, true>();
|
||||
run_d_ary_heap_mutable_test<4, true>();
|
||||
run_d_ary_heap_mutable_test<5, true>();
|
||||
run_d_ary_heap_mutable_test< 2, true >();
|
||||
run_d_ary_heap_mutable_test< 3, true >();
|
||||
run_d_ary_heap_mutable_test< 4, true >();
|
||||
run_d_ary_heap_mutable_test< 5, true >();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_ary_heap_compare_lookup_test )
|
||||
{
|
||||
typedef boost::heap::d_ary_heap<int, boost::heap::arity<2>,
|
||||
boost::heap::compare<less_with_T>,
|
||||
boost::heap::allocator<std::allocator<int> > > pri_queue;
|
||||
run_common_heap_tests<pri_queue>();
|
||||
typedef boost::heap::d_ary_heap< int,
|
||||
boost::heap::arity< 2 >,
|
||||
boost::heap::compare< less_with_T >,
|
||||
boost::heap::allocator< std::allocator< int > > >
|
||||
pri_queue;
|
||||
run_common_heap_tests< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_ary_heap_leak_test )
|
||||
{
|
||||
typedef boost::heap::d_ary_heap<boost::shared_ptr<int>, boost::heap::arity<2> > pri_queue;
|
||||
run_leak_check_test<pri_queue>();
|
||||
typedef boost::heap::d_ary_heap< boost::shared_ptr< int >, boost::heap::arity< 2 > > pri_queue;
|
||||
run_leak_check_test< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -14,63 +14,65 @@
|
||||
#include <boost/heap/fibonacci_heap.hpp>
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "merge_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
|
||||
|
||||
template <bool stable, bool constant_time_size>
|
||||
void run_fibonacci_heap_test(void)
|
||||
template < bool stable, bool constant_time_size >
|
||||
void run_fibonacci_heap_test( void )
|
||||
{
|
||||
typedef boost::heap::fibonacci_heap<int, boost::heap::stable<stable>,
|
||||
boost::heap::compare<std::less<int> >,
|
||||
boost::heap::allocator<std::allocator<int> >,
|
||||
boost::heap::constant_time_size<constant_time_size>
|
||||
> pri_queue;
|
||||
typedef boost::heap::fibonacci_heap< int,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::compare< std::less< int > >,
|
||||
boost::heap::allocator< std::allocator< int > >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MutablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MergablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MutablePriorityQueue< pri_queue >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MergablePriorityQueue< pri_queue >));
|
||||
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
|
||||
run_merge_tests<pri_queue>();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
run_mutable_heap_tests<pri_queue>();
|
||||
run_ordered_iterator_tests<pri_queue>();
|
||||
run_mutable_heap_tests< pri_queue >();
|
||||
run_ordered_iterator_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::fibonacci_heap<q_tester, boost::heap::stable<stable>,
|
||||
boost::heap::constant_time_size<constant_time_size>
|
||||
> stable_pri_queue;
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
if ( stable ) {
|
||||
typedef boost::heap::fibonacci_heap< q_tester,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
stable_pri_queue;
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fibonacci_heap_test )
|
||||
{
|
||||
run_fibonacci_heap_test<true, false>();
|
||||
run_fibonacci_heap_test<true, true>();
|
||||
run_fibonacci_heap_test< true, false >();
|
||||
run_fibonacci_heap_test< true, true >();
|
||||
|
||||
run_fibonacci_heap_test<false, false>();
|
||||
run_fibonacci_heap_test<false, true>();
|
||||
run_fibonacci_heap_test< false, false >();
|
||||
run_fibonacci_heap_test< false, true >();
|
||||
|
||||
RUN_EMPLACE_TEST(fibonacci_heap);
|
||||
RUN_EMPLACE_TEST( fibonacci_heap );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fibonacci_heap_compare_lookup_test )
|
||||
{
|
||||
typedef boost::heap::fibonacci_heap<int,
|
||||
boost::heap::compare<less_with_T>,
|
||||
boost::heap::allocator<std::allocator<int> > > pri_queue;
|
||||
run_common_heap_tests<pri_queue>();
|
||||
typedef boost::heap::
|
||||
fibonacci_heap< int, boost::heap::compare< less_with_T >, boost::heap::allocator< std::allocator< int > > >
|
||||
pri_queue;
|
||||
run_common_heap_tests< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fibonacci_heap_leak_test )
|
||||
{
|
||||
typedef boost::heap::fibonacci_heap<boost::shared_ptr<int> > pri_queue;
|
||||
run_leak_check_test<pri_queue>();
|
||||
typedef boost::heap::fibonacci_heap< boost::shared_ptr< int > > pri_queue;
|
||||
run_leak_check_test< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -9,67 +9,63 @@
|
||||
#include "common_heap_tests.hpp"
|
||||
#include <boost/heap/heap_merge.hpp>
|
||||
|
||||
#define GENERATE_TEST_DATA(INDEX) \
|
||||
test_data data = make_test_data(test_size, 0, 1); \
|
||||
random_shuffle(data.begin(), data.end()); \
|
||||
#define GENERATE_TEST_DATA( INDEX ) \
|
||||
test_data data = make_test_data( test_size, 0, 1 ); \
|
||||
random_shuffle( data.begin(), data.end() ); \
|
||||
\
|
||||
test_data data_q (data.begin(), data.begin() + INDEX); \
|
||||
test_data data_r (data.begin() + INDEX, data.end()); \
|
||||
test_data data_q( data.begin(), data.begin() + INDEX ); \
|
||||
test_data data_r( data.begin() + INDEX, data.end() ); \
|
||||
\
|
||||
std::stable_sort(data.begin(), data.end());
|
||||
std::stable_sort( data.begin(), data.end() );
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct pri_queue_test_merge
|
||||
{
|
||||
static void run(void)
|
||||
static void run( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q, r;
|
||||
GENERATE_TEST_DATA(i);
|
||||
GENERATE_TEST_DATA( i );
|
||||
|
||||
fill_q(q, data_q);
|
||||
fill_q(r, data_r);
|
||||
fill_q( q, data_q );
|
||||
fill_q( r, data_r );
|
||||
|
||||
q.merge(r);
|
||||
q.merge( r );
|
||||
|
||||
BOOST_REQUIRE(r.empty());
|
||||
check_q(q, data);
|
||||
BOOST_REQUIRE( r.empty() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename pri_queue1, typename pri_queue2>
|
||||
template < typename pri_queue1, typename pri_queue2 >
|
||||
struct pri_queue_test_heap_merge
|
||||
{
|
||||
static void run (void)
|
||||
static void run( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue1 q;
|
||||
pri_queue2 r;
|
||||
GENERATE_TEST_DATA(i);
|
||||
GENERATE_TEST_DATA( i );
|
||||
|
||||
fill_q(q, data_q);
|
||||
fill_q(r, data_r);
|
||||
fill_q( q, data_q );
|
||||
fill_q( r, data_r );
|
||||
|
||||
boost::heap::heap_merge(q, r);
|
||||
boost::heap::heap_merge( q, r );
|
||||
|
||||
BOOST_REQUIRE(r.empty());
|
||||
check_q(q, data);
|
||||
BOOST_REQUIRE( r.empty() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_merge_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_merge_tests( void )
|
||||
{
|
||||
boost::conditional<pri_queue::is_mergable,
|
||||
pri_queue_test_merge<pri_queue>,
|
||||
dummy_run
|
||||
>::type::run();
|
||||
boost::conditional< pri_queue::is_mergable, pri_queue_test_merge< pri_queue >, dummy_run >::type::run();
|
||||
|
||||
pri_queue_test_heap_merge<pri_queue, pri_queue>::run();
|
||||
pri_queue_test_heap_merge< pri_queue, pri_queue >::run();
|
||||
}
|
||||
|
||||
@@ -9,44 +9,46 @@
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <boost/heap/binomial_heap.hpp>
|
||||
#include <boost/heap/d_ary_heap.hpp>
|
||||
#include <boost/heap/fibonacci_heap.hpp>
|
||||
#include <boost/heap/pairing_heap.hpp>
|
||||
#include <boost/heap/binomial_heap.hpp>
|
||||
#include <boost/heap/skew_heap.hpp>
|
||||
|
||||
using namespace boost::heap;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, != 1800)
|
||||
typedef fibonacci_heap<struct fwd_declared_struct_1>::handle_type handle_type_1;
|
||||
typedef d_ary_heap<struct fwd_declared_struct_2, arity<4>, mutable_<true> >::handle_type handle_type_2;
|
||||
typedef pairing_heap<struct fwd_declared_struct_3>::handle_type handle_type_3;
|
||||
typedef binomial_heap<struct fwd_declared_struct_4>::handle_type handle_type_4;
|
||||
typedef skew_heap<struct fwd_declared_struct_5, mutable_<true> >::handle_type handle_type_5;
|
||||
#if BOOST_WORKAROUND( BOOST_MSVC, != 1800 )
|
||||
typedef fibonacci_heap< struct fwd_declared_struct_1 >::handle_type handle_type_1;
|
||||
typedef d_ary_heap< struct fwd_declared_struct_2, arity< 4 >, mutable_< true > >::handle_type handle_type_2;
|
||||
typedef pairing_heap< struct fwd_declared_struct_3 >::handle_type handle_type_3;
|
||||
typedef binomial_heap< struct fwd_declared_struct_4 >::handle_type handle_type_4;
|
||||
typedef skew_heap< struct fwd_declared_struct_5, mutable_< true > >::handle_type handle_type_5;
|
||||
#endif
|
||||
|
||||
template <typename HeapType>
|
||||
void run_handle_as_member_test(void)
|
||||
template < typename HeapType >
|
||||
void run_handle_as_member_test( void )
|
||||
{
|
||||
typedef typename HeapType::value_type value_type;
|
||||
HeapType heap;
|
||||
value_type f(2);
|
||||
typename value_type::handle_type handle = heap.push(f);
|
||||
value_type & fInHeap = *handle;
|
||||
fInHeap.handle = handle;
|
||||
HeapType heap;
|
||||
value_type f( 2 );
|
||||
typename value_type::handle_type handle = heap.push( f );
|
||||
value_type& fInHeap = *handle;
|
||||
fInHeap.handle = handle;
|
||||
}
|
||||
|
||||
|
||||
struct fibonacci_heap_data
|
||||
{
|
||||
typedef fibonacci_heap<fibonacci_heap_data>::handle_type handle_type;
|
||||
typedef fibonacci_heap< fibonacci_heap_data >::handle_type handle_type;
|
||||
|
||||
handle_type handle;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
fibonacci_heap_data(int i):i(i) {}
|
||||
fibonacci_heap_data( int i ) :
|
||||
i( i )
|
||||
{}
|
||||
|
||||
bool operator<(fibonacci_heap_data const & rhs) const
|
||||
bool operator<( fibonacci_heap_data const& rhs ) const
|
||||
{
|
||||
return i < rhs.i;
|
||||
}
|
||||
@@ -54,19 +56,21 @@ struct fibonacci_heap_data
|
||||
|
||||
BOOST_AUTO_TEST_CASE( fibonacci_heap_handle_as_member )
|
||||
{
|
||||
run_handle_as_member_test<fibonacci_heap<fibonacci_heap_data> >();
|
||||
run_handle_as_member_test< fibonacci_heap< fibonacci_heap_data > >();
|
||||
}
|
||||
|
||||
struct d_heap_data
|
||||
{
|
||||
typedef d_ary_heap<d_heap_data, arity<4>, mutable_<true> >::handle_type handle_type;
|
||||
typedef d_ary_heap< d_heap_data, arity< 4 >, mutable_< true > >::handle_type handle_type;
|
||||
|
||||
handle_type handle;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
d_heap_data(int i):i(i) {}
|
||||
d_heap_data( int i ) :
|
||||
i( i )
|
||||
{}
|
||||
|
||||
bool operator<(d_heap_data const & rhs) const
|
||||
bool operator<( d_heap_data const& rhs ) const
|
||||
{
|
||||
return i < rhs.i;
|
||||
}
|
||||
@@ -75,19 +79,21 @@ struct d_heap_data
|
||||
|
||||
BOOST_AUTO_TEST_CASE( d_heap_handle_as_member )
|
||||
{
|
||||
run_handle_as_member_test<d_ary_heap<d_heap_data, arity<4>, mutable_<true> > >();
|
||||
run_handle_as_member_test< d_ary_heap< d_heap_data, arity< 4 >, mutable_< true > > >();
|
||||
}
|
||||
|
||||
struct pairing_heap_data
|
||||
{
|
||||
typedef pairing_heap<pairing_heap_data>::handle_type handle_type;
|
||||
typedef pairing_heap< pairing_heap_data >::handle_type handle_type;
|
||||
|
||||
handle_type handle;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
pairing_heap_data(int i):i(i) {}
|
||||
pairing_heap_data( int i ) :
|
||||
i( i )
|
||||
{}
|
||||
|
||||
bool operator<(pairing_heap_data const & rhs) const
|
||||
bool operator<( pairing_heap_data const& rhs ) const
|
||||
{
|
||||
return i < rhs.i;
|
||||
}
|
||||
@@ -96,41 +102,45 @@ struct pairing_heap_data
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pairing_heap_handle_as_member )
|
||||
{
|
||||
run_handle_as_member_test<pairing_heap<pairing_heap_data> >();
|
||||
run_handle_as_member_test< pairing_heap< pairing_heap_data > >();
|
||||
}
|
||||
|
||||
|
||||
struct binomial_heap_data
|
||||
{
|
||||
typedef binomial_heap<binomial_heap_data>::handle_type handle_type;
|
||||
typedef binomial_heap< binomial_heap_data >::handle_type handle_type;
|
||||
|
||||
handle_type handle;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
binomial_heap_data(int i):i(i) {}
|
||||
binomial_heap_data( int i ) :
|
||||
i( i )
|
||||
{}
|
||||
|
||||
bool operator<(binomial_heap_data const & rhs) const
|
||||
bool operator<( binomial_heap_data const& rhs ) const
|
||||
{
|
||||
return i < rhs.i;
|
||||
return i < rhs.i;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( binomial_heap_handle_as_member )
|
||||
{
|
||||
run_handle_as_member_test<binomial_heap<binomial_heap_data> >();
|
||||
run_handle_as_member_test< binomial_heap< binomial_heap_data > >();
|
||||
}
|
||||
|
||||
struct skew_heap_data
|
||||
{
|
||||
typedef skew_heap<skew_heap_data, mutable_<true> >::handle_type handle_type;
|
||||
typedef skew_heap< skew_heap_data, mutable_< true > >::handle_type handle_type;
|
||||
|
||||
handle_type handle;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
skew_heap_data(int i):i(i) {}
|
||||
skew_heap_data( int i ) :
|
||||
i( i )
|
||||
{}
|
||||
|
||||
bool operator<(skew_heap_data const & rhs) const
|
||||
bool operator<( skew_heap_data const& rhs ) const
|
||||
{
|
||||
return i < rhs.i;
|
||||
}
|
||||
@@ -139,5 +149,5 @@ struct skew_heap_data
|
||||
|
||||
BOOST_AUTO_TEST_CASE( skew_heap_handle_as_member )
|
||||
{
|
||||
run_handle_as_member_test<skew_heap<skew_heap_data, mutable_<true> > >();
|
||||
run_handle_as_member_test< skew_heap< skew_heap_data, mutable_< true > > >();
|
||||
}
|
||||
|
||||
@@ -7,319 +7,315 @@
|
||||
=============================================================================*/
|
||||
|
||||
// random uses boost.fusion, which clashes with boost.test
|
||||
//#define USE_BOOST_RANDOM
|
||||
// #define USE_BOOST_RANDOM
|
||||
|
||||
#ifdef USE_BOOST_RANDOM
|
||||
#include <boost/random.hpp>
|
||||
# include <boost/random.hpp>
|
||||
#else
|
||||
#include <cstdlib>
|
||||
# include <cstdlib>
|
||||
#endif
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
|
||||
|
||||
#define PUSH_WITH_HANDLES(HANDLES, Q, DATA) \
|
||||
std::vector<typename pri_queue::handle_type> HANDLES; \
|
||||
#define PUSH_WITH_HANDLES( HANDLES, Q, DATA ) \
|
||||
std::vector< typename pri_queue::handle_type > HANDLES; \
|
||||
\
|
||||
for (unsigned int k = 0; k != data.size(); ++k) \
|
||||
HANDLES.push_back(Q.push(DATA[k]));
|
||||
for ( unsigned int k = 0; k != data.size(); ++k ) \
|
||||
HANDLES.push_back( Q.push( DATA[ k ] ) );
|
||||
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_update_decrease(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_update_decrease( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
*handles[i] = -1;
|
||||
data[i] = -1;
|
||||
q.update(handles[i]);
|
||||
*handles[ i ] = -1;
|
||||
data[ i ] = -1;
|
||||
q.update( handles[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_update_decrease_function(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_update_decrease_function( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
data[i] = -1;
|
||||
q.update(handles[i], -1);
|
||||
data[ i ] = -1;
|
||||
q.update( handles[ i ], -1 );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_update_function_identity(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_update_function_identity( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
q.update(handles[i], data[i]);
|
||||
q.update( handles[ i ], data[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_update_shuffled(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_update_shuffled( void )
|
||||
{
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
test_data shuffled (data);
|
||||
random_shuffle(shuffled.begin(), shuffled.end());
|
||||
test_data shuffled( data );
|
||||
random_shuffle( shuffled.begin(), shuffled.end() );
|
||||
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
q.update(handles[i], shuffled[i]);
|
||||
for ( int i = 0; i != test_size; ++i )
|
||||
q.update( handles[ i ], shuffled[ i ] );
|
||||
|
||||
check_q(q, data);
|
||||
check_q( q, data );
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_update_increase(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_update_increase( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
data[i] = data.back()+1;
|
||||
*handles[i] = data[i];
|
||||
q.update(handles[i]);
|
||||
data[ i ] = data.back() + 1;
|
||||
*handles[ i ] = data[ i ];
|
||||
q.update( handles[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_update_increase_function(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_update_increase_function( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
data[i] = data.back()+1;
|
||||
q.update(handles[i], data[i]);
|
||||
data[ i ] = data.back() + 1;
|
||||
q.update( handles[ i ], data[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_decrease(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_decrease( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
*handles[i] = -1;
|
||||
data[i] = -1;
|
||||
q.decrease(handles[i]);
|
||||
*handles[ i ] = -1;
|
||||
data[ i ] = -1;
|
||||
q.decrease( handles[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_decrease_function(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_decrease_function( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
data[i] = -1;
|
||||
q.decrease(handles[i], -1);
|
||||
data[ i ] = -1;
|
||||
q.decrease( handles[ i ], -1 );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_decrease_function_identity(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_decrease_function_identity( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
q.decrease(handles[i], data[i]);
|
||||
q.decrease( handles[ i ], data[ i ] );
|
||||
|
||||
check_q(q, data);
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_increase(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_increase( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
data[i] = data.back()+1;
|
||||
*handles[i] = data[i];
|
||||
q.increase(handles[i]);
|
||||
data[ i ] = data.back() + 1;
|
||||
*handles[ i ] = data[ i ];
|
||||
q.increase( handles[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_increase_function(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_increase_function( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
data[i] = data.back()+1;
|
||||
q.increase(handles[i], data[i]);
|
||||
data[ i ] = data.back() + 1;
|
||||
q.increase( handles[ i ], data[ i ] );
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_increase_function_identity(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_increase_function_identity( void )
|
||||
{
|
||||
for (int i = 0; i != test_size; ++i) {
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
q.increase(handles[i], data[i]);
|
||||
q.increase( handles[ i ], data[ i ] );
|
||||
|
||||
check_q(q, data);
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_test_erase(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_test_erase( void )
|
||||
{
|
||||
#ifdef USE_BOOST_RANDOM
|
||||
boost::mt19937 rng;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i != test_size; ++i)
|
||||
{
|
||||
for ( int i = 0; i != test_size; ++i ) {
|
||||
pri_queue q;
|
||||
test_data data = make_test_data(test_size);
|
||||
PUSH_WITH_HANDLES(handles, q, data);
|
||||
test_data data = make_test_data( test_size );
|
||||
PUSH_WITH_HANDLES( handles, q, data );
|
||||
|
||||
for (int j = 0; j != i; ++j)
|
||||
{
|
||||
for ( int j = 0; j != i; ++j ) {
|
||||
#ifdef USE_BOOST_RANDOM
|
||||
boost::uniform_int<> range(0, data.size() - 1);
|
||||
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > gen(rng, range);
|
||||
boost::uniform_int<> range( 0, data.size() - 1 );
|
||||
boost::variate_generator< boost::mt19937&, boost::uniform_int<> > gen( rng, range );
|
||||
|
||||
int index = gen();
|
||||
#else
|
||||
int index = std::rand() % (data.size() - 1);
|
||||
int index = std::rand() % ( data.size() - 1 );
|
||||
#endif
|
||||
q.erase(handles[index]);
|
||||
handles.erase(handles.begin() + index);
|
||||
data.erase(data.begin() + index);
|
||||
q.erase( handles[ index ] );
|
||||
handles.erase( handles.begin() + index );
|
||||
data.erase( data.begin() + index );
|
||||
}
|
||||
|
||||
std::sort(data.begin(), data.end());
|
||||
check_q(q, data);
|
||||
std::sort( data.begin(), data.end() );
|
||||
check_q( q, data );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_update_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_update_tests( void )
|
||||
{
|
||||
pri_queue_test_update_increase<pri_queue>();
|
||||
pri_queue_test_update_decrease<pri_queue>();
|
||||
pri_queue_test_update_increase< pri_queue >();
|
||||
pri_queue_test_update_decrease< pri_queue >();
|
||||
|
||||
pri_queue_test_update_shuffled<pri_queue>();
|
||||
pri_queue_test_update_shuffled< pri_queue >();
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_update_function_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_update_function_tests( void )
|
||||
{
|
||||
pri_queue_test_update_increase_function<pri_queue>();
|
||||
pri_queue_test_update_decrease_function<pri_queue>();
|
||||
pri_queue_test_update_function_identity<pri_queue>();
|
||||
pri_queue_test_update_increase_function< pri_queue >();
|
||||
pri_queue_test_update_decrease_function< pri_queue >();
|
||||
pri_queue_test_update_function_identity< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_decrease_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_decrease_tests( void )
|
||||
{
|
||||
pri_queue_test_decrease<pri_queue>();
|
||||
pri_queue_test_decrease_function<pri_queue>();
|
||||
pri_queue_test_decrease_function_identity<pri_queue>();
|
||||
pri_queue_test_decrease< pri_queue >();
|
||||
pri_queue_test_decrease_function< pri_queue >();
|
||||
pri_queue_test_decrease_function_identity< pri_queue >();
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_increase_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_increase_tests( void )
|
||||
{
|
||||
pri_queue_test_increase<pri_queue>();
|
||||
pri_queue_test_increase_function<pri_queue>();
|
||||
pri_queue_test_increase_function_identity<pri_queue>();
|
||||
pri_queue_test_increase< pri_queue >();
|
||||
pri_queue_test_increase_function< pri_queue >();
|
||||
pri_queue_test_increase_function_identity< pri_queue >();
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_erase_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_erase_tests( void )
|
||||
{
|
||||
pri_queue_test_erase<pri_queue>();
|
||||
pri_queue_test_erase< pri_queue >();
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_test_handle_from_iterator(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_test_handle_from_iterator( void )
|
||||
{
|
||||
pri_queue que;
|
||||
|
||||
que.push(3);
|
||||
que.push(1);
|
||||
que.push(4);
|
||||
que.push( 3 );
|
||||
que.push( 1 );
|
||||
que.push( 4 );
|
||||
|
||||
que.update(pri_queue::s_handle_from_iterator(que.begin()),
|
||||
6);
|
||||
que.update( pri_queue::s_handle_from_iterator( que.begin() ), 6 );
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_mutable_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_mutable_heap_tests( void )
|
||||
{
|
||||
run_mutable_heap_update_function_tests<pri_queue>();
|
||||
run_mutable_heap_update_tests<pri_queue>();
|
||||
run_mutable_heap_decrease_tests<pri_queue>();
|
||||
run_mutable_heap_increase_tests<pri_queue>();
|
||||
run_mutable_heap_erase_tests<pri_queue>();
|
||||
run_mutable_heap_test_handle_from_iterator<pri_queue>();
|
||||
run_mutable_heap_update_function_tests< pri_queue >();
|
||||
run_mutable_heap_update_tests< pri_queue >();
|
||||
run_mutable_heap_decrease_tests< pri_queue >();
|
||||
run_mutable_heap_increase_tests< pri_queue >();
|
||||
run_mutable_heap_erase_tests< pri_queue >();
|
||||
run_mutable_heap_test_handle_from_iterator< pri_queue >();
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
void run_ordered_iterator_tests()
|
||||
{
|
||||
pri_queue_test_ordered_iterators<pri_queue>();
|
||||
pri_queue_test_ordered_iterators< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -14,61 +14,64 @@
|
||||
#include <boost/heap/pairing_heap.hpp>
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "merge_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
|
||||
template <bool stable, bool constant_time_size>
|
||||
void run_pairing_heap_test(void)
|
||||
template < bool stable, bool constant_time_size >
|
||||
void run_pairing_heap_test( void )
|
||||
{
|
||||
typedef boost::heap::pairing_heap<int, boost::heap::stable<stable>,
|
||||
boost::heap::compare<std::less<int> >,
|
||||
boost::heap::allocator<std::allocator<int> >,
|
||||
boost::heap::constant_time_size<constant_time_size> > pri_queue;
|
||||
typedef boost::heap::pairing_heap< int,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::compare< std::less< int > >,
|
||||
boost::heap::allocator< std::allocator< int > >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MutablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MergablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MutablePriorityQueue< pri_queue >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MergablePriorityQueue< pri_queue >));
|
||||
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
|
||||
run_merge_tests<pri_queue>();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
run_mutable_heap_tests<pri_queue >();
|
||||
run_mutable_heap_tests< pri_queue >();
|
||||
|
||||
run_ordered_iterator_tests<pri_queue>();
|
||||
run_ordered_iterator_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::pairing_heap<q_tester, boost::heap::stable<stable>,
|
||||
boost::heap::constant_time_size<constant_time_size>
|
||||
> stable_pri_queue;
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
if ( stable ) {
|
||||
typedef boost::heap::pairing_heap< q_tester,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
stable_pri_queue;
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pairing_heap_test )
|
||||
{
|
||||
run_pairing_heap_test<false, false>();
|
||||
run_pairing_heap_test<false, true>();
|
||||
run_pairing_heap_test<true, false>();
|
||||
run_pairing_heap_test<true, true>();
|
||||
run_pairing_heap_test< false, false >();
|
||||
run_pairing_heap_test< false, true >();
|
||||
run_pairing_heap_test< true, false >();
|
||||
run_pairing_heap_test< true, true >();
|
||||
|
||||
RUN_EMPLACE_TEST(pairing_heap);
|
||||
RUN_EMPLACE_TEST( pairing_heap );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pairing_heap_compare_lookup_test )
|
||||
{
|
||||
typedef boost::heap::pairing_heap<int,
|
||||
boost::heap::compare<less_with_T>,
|
||||
boost::heap::allocator<std::allocator<int> > > pri_queue;
|
||||
run_common_heap_tests<pri_queue>();
|
||||
typedef boost::heap::
|
||||
pairing_heap< int, boost::heap::compare< less_with_T >, boost::heap::allocator< std::allocator< int > > >
|
||||
pri_queue;
|
||||
run_common_heap_tests< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( pairing_heap_leak_test )
|
||||
{
|
||||
typedef boost::heap::pairing_heap<boost::shared_ptr<int> > pri_queue;
|
||||
run_leak_check_test<pri_queue>();
|
||||
typedef boost::heap::pairing_heap< boost::shared_ptr< int > > pri_queue;
|
||||
run_leak_check_test< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -12,36 +12,36 @@
|
||||
#include <boost/heap/priority_queue.hpp>
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
#include "merge_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
|
||||
template <bool stable>
|
||||
void run_common_priority_queue_tests(void)
|
||||
template < bool stable >
|
||||
void run_common_priority_queue_tests( void )
|
||||
{
|
||||
typedef boost::heap::priority_queue<int, boost::heap::stable<stable> > pri_queue;
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<pri_queue>));
|
||||
typedef boost::heap::priority_queue< int, boost::heap::stable< stable > > pri_queue;
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::PriorityQueue< pri_queue >));
|
||||
|
||||
run_concept_check<pri_queue>();
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_merge_tests<pri_queue>();
|
||||
run_concept_check< pri_queue >();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::priority_queue<q_tester, boost::heap::stable<stable> > stable_pri_queue;
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
if ( stable ) {
|
||||
typedef boost::heap::priority_queue< q_tester, boost::heap::stable< stable > > stable_pri_queue;
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( std_pri_queue_test )
|
||||
{
|
||||
run_common_priority_queue_tests<false>();
|
||||
run_common_priority_queue_tests<true>();
|
||||
run_common_priority_queue_tests< false >();
|
||||
run_common_priority_queue_tests< true >();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( std_pri_queue_leak_test )
|
||||
{
|
||||
typedef boost::heap::priority_queue<boost::shared_ptr<int> > pri_queue;
|
||||
run_leak_check_test<pri_queue>();
|
||||
typedef boost::heap::priority_queue< boost::shared_ptr< int > > pri_queue;
|
||||
run_leak_check_test< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -9,14 +9,15 @@
|
||||
* \author Andrey Semashev
|
||||
* \date 28.10.2018
|
||||
*
|
||||
* \brief This file contains a test boilerplate for checking that every public header is self-contained and does not have any missing #includes.
|
||||
* \brief This file contains a test boilerplate for checking that every public header is self-contained and does not
|
||||
* have any missing #includes.
|
||||
*/
|
||||
|
||||
#define BOOST_HEAP_TEST_INCLUDE_HEADER() <boost/heap/BOOST_HEAP_TEST_HEADER>
|
||||
|
||||
#include BOOST_HEAP_TEST_INCLUDE_HEADER()
|
||||
|
||||
int main(int, char*[])
|
||||
int main( int, char*[] )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,107 +14,112 @@
|
||||
#include <boost/heap/skew_heap.hpp>
|
||||
|
||||
#include "common_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "merge_heap_tests.hpp"
|
||||
#include "mutable_heap_tests.hpp"
|
||||
#include "stable_heap_tests.hpp"
|
||||
|
||||
template <bool stable, bool constant_time_size, bool store_parent_pointer>
|
||||
void run_skew_heap_test(void)
|
||||
template < bool stable, bool constant_time_size, bool store_parent_pointer >
|
||||
void run_skew_heap_test( void )
|
||||
{
|
||||
typedef boost::heap::skew_heap<int, boost::heap::stable<stable>,
|
||||
boost::heap::compare<std::less<int> >,
|
||||
boost::heap::allocator<std::allocator<int> >,
|
||||
boost::heap::constant_time_size<constant_time_size>,
|
||||
boost::heap::store_parent_pointer<store_parent_pointer>
|
||||
> pri_queue;
|
||||
typedef boost::heap::skew_heap< int,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::compare< std::less< int > >,
|
||||
boost::heap::allocator< std::allocator< int > >,
|
||||
boost::heap::constant_time_size< constant_time_size >,
|
||||
boost::heap::store_parent_pointer< store_parent_pointer > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MergablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::PriorityQueue< pri_queue >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MergablePriorityQueue< pri_queue >));
|
||||
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
|
||||
run_merge_tests<pri_queue>();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
pri_queue_test_ordered_iterators<pri_queue>();
|
||||
pri_queue_test_ordered_iterators< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::skew_heap<q_tester, boost::heap::stable<stable>,
|
||||
boost::heap::constant_time_size<constant_time_size>,
|
||||
boost::heap::store_parent_pointer<store_parent_pointer>
|
||||
> stable_pri_queue;
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
if ( stable ) {
|
||||
typedef boost::heap::skew_heap< q_tester,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::constant_time_size< constant_time_size >,
|
||||
boost::heap::store_parent_pointer< store_parent_pointer > >
|
||||
stable_pri_queue;
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
template <bool stable, bool constant_time_size>
|
||||
void run_skew_heap_mutable_test(void)
|
||||
template < bool stable, bool constant_time_size >
|
||||
void run_skew_heap_mutable_test( void )
|
||||
{
|
||||
typedef boost::heap::skew_heap<int, boost::heap::stable<stable>, boost::heap::mutable_<true>,
|
||||
boost::heap::compare<std::less<int> >,
|
||||
boost::heap::allocator<std::allocator<int> >,
|
||||
boost::heap::constant_time_size<constant_time_size>
|
||||
> pri_queue;
|
||||
typedef boost::heap::skew_heap< int,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::mutable_< true >,
|
||||
boost::heap::compare< std::less< int > >,
|
||||
boost::heap::allocator< std::allocator< int > >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
pri_queue;
|
||||
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MutablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT((boost::heap::MergablePriorityQueue<pri_queue>));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MutablePriorityQueue< pri_queue >));
|
||||
BOOST_CONCEPT_ASSERT( (boost::heap::MergablePriorityQueue< pri_queue >));
|
||||
|
||||
run_common_heap_tests<pri_queue>();
|
||||
run_iterator_heap_tests<pri_queue>();
|
||||
run_copyable_heap_tests<pri_queue>();
|
||||
run_moveable_heap_tests<pri_queue>();
|
||||
run_common_heap_tests< pri_queue >();
|
||||
run_iterator_heap_tests< pri_queue >();
|
||||
run_copyable_heap_tests< pri_queue >();
|
||||
run_moveable_heap_tests< pri_queue >();
|
||||
|
||||
run_merge_tests<pri_queue>();
|
||||
run_merge_tests< pri_queue >();
|
||||
|
||||
run_mutable_heap_tests<pri_queue >();
|
||||
run_mutable_heap_tests< pri_queue >();
|
||||
|
||||
run_ordered_iterator_tests<pri_queue>();
|
||||
run_ordered_iterator_tests< pri_queue >();
|
||||
|
||||
if (stable) {
|
||||
typedef boost::heap::skew_heap<q_tester, boost::heap::stable<stable>, boost::heap::mutable_<true>,
|
||||
boost::heap::constant_time_size<constant_time_size>
|
||||
> stable_pri_queue;
|
||||
run_stable_heap_tests<stable_pri_queue>();
|
||||
if ( stable ) {
|
||||
typedef boost::heap::skew_heap< q_tester,
|
||||
boost::heap::stable< stable >,
|
||||
boost::heap::mutable_< true >,
|
||||
boost::heap::constant_time_size< constant_time_size > >
|
||||
stable_pri_queue;
|
||||
run_stable_heap_tests< stable_pri_queue >();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( skew_heap_test )
|
||||
{
|
||||
run_skew_heap_test<false, false, true>();
|
||||
run_skew_heap_test<false, true, true>();
|
||||
run_skew_heap_test<true, false, true>();
|
||||
run_skew_heap_test<true, true, true>();
|
||||
run_skew_heap_test< false, false, true >();
|
||||
run_skew_heap_test< false, true, true >();
|
||||
run_skew_heap_test< true, false, true >();
|
||||
run_skew_heap_test< true, true, true >();
|
||||
|
||||
run_skew_heap_test<false, false, false>();
|
||||
run_skew_heap_test<false, true, false>();
|
||||
run_skew_heap_test<true, false, false>();
|
||||
run_skew_heap_test<true, true, false>();
|
||||
run_skew_heap_test< false, false, false >();
|
||||
run_skew_heap_test< false, true, false >();
|
||||
run_skew_heap_test< true, false, false >();
|
||||
run_skew_heap_test< true, true, false >();
|
||||
|
||||
RUN_EMPLACE_TEST(skew_heap);
|
||||
RUN_EMPLACE_TEST( skew_heap );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( skew_heap_mutable_test )
|
||||
{
|
||||
run_skew_heap_mutable_test<false, false>();
|
||||
run_skew_heap_mutable_test<false, true>();
|
||||
run_skew_heap_mutable_test<true, false>();
|
||||
run_skew_heap_mutable_test<true, true>();
|
||||
run_skew_heap_mutable_test< false, false >();
|
||||
run_skew_heap_mutable_test< false, true >();
|
||||
run_skew_heap_mutable_test< true, false >();
|
||||
run_skew_heap_mutable_test< true, true >();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( skew_heap_compare_lookup_test )
|
||||
{
|
||||
typedef boost::heap::skew_heap<int,
|
||||
boost::heap::compare<less_with_T>,
|
||||
boost::heap::allocator<std::allocator<int> > > pri_queue;
|
||||
run_common_heap_tests<pri_queue>();
|
||||
typedef boost::heap::skew_heap< int, boost::heap::compare< less_with_T >, boost::heap::allocator< std::allocator< int > > >
|
||||
pri_queue;
|
||||
run_common_heap_tests< pri_queue >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( skew_heap_leak_test )
|
||||
{
|
||||
typedef boost::heap::skew_heap<boost::shared_ptr<int> > pri_queue;
|
||||
run_leak_check_test<pri_queue>();
|
||||
typedef boost::heap::skew_heap< boost::shared_ptr< int > > pri_queue;
|
||||
run_leak_check_test< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -6,94 +6,94 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include "common_heap_tests.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
struct q_tester
|
||||
{
|
||||
q_tester(int i = 0, int j = 0):
|
||||
value(i), id(j)
|
||||
q_tester( int i = 0, int j = 0 ) :
|
||||
value( i ),
|
||||
id( j )
|
||||
{}
|
||||
|
||||
bool operator< (q_tester const & rhs) const
|
||||
bool operator<( q_tester const& rhs ) const
|
||||
{
|
||||
return value < rhs.value;
|
||||
}
|
||||
|
||||
bool operator> (q_tester const & rhs) const
|
||||
bool operator>( q_tester const& rhs ) const
|
||||
{
|
||||
return value > rhs.value;
|
||||
}
|
||||
|
||||
bool operator== (q_tester const & rhs) const
|
||||
bool operator==( q_tester const& rhs ) const
|
||||
{
|
||||
return (value == rhs.value) && (id == rhs.id);
|
||||
return ( value == rhs.value ) && ( id == rhs.id );
|
||||
}
|
||||
|
||||
int value;
|
||||
int id;
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& out, q_tester const & t)
|
||||
std::ostream& operator<<( std::ostream& out, q_tester const& t )
|
||||
{
|
||||
out << "[" << t.value << " " << t.id << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
typedef std::vector<q_tester> stable_test_data;
|
||||
typedef std::vector< q_tester > stable_test_data;
|
||||
|
||||
stable_test_data make_stable_test_data(int size, int same_count = 3,
|
||||
int offset = 0, int strive = 1)
|
||||
stable_test_data make_stable_test_data( int size, int same_count = 3, int offset = 0, int strive = 1 )
|
||||
{
|
||||
stable_test_data ret;
|
||||
|
||||
for (int i = 0; i != size; ++i)
|
||||
for (int j = 0; j != same_count; ++j)
|
||||
ret.push_back(q_tester(i * strive + offset, j));
|
||||
for ( int i = 0; i != size; ++i )
|
||||
for ( int j = 0; j != same_count; ++j )
|
||||
ret.push_back( q_tester( i * strive + offset, j ) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct compare_by_id
|
||||
{
|
||||
bool operator()(q_tester const & lhs, q_tester const & rhs)
|
||||
bool operator()( q_tester const& lhs, q_tester const& rhs )
|
||||
{
|
||||
return lhs.id > rhs.id;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_stable_test_sequential_push(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_stable_test_sequential_push( void )
|
||||
{
|
||||
stable_test_data data = make_stable_test_data(test_size);
|
||||
stable_test_data data = make_stable_test_data( test_size );
|
||||
|
||||
pri_queue q;
|
||||
fill_q(q, data);
|
||||
std::stable_sort(data.begin(), data.end(), compare_by_id());
|
||||
std::stable_sort(data.begin(), data.end(), std::less<q_tester>());
|
||||
check_q(q, data);
|
||||
fill_q( q, data );
|
||||
std::stable_sort( data.begin(), data.end(), compare_by_id() );
|
||||
std::stable_sort( data.begin(), data.end(), std::less< q_tester >() );
|
||||
check_q( q, data );
|
||||
}
|
||||
|
||||
template <typename pri_queue>
|
||||
void pri_queue_stable_test_sequential_reverse_push(void)
|
||||
template < typename pri_queue >
|
||||
void pri_queue_stable_test_sequential_reverse_push( void )
|
||||
{
|
||||
stable_test_data data = make_stable_test_data(test_size);
|
||||
pri_queue q;
|
||||
stable_test_data push_data(data);
|
||||
stable_test_data data = make_stable_test_data( test_size );
|
||||
pri_queue q;
|
||||
stable_test_data push_data( data );
|
||||
|
||||
std::stable_sort(push_data.begin(), push_data.end(), std::greater<q_tester>());
|
||||
std::stable_sort( push_data.begin(), push_data.end(), std::greater< q_tester >() );
|
||||
|
||||
fill_q(q, push_data);
|
||||
fill_q( q, push_data );
|
||||
|
||||
std::stable_sort(data.begin(), data.end(), compare_by_id());
|
||||
std::stable_sort(data.begin(), data.end(), std::less<q_tester>());
|
||||
std::stable_sort( data.begin(), data.end(), compare_by_id() );
|
||||
std::stable_sort( data.begin(), data.end(), std::less< q_tester >() );
|
||||
|
||||
check_q(q, data);
|
||||
check_q( q, data );
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void run_stable_heap_tests(void)
|
||||
template < typename pri_queue >
|
||||
void run_stable_heap_tests( void )
|
||||
{
|
||||
pri_queue_stable_test_sequential_push<pri_queue>();
|
||||
pri_queue_stable_test_sequential_reverse_push<pri_queue>();
|
||||
pri_queue_stable_test_sequential_push< pri_queue >();
|
||||
pri_queue_stable_test_sequential_reverse_push< pri_queue >();
|
||||
}
|
||||
|
||||
@@ -9,269 +9,269 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include "high_resolution_timer.hpp"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <boost/heap/heap_merge.hpp>
|
||||
|
||||
#if defined(__GNUC__) && (!defined __INTEL_COMPILER)
|
||||
#define no_inline __attribute__ ((noinline))
|
||||
#if defined( __GNUC__ ) && ( !defined __INTEL_COMPILER )
|
||||
# define no_inline __attribute__( ( noinline ) )
|
||||
#else
|
||||
#define no_inline
|
||||
# define no_inline
|
||||
#endif
|
||||
|
||||
typedef std::vector<int> test_data;
|
||||
typedef std::vector< int > test_data;
|
||||
|
||||
const int num_benchmarks = 1;
|
||||
|
||||
inline test_data make_sequential_test_data(int size)
|
||||
inline test_data make_sequential_test_data( int size )
|
||||
{
|
||||
test_data v(size);
|
||||
for (int i = 0; i != size; ++i)
|
||||
v[i] = i;
|
||||
test_data v( size );
|
||||
for ( int i = 0; i != size; ++i )
|
||||
v[ i ] = i;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline test_data make_test_data(int size)
|
||||
inline test_data make_test_data( int size )
|
||||
{
|
||||
test_data v = make_sequential_test_data(size);
|
||||
std::random_shuffle(v.begin(), v.end());
|
||||
test_data v = make_sequential_test_data( size );
|
||||
std::random_shuffle( v.begin(), v.end() );
|
||||
return v;
|
||||
}
|
||||
|
||||
const int max_data = 20;
|
||||
|
||||
test_data const & get_data(int index)
|
||||
test_data const& get_data( int index )
|
||||
{
|
||||
static std::vector <test_data> data;
|
||||
if (data.empty())
|
||||
for (int i = 0; i != num_benchmarks; ++i)
|
||||
data.push_back(make_test_data((1<<(max_data+1))+1024));
|
||||
static std::vector< test_data > data;
|
||||
if ( data.empty() )
|
||||
for ( int i = 0; i != num_benchmarks; ++i )
|
||||
data.push_back( make_test_data( ( 1 << ( max_data + 1 ) ) + 1024 ) );
|
||||
|
||||
return data[index];
|
||||
return data[ index ];
|
||||
}
|
||||
|
||||
|
||||
#define DEFINE_BENCHMARKS_SELECTOR(SUFFIX) \
|
||||
struct make_##SUFFIX \
|
||||
{ \
|
||||
template <typename heap> \
|
||||
struct rebind { \
|
||||
typedef run_##SUFFIX<heap> type; \
|
||||
}; \
|
||||
};
|
||||
#define DEFINE_BENCHMARKS_SELECTOR( SUFFIX ) \
|
||||
struct make_##SUFFIX \
|
||||
{ \
|
||||
template < typename heap > \
|
||||
struct rebind \
|
||||
{ \
|
||||
typedef run_##SUFFIX< heap > type; \
|
||||
}; \
|
||||
};
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
void fill_heap(pri_queue & q, int index, int size, int offset = 0)
|
||||
template < typename pri_queue >
|
||||
void fill_heap( pri_queue& q, int index, int size, int offset = 0 )
|
||||
{
|
||||
test_data const & data = get_data(index);
|
||||
test_data const& data = get_data( index );
|
||||
|
||||
for (int i = 0; i != size + 1; ++i) {
|
||||
q.push(data[i]);
|
||||
for ( int i = 0; i != size + 1; ++i ) {
|
||||
q.push( data[ i ] );
|
||||
int top = q.top();
|
||||
q.pop();
|
||||
q.push(top);
|
||||
q.push( top );
|
||||
}
|
||||
}
|
||||
|
||||
template <typename pri_queue,
|
||||
typename handle_container
|
||||
>
|
||||
void fill_heap_with_handles(pri_queue & q, handle_container & handles, int index, int size, int offset = 0)
|
||||
template < typename pri_queue, typename handle_container >
|
||||
void fill_heap_with_handles( pri_queue& q, handle_container& handles, int index, int size, int offset = 0 )
|
||||
{
|
||||
test_data const & data = get_data(index);
|
||||
test_data const& data = get_data( index );
|
||||
|
||||
for (int i = 0; i != size + 1; ++i) {
|
||||
handles[i] = q.push(data[i]);
|
||||
for ( int i = 0; i != size + 1; ++i ) {
|
||||
handles[ i ] = q.push( data[ i ] );
|
||||
|
||||
if (i > 0) {
|
||||
typename pri_queue::handle_type last = handles[i-1];
|
||||
int val = *last;
|
||||
q.erase(last);
|
||||
handles[i-1] = q.push(val);
|
||||
if ( i > 0 ) {
|
||||
typename pri_queue::handle_type last = handles[ i - 1 ];
|
||||
int val = *last;
|
||||
q.erase( last );
|
||||
handles[ i - 1 ] = q.push( val );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct run_sequential_push
|
||||
{
|
||||
run_sequential_push(int size):
|
||||
size(size)
|
||||
run_sequential_push( int size ) :
|
||||
size( size )
|
||||
{}
|
||||
|
||||
void prepare(int index)
|
||||
void prepare( int index )
|
||||
{
|
||||
q.clear();
|
||||
fill_heap(q, index, size);
|
||||
fill_heap( q, index, size );
|
||||
}
|
||||
|
||||
no_inline void operator()(int index)
|
||||
no_inline void operator()( int index )
|
||||
{
|
||||
test_data const & data = get_data(index);
|
||||
test_data const& data = get_data( index );
|
||||
|
||||
for (int i = 0; i != 16; ++i)
|
||||
q.push(data[(1<<max_data) + i]);
|
||||
for ( int i = 0; i != 16; ++i )
|
||||
q.push( data[ ( 1 << max_data ) + i ] );
|
||||
}
|
||||
|
||||
pri_queue q;
|
||||
int size;
|
||||
int size;
|
||||
};
|
||||
|
||||
DEFINE_BENCHMARKS_SELECTOR(sequential_push)
|
||||
DEFINE_BENCHMARKS_SELECTOR( sequential_push )
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct run_sequential_pop
|
||||
{
|
||||
run_sequential_pop(int size):
|
||||
size(size)
|
||||
run_sequential_pop( int size ) :
|
||||
size( size )
|
||||
{}
|
||||
|
||||
void prepare(int index)
|
||||
void prepare( int index )
|
||||
{
|
||||
q.clear();
|
||||
fill_heap(q, index, size);
|
||||
fill_heap( q, index, size );
|
||||
}
|
||||
|
||||
no_inline void operator()(int index)
|
||||
no_inline void operator()( int index )
|
||||
{
|
||||
for (int i = 0; i != 16; ++i)
|
||||
for ( int i = 0; i != 16; ++i )
|
||||
q.pop();
|
||||
}
|
||||
|
||||
pri_queue q;
|
||||
int size;
|
||||
int size;
|
||||
};
|
||||
|
||||
DEFINE_BENCHMARKS_SELECTOR(sequential_pop)
|
||||
DEFINE_BENCHMARKS_SELECTOR( sequential_pop )
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct run_sequential_increase
|
||||
{
|
||||
run_sequential_increase(int size):
|
||||
size(size), handles(size)
|
||||
run_sequential_increase( int size ) :
|
||||
size( size ),
|
||||
handles( size )
|
||||
{}
|
||||
|
||||
void prepare(int index)
|
||||
void prepare( int index )
|
||||
{
|
||||
q.clear();
|
||||
fill_heap_with_handles(q, handles, index, size);
|
||||
fill_heap_with_handles( q, handles, index, size );
|
||||
}
|
||||
|
||||
no_inline void operator()(int index)
|
||||
no_inline void operator()( int index )
|
||||
{
|
||||
test_data const & data = get_data(index);
|
||||
for (int i = 0; i != 16; ++i)
|
||||
q.increase(handles[i], data[i] + (1<<max_data));
|
||||
test_data const& data = get_data( index );
|
||||
for ( int i = 0; i != 16; ++i )
|
||||
q.increase( handles[ i ], data[ i ] + ( 1 << max_data ) );
|
||||
}
|
||||
|
||||
pri_queue q;
|
||||
int size;
|
||||
std::vector<typename pri_queue::handle_type> handles;
|
||||
pri_queue q;
|
||||
int size;
|
||||
std::vector< typename pri_queue::handle_type > handles;
|
||||
};
|
||||
|
||||
DEFINE_BENCHMARKS_SELECTOR(sequential_increase)
|
||||
DEFINE_BENCHMARKS_SELECTOR( sequential_increase )
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct run_sequential_decrease
|
||||
{
|
||||
run_sequential_decrease(int size):
|
||||
size(size), handles(size)
|
||||
run_sequential_decrease( int size ) :
|
||||
size( size ),
|
||||
handles( size )
|
||||
{}
|
||||
|
||||
void prepare(int index)
|
||||
void prepare( int index )
|
||||
{
|
||||
q.clear();
|
||||
fill_heap_with_handles(q, handles, index, size);
|
||||
fill_heap_with_handles( q, handles, index, size );
|
||||
}
|
||||
|
||||
no_inline void operator()(int index)
|
||||
no_inline void operator()( int index )
|
||||
{
|
||||
test_data const & data = get_data(index);
|
||||
for (int i = 0; i != 16; ++i)
|
||||
q.decrease(handles[i], data[i] + (1<<max_data));
|
||||
test_data const& data = get_data( index );
|
||||
for ( int i = 0; i != 16; ++i )
|
||||
q.decrease( handles[ i ], data[ i ] + ( 1 << max_data ) );
|
||||
}
|
||||
|
||||
pri_queue q;
|
||||
int size;
|
||||
std::vector<typename pri_queue::handle_type> handles;
|
||||
pri_queue q;
|
||||
int size;
|
||||
std::vector< typename pri_queue::handle_type > handles;
|
||||
};
|
||||
|
||||
DEFINE_BENCHMARKS_SELECTOR(sequential_decrease)
|
||||
DEFINE_BENCHMARKS_SELECTOR( sequential_decrease )
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct run_merge_and_clear
|
||||
{
|
||||
run_merge_and_clear(int size):
|
||||
size(size)
|
||||
run_merge_and_clear( int size ) :
|
||||
size( size )
|
||||
{}
|
||||
|
||||
void prepare(int index)
|
||||
void prepare( int index )
|
||||
{
|
||||
q.clear();
|
||||
r.clear();
|
||||
|
||||
fill_heap(q, index, size);
|
||||
fill_heap(r, index, size, size);
|
||||
fill_heap( q, index, size );
|
||||
fill_heap( r, index, size, size );
|
||||
}
|
||||
|
||||
no_inline void operator()(int index)
|
||||
no_inline void operator()( int index )
|
||||
{
|
||||
boost::heap::heap_merge(q, r);
|
||||
boost::heap::heap_merge( q, r );
|
||||
}
|
||||
|
||||
pri_queue q, r;
|
||||
int size;
|
||||
int size;
|
||||
};
|
||||
|
||||
DEFINE_BENCHMARKS_SELECTOR(merge_and_clear)
|
||||
DEFINE_BENCHMARKS_SELECTOR( merge_and_clear )
|
||||
|
||||
template <typename pri_queue>
|
||||
template < typename pri_queue >
|
||||
struct run_equivalence
|
||||
{
|
||||
run_equivalence(int size):
|
||||
size(size)
|
||||
run_equivalence( int size ) :
|
||||
size( size )
|
||||
{}
|
||||
|
||||
void prepare(int index)
|
||||
void prepare( int index )
|
||||
{
|
||||
q.clear();
|
||||
r.clear();
|
||||
s.clear();
|
||||
|
||||
fill_heap(q, index, size);
|
||||
fill_heap(r, index, size, size);
|
||||
fill_heap(s, index, size);
|
||||
fill_heap( q, index, size );
|
||||
fill_heap( r, index, size, size );
|
||||
fill_heap( s, index, size );
|
||||
}
|
||||
|
||||
no_inline bool operator()(int index)
|
||||
no_inline bool operator()( int index )
|
||||
{
|
||||
return (q == r) ^ (q == s);
|
||||
return ( q == r ) ^ ( q == s );
|
||||
}
|
||||
|
||||
pri_queue q, r, s;
|
||||
int size;
|
||||
int size;
|
||||
};
|
||||
|
||||
DEFINE_BENCHMARKS_SELECTOR(equivalence)
|
||||
DEFINE_BENCHMARKS_SELECTOR( equivalence )
|
||||
|
||||
|
||||
template <typename benchmark>
|
||||
inline double run_benchmark(benchmark & b)
|
||||
template < typename benchmark >
|
||||
inline double run_benchmark( benchmark& b )
|
||||
{
|
||||
boost::high_resolution_timer timer;
|
||||
std::vector<double> results;
|
||||
std::vector< double > results;
|
||||
|
||||
for (int i = 0; i != num_benchmarks; ++i)
|
||||
{
|
||||
b.prepare(i);
|
||||
for ( int i = 0; i != num_benchmarks; ++i ) {
|
||||
b.prepare( i );
|
||||
timer.restart();
|
||||
b(i);
|
||||
b( i );
|
||||
double t = timer.elapsed();
|
||||
results.push_back(t);
|
||||
results.push_back( t );
|
||||
}
|
||||
|
||||
return results.at(results.size()/2); // median
|
||||
return results.at( results.size() / 2 ); // median
|
||||
}
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP)
|
||||
#define BOOST_HIGH_RESOLUTION_TIMER_HPP
|
||||
#if !defined( BOOST_HIGH_RESOLUTION_TIMER_HPP )
|
||||
# define BOOST_HIGH_RESOLUTION_TIMER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
|
||||
#if _POSIX_C_SOURCE >= 199309L
|
||||
# if _POSIX_C_SOURCE >= 199309L
|
||||
|
||||
#include "time.h"
|
||||
# include "time.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <limits>
|
||||
# include <limits>
|
||||
# include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -31,28 +31,27 @@ public:
|
||||
|
||||
void restart()
|
||||
{
|
||||
int status = clock_gettime(CLOCK_REALTIME, &start_time);
|
||||
int status = clock_gettime( CLOCK_REALTIME, &start_time );
|
||||
|
||||
if (status == -1)
|
||||
boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
|
||||
if ( status == -1 )
|
||||
boost::throw_exception( std::runtime_error( "Couldn't initialize start_time" ) );
|
||||
}
|
||||
|
||||
double elapsed() const // return elapsed time in seconds
|
||||
double elapsed() const // return elapsed time in seconds
|
||||
{
|
||||
struct timespec now;
|
||||
|
||||
int status = clock_gettime(CLOCK_REALTIME, &now);
|
||||
int status = clock_gettime( CLOCK_REALTIME, &now );
|
||||
|
||||
if (status == -1)
|
||||
boost::throw_exception(std::runtime_error("Couldn't get current time"));
|
||||
if ( status == -1 )
|
||||
boost::throw_exception( std::runtime_error( "Couldn't get current time" ) );
|
||||
|
||||
struct timespec diff;
|
||||
|
||||
double ret_sec = double(now.tv_sec - start_time.tv_sec);
|
||||
double ret_nsec = double(now.tv_nsec - start_time.tv_nsec);
|
||||
double ret_sec = double( now.tv_sec - start_time.tv_sec );
|
||||
double ret_nsec = double( now.tv_nsec - start_time.tv_nsec );
|
||||
|
||||
while (ret_nsec < 0)
|
||||
{
|
||||
while ( ret_nsec < 0 ) {
|
||||
ret_sec -= 1.0;
|
||||
ret_nsec += 1e9;
|
||||
}
|
||||
@@ -62,12 +61,12 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
||||
{
|
||||
return double((std::numeric_limits<double>::max)());
|
||||
return double( ( std::numeric_limits< double >::max )() );
|
||||
}
|
||||
|
||||
double elapsed_min() const // return minimum value for elapsed()
|
||||
double elapsed_min() const // return minimum value for elapsed()
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
@@ -78,9 +77,9 @@ private:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
# elif defined( __APPLE__ )
|
||||
|
||||
#import <mach/mach_time.h>
|
||||
# import <mach/mach_time.h>
|
||||
|
||||
|
||||
namespace boost {
|
||||
@@ -88,15 +87,15 @@ namespace boost {
|
||||
class high_resolution_timer
|
||||
{
|
||||
public:
|
||||
high_resolution_timer(void)
|
||||
high_resolution_timer( void )
|
||||
{
|
||||
mach_timebase_info_data_t info;
|
||||
|
||||
kern_return_t err = mach_timebase_info(&info);
|
||||
if (err)
|
||||
throw std::runtime_error("cannot create mach timebase info");
|
||||
kern_return_t err = mach_timebase_info( &info );
|
||||
if ( err )
|
||||
throw std::runtime_error( "cannot create mach timebase info" );
|
||||
|
||||
conversion_factor = (double)info.numer/(double)info.denom;
|
||||
conversion_factor = (double)info.numer / (double)info.denom;
|
||||
restart();
|
||||
}
|
||||
|
||||
@@ -105,36 +104,36 @@ public:
|
||||
start = mach_absolute_time();
|
||||
}
|
||||
|
||||
double elapsed() const // return elapsed time in seconds
|
||||
double elapsed() const // return elapsed time in seconds
|
||||
{
|
||||
uint64_t now = mach_absolute_time();
|
||||
double duration = double(now - start) * conversion_factor;
|
||||
uint64_t now = mach_absolute_time();
|
||||
double duration = double( now - start ) * conversion_factor;
|
||||
|
||||
return duration
|
||||
}
|
||||
|
||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
||||
{
|
||||
return double((std::numeric_limits<double>::max)());
|
||||
return double( ( std::numeric_limits< double >::max )() );
|
||||
}
|
||||
|
||||
double elapsed_min() const // return minimum value for elapsed()
|
||||
double elapsed_min() const // return minimum value for elapsed()
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t start;
|
||||
double conversion_factor;
|
||||
double conversion_factor;
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#elif defined(BOOST_WINDOWS)
|
||||
# elif defined( BOOST_WINDOWS )
|
||||
|
||||
#include <stdexcept>
|
||||
#include <limits>
|
||||
#include <windows.h>
|
||||
# include <limits>
|
||||
# include <stdexcept>
|
||||
# include <windows.h>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -151,36 +150,36 @@ public:
|
||||
high_resolution_timer()
|
||||
{
|
||||
start_time.QuadPart = 0;
|
||||
frequency.QuadPart = 0;
|
||||
frequency.QuadPart = 0;
|
||||
|
||||
if (!QueryPerformanceFrequency(&frequency))
|
||||
boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
|
||||
if ( !QueryPerformanceFrequency( &frequency ) )
|
||||
boost::throw_exception( std::runtime_error( "Couldn't acquire frequency" ) );
|
||||
|
||||
restart();
|
||||
}
|
||||
|
||||
void restart()
|
||||
{
|
||||
if (!QueryPerformanceCounter(&start_time))
|
||||
boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
|
||||
if ( !QueryPerformanceCounter( &start_time ) )
|
||||
boost::throw_exception( std::runtime_error( "Couldn't initialize start_time" ) );
|
||||
}
|
||||
|
||||
double elapsed() const // return elapsed time in seconds
|
||||
double elapsed() const // return elapsed time in seconds
|
||||
{
|
||||
LARGE_INTEGER now;
|
||||
if (!QueryPerformanceCounter(&now))
|
||||
boost::throw_exception(std::runtime_error("Couldn't get current time"));
|
||||
if ( !QueryPerformanceCounter( &now ) )
|
||||
boost::throw_exception( std::runtime_error( "Couldn't get current time" ) );
|
||||
|
||||
return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart;
|
||||
return double( now.QuadPart - start_time.QuadPart ) / frequency.QuadPart;
|
||||
}
|
||||
|
||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
||||
{
|
||||
return (double((std::numeric_limits<LONGLONG>::max)())
|
||||
- double(start_time.QuadPart)) / double(frequency.QuadPart);
|
||||
return ( double( ( std::numeric_limits< LONGLONG >::max )() ) - double( start_time.QuadPart ) )
|
||||
/ double( frequency.QuadPart );
|
||||
}
|
||||
|
||||
double elapsed_min() const // return minimum value for elapsed()
|
||||
double elapsed_min() const // return minimum value for elapsed()
|
||||
{
|
||||
return 1.0 / frequency.QuadPart;
|
||||
}
|
||||
@@ -192,17 +191,16 @@ private:
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
# else
|
||||
|
||||
// For other platforms, simply fall back to boost::timer
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
# include <boost/timer.hpp>
|
||||
|
||||
namespace boost {
|
||||
typedef boost::timer high_resolution_timer;
|
||||
}
|
||||
typedef boost::timer high_resolution_timer;
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP)
|
||||
# endif
|
||||
|
||||
#endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP)
|
||||
|
||||
@@ -6,132 +6,124 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
#include "../../../boost/heap/d_ary_heap.hpp"
|
||||
#include "../../../boost/heap/pairing_heap.hpp"
|
||||
#include "../../../boost/heap/fibonacci_heap.hpp"
|
||||
#include "../../../boost/heap/binomial_heap.hpp"
|
||||
#include "../../../boost/heap/d_ary_heap.hpp"
|
||||
#include "../../../boost/heap/fibonacci_heap.hpp"
|
||||
#include "../../../boost/heap/pairing_heap.hpp"
|
||||
#include "../../../boost/heap/skew_heap.hpp"
|
||||
|
||||
#include "heap_benchmarks.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename benchmark_selector>
|
||||
void run_benchmarks_immutable(void)
|
||||
template < typename benchmark_selector >
|
||||
void run_benchmarks_immutable( void )
|
||||
{
|
||||
for (int i = 4; i != max_data; ++i) {
|
||||
for (int j = 0; j != 8; ++j) {
|
||||
int size = 1<<i;
|
||||
if (j%4 == 1)
|
||||
size += 1<<(i-3);
|
||||
if (j%4 == 2)
|
||||
size += 1<<(i-2);
|
||||
if (j%4 == 3)
|
||||
size += (1<<(i-3)) + (1<<(i-2));
|
||||
if (j >= 4)
|
||||
size += (1<<(i-1));
|
||||
for ( int i = 4; i != max_data; ++i ) {
|
||||
for ( int j = 0; j != 8; ++j ) {
|
||||
int size = 1 << i;
|
||||
if ( j % 4 == 1 )
|
||||
size += 1 << ( i - 3 );
|
||||
if ( j % 4 == 2 )
|
||||
size += 1 << ( i - 2 );
|
||||
if ( j % 4 == 3 )
|
||||
size += ( 1 << ( i - 3 ) ) + ( 1 << ( i - 2 ) );
|
||||
if ( j >= 4 )
|
||||
size += ( 1 << ( i - 1 ) );
|
||||
|
||||
cout << size << "\t";
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<2> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 2 > > >::type benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<2>, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 2 >, boost::heap::mutable_< true > > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<4> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 4 > > >::type benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<4>, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 4 >, boost::heap::mutable_< true > > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<8> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 8 > > >::type benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<8>, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 8 >, boost::heap::mutable_< true > > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::binomial_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind< boost::heap::binomial_heap< long > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::fibonacci_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind< boost::heap::fibonacci_heap< long > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::pairing_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind< boost::heap::pairing_heap< long > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::skew_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef
|
||||
typename benchmark_selector::template rebind< boost::heap::skew_heap< long > >::type benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::skew_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef
|
||||
typename benchmark_selector::template rebind< boost::heap::skew_heap< long > >::type benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
cout << endl;
|
||||
@@ -139,84 +131,78 @@ void run_benchmarks_immutable(void)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename benchmark_selector>
|
||||
void run_benchmarks_mutable(void)
|
||||
template < typename benchmark_selector >
|
||||
void run_benchmarks_mutable( void )
|
||||
{
|
||||
for (int i = 4; i != max_data; ++i)
|
||||
{
|
||||
for (int j = 0; j != 8; ++j)
|
||||
{
|
||||
int size = 1<<i;
|
||||
if (j%4 == 1)
|
||||
size += 1<<(i-3);
|
||||
if (j%4 == 2)
|
||||
size += 1<<(i-2);
|
||||
if (j%4 == 3)
|
||||
size += (1<<(i-3)) + (1<<(i-2));
|
||||
if (j >= 4)
|
||||
size += (1<<(i-1));
|
||||
for ( int i = 4; i != max_data; ++i ) {
|
||||
for ( int j = 0; j != 8; ++j ) {
|
||||
int size = 1 << i;
|
||||
if ( j % 4 == 1 )
|
||||
size += 1 << ( i - 3 );
|
||||
if ( j % 4 == 2 )
|
||||
size += 1 << ( i - 2 );
|
||||
if ( j % 4 == 3 )
|
||||
size += ( 1 << ( i - 3 ) ) + ( 1 << ( i - 2 ) );
|
||||
if ( j >= 4 )
|
||||
size += ( 1 << ( i - 1 ) );
|
||||
|
||||
cout << size << "\t";
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<2>, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 2 >, boost::heap::mutable_< true > > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<4>, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 4 >, boost::heap::mutable_< true > > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::d_ary_heap<long, boost::heap::arity<8>, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::d_ary_heap< long, boost::heap::arity< 8 >, boost::heap::mutable_< true > > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::binomial_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind< boost::heap::binomial_heap< long > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::fibonacci_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind< boost::heap::fibonacci_heap< long > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::pairing_heap<long> >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind< boost::heap::pairing_heap< long > >::type
|
||||
benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
|
||||
{
|
||||
typedef typename benchmark_selector::
|
||||
template rebind<boost::heap::skew_heap<long, boost::heap::mutable_<true> > >
|
||||
::type benchmark_functor;
|
||||
benchmark_functor benchmark(size);
|
||||
double result = run_benchmark(benchmark);
|
||||
typedef typename benchmark_selector::template rebind<
|
||||
boost::heap::skew_heap< long, boost::heap::mutable_< true > > >::type benchmark_functor;
|
||||
benchmark_functor benchmark( size );
|
||||
double result = run_benchmark( benchmark );
|
||||
cout << result << '\t';
|
||||
}
|
||||
cout << endl;
|
||||
@@ -226,23 +212,23 @@ void run_benchmarks_mutable(void)
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << fixed << setprecision(12);
|
||||
cout << fixed << setprecision( 12 );
|
||||
|
||||
cout << "sequential push" << endl;
|
||||
run_benchmarks_immutable<make_sequential_push>();
|
||||
run_benchmarks_immutable< make_sequential_push >();
|
||||
|
||||
cout << endl << "sequential pop" << endl;
|
||||
run_benchmarks_immutable<make_sequential_pop>();
|
||||
run_benchmarks_immutable< make_sequential_pop >();
|
||||
|
||||
cout << endl << "sequential increase" << endl;
|
||||
run_benchmarks_mutable<make_sequential_increase>();
|
||||
run_benchmarks_mutable< make_sequential_increase >();
|
||||
|
||||
cout << endl << "sequential decrease" << endl;
|
||||
run_benchmarks_mutable<make_sequential_decrease>();
|
||||
run_benchmarks_mutable< make_sequential_decrease >();
|
||||
|
||||
cout << endl << "merge_and_clear" << endl;
|
||||
run_benchmarks_immutable<make_merge_and_clear>();
|
||||
run_benchmarks_immutable< make_merge_and_clear >();
|
||||
|
||||
cout << endl << "equivalence" << endl;
|
||||
run_benchmarks_immutable<make_equivalence>();
|
||||
run_benchmarks_immutable< make_equivalence >();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user