2
0
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:
Tim Blechmann
2023-12-07 17:27:32 +08:00
parent e312718a99
commit 7982bdc650
35 changed files with 3889 additions and 4010 deletions

View File

@@ -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%

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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

View File

@@ -6,8 +6,8 @@
Automatic redirection failed, please go to
<a href="../../doc/html/heap.html">../../doc/html/heap.html</a> &nbsp;<hr>
<p>&copy; 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>

View File

@@ -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 >();
}

View File

@@ -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

View File

@@ -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 >();
}

View File

@@ -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 >();
}

View File

@@ -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();
}

View File

@@ -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 > > >();
}

View File

@@ -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 >();
}

View File

@@ -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 >();
}

View File

@@ -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 >();
}

View File

@@ -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;
}

View File

@@ -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 >();
}

View File

@@ -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 >();
}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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 >();
}