File indexing completed on 2025-09-16 08:36:47
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_HEAP_DETAIL_ORDERED_ADAPTOR_ITERATOR_HPP
0010 #define BOOST_HEAP_DETAIL_ORDERED_ADAPTOR_ITERATOR_HPP
0011
0012 #include <limits>
0013
0014 #include <boost/assert.hpp>
0015 #include <boost/concept_check.hpp>
0016 #include <boost/heap/detail/tree_iterator.hpp>
0017 #include <boost/iterator/iterator_adaptor.hpp>
0018 #include <boost/iterator/iterator_facade.hpp>
0019
0020 namespace boost { namespace heap { namespace detail {
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 template < typename ValueType, typename InternalType, typename ContainerType, typename Alloc, typename ValueCompare, typename Dispatcher >
0036 class ordered_adaptor_iterator :
0037 public boost::iterator_facade<
0038 ordered_adaptor_iterator< ValueType, InternalType, ContainerType, Alloc, ValueCompare, Dispatcher >,
0039 ValueType,
0040 boost::forward_traversal_tag >,
0041 Dispatcher
0042 {
0043 friend class boost::iterator_core_access;
0044
0045 struct compare_by_heap_value : ValueCompare
0046 {
0047 const ContainerType* container;
0048
0049 compare_by_heap_value( const ContainerType* container, ValueCompare const& cmp ) :
0050 ValueCompare( cmp ),
0051 container( container )
0052 {}
0053
0054 bool operator()( size_t lhs, size_t rhs )
0055 {
0056 BOOST_ASSERT( lhs <= Dispatcher::max_index( container ) );
0057 BOOST_ASSERT( rhs <= Dispatcher::max_index( container ) );
0058 return ValueCompare::operator()( Dispatcher::get_internal_value( container, lhs ),
0059 Dispatcher::get_internal_value( container, rhs ) );
0060 }
0061 };
0062
0063 const ContainerType* container;
0064 size_t current_index;
0065
0066 public:
0067 ordered_adaptor_iterator( void ) :
0068 container( nullptr ),
0069 current_index( ( std::numeric_limits< size_t >::max )() ),
0070 unvisited_nodes( compare_by_heap_value( nullptr, ValueCompare() ) )
0071 {}
0072
0073 ordered_adaptor_iterator( const ContainerType* container, ValueCompare const& cmp ) :
0074 container( container ),
0075 current_index( container->size() ),
0076 unvisited_nodes( compare_by_heap_value( container, ValueCompare() ) )
0077 {}
0078
0079 ordered_adaptor_iterator( size_t initial_index, const ContainerType* container, ValueCompare const& cmp ) :
0080 container( container ),
0081 current_index( initial_index ),
0082 unvisited_nodes( compare_by_heap_value( container, cmp ) )
0083 {
0084 discover_nodes( initial_index );
0085 }
0086
0087 private:
0088 bool equal( ordered_adaptor_iterator const& rhs ) const
0089 {
0090 if ( current_index != rhs.current_index )
0091 return false;
0092
0093 if ( container != rhs.container )
0094 return false;
0095
0096 return true;
0097 }
0098
0099 void increment( void )
0100 {
0101 if ( unvisited_nodes.empty() )
0102 current_index = Dispatcher::max_index( container ) + 1;
0103 else {
0104 current_index = unvisited_nodes.top();
0105 unvisited_nodes.pop();
0106 discover_nodes( current_index );
0107 }
0108 }
0109
0110 ValueType const& dereference() const
0111 {
0112 BOOST_ASSERT( current_index <= Dispatcher::max_index( container ) );
0113 return Dispatcher::get_value( Dispatcher::get_internal_value( container, current_index ) );
0114 }
0115
0116 void discover_nodes( size_t index )
0117 {
0118 if ( Dispatcher::is_leaf( container, index ) )
0119 return;
0120
0121 std::pair< size_t, size_t > child_range = Dispatcher::get_child_nodes( container, index );
0122
0123 for ( size_t i = child_range.first; i <= child_range.second; ++i )
0124 unvisited_nodes.push( i );
0125 }
0126
0127 std::priority_queue< size_t,
0128 std::vector< size_t, typename boost::allocator_rebind< Alloc, size_t >::type >,
0129 compare_by_heap_value >
0130 unvisited_nodes;
0131 };
0132
0133
0134 }}}
0135
0136 #endif