priority_queue.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. // boost heap: wrapper for stl heap
  2. //
  3. // Copyright (C) 2010 Tim Blechmann
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_HEAP_PRIORITY_QUEUE_HPP
  9. #define BOOST_HEAP_PRIORITY_QUEUE_HPP
  10. #include <algorithm>
  11. #include <utility>
  12. #include <vector>
  13. #include <boost/assert.hpp>
  14. #include <boost/heap/detail/heap_comparison.hpp>
  15. #include <boost/heap/detail/stable_heap.hpp>
  16. #ifdef BOOST_HAS_PRAGMA_ONCE
  17. # pragma once
  18. #endif
  19. namespace boost { namespace heap {
  20. namespace detail {
  21. typedef parameter::parameters< boost::parameter::optional< tag::allocator >,
  22. boost::parameter::optional< tag::compare >,
  23. boost::parameter::optional< tag::stable >,
  24. boost::parameter::optional< tag::stability_counter_type > >
  25. priority_queue_signature;
  26. } // namespace detail
  27. /**
  28. * \class priority_queue
  29. * \brief priority queue, based on stl heap functions
  30. *
  31. * The priority_queue class is a wrapper for the stl heap functions.<br>
  32. * The template parameter T is the type to be managed by the container.
  33. * The user can specify additional options and if no options are provided default options are used.
  34. *
  35. * The container supports the following options:
  36. * - \c boost::heap::compare<>, defaults to \c compare<std::less<T> >
  37. * - \c boost::heap::stable<>, defaults to \c stable<false>
  38. * - \c boost::heap::stability_counter_type<>, defaults to \c stability_counter_type<boost::uintmax_t>
  39. * - \c boost::heap::allocator<>, defaults to \c allocator<std::allocator<T> >
  40. *
  41. */
  42. #ifdef BOOST_DOXYGEN_INVOKED
  43. template < class T, class... Options >
  44. #else
  45. template < typename T,
  46. class A0 = boost::parameter::void_,
  47. class A1 = boost::parameter::void_,
  48. class A2 = boost::parameter::void_,
  49. class A3 = boost::parameter::void_ >
  50. #endif
  51. class priority_queue :
  52. private detail::make_heap_base< T, typename detail::priority_queue_signature::bind< A0, A1, A2, A3 >::type, false >::type
  53. {
  54. typedef detail::make_heap_base< T, typename detail::priority_queue_signature::bind< A0, A1, A2, A3 >::type, false >
  55. heap_base_maker;
  56. typedef typename heap_base_maker::type super_t;
  57. typedef typename super_t::internal_type internal_type;
  58. typedef typename boost::allocator_rebind< typename heap_base_maker::allocator_argument, internal_type >::type
  59. internal_type_allocator;
  60. typedef std::vector< internal_type, internal_type_allocator > container_type;
  61. template < typename Heap1, typename Heap2 >
  62. friend struct detail::heap_merge_emulate;
  63. container_type q_;
  64. #ifndef BOOST_DOXYGEN_INVOKED
  65. struct implementation_defined : detail::extract_allocator_types< typename heap_base_maker::allocator_argument >
  66. {
  67. typedef typename heap_base_maker::compare_argument value_compare;
  68. typedef detail::stable_heap_iterator< T, typename container_type::const_iterator, super_t > iterator;
  69. typedef iterator const_iterator;
  70. typedef typename container_type::allocator_type allocator_type;
  71. };
  72. #endif
  73. public:
  74. typedef T value_type;
  75. typedef typename implementation_defined::size_type size_type;
  76. typedef typename implementation_defined::difference_type difference_type;
  77. typedef typename implementation_defined::value_compare value_compare;
  78. typedef typename implementation_defined::allocator_type allocator_type;
  79. typedef typename implementation_defined::reference reference;
  80. typedef typename implementation_defined::const_reference const_reference;
  81. typedef typename implementation_defined::pointer pointer;
  82. typedef typename implementation_defined::const_pointer const_pointer;
  83. /**
  84. * \b Note: The iterator does not traverse the priority queue in order of the priorities.
  85. * */
  86. typedef typename implementation_defined::iterator iterator;
  87. typedef typename implementation_defined::const_iterator const_iterator;
  88. static const bool constant_time_size = true;
  89. static const bool has_ordered_iterators = false;
  90. static const bool is_mergable = false;
  91. static const bool is_stable = heap_base_maker::is_stable;
  92. static const bool has_reserve = true;
  93. /**
  94. * \b Effects: constructs an empty priority queue.
  95. *
  96. * \b Complexity: Constant.
  97. *
  98. * */
  99. explicit priority_queue( value_compare const& cmp = value_compare() ) :
  100. super_t( cmp )
  101. {}
  102. /**
  103. * \b Effects: constructs an empty priority queue.
  104. *
  105. * \b Complexity: Constant.
  106. *
  107. * */
  108. explicit priority_queue( allocator_type const& alloc ) :
  109. q_( alloc )
  110. {}
  111. /**
  112. * \b Effects: copy-constructs priority queue from rhs.
  113. *
  114. * \b Complexity: Linear.
  115. *
  116. * */
  117. priority_queue( priority_queue const& rhs ) :
  118. super_t( rhs ),
  119. q_( rhs.q_ )
  120. {}
  121. /**
  122. * \b Effects: C++11-style move constructor.
  123. *
  124. * \b Complexity: Constant.
  125. *
  126. * */
  127. priority_queue( priority_queue&& rhs ) noexcept( std::is_nothrow_move_constructible< super_t >::value ) :
  128. super_t( std::move( rhs ) ),
  129. q_( std::move( rhs.q_ ) )
  130. {}
  131. /**
  132. * \b Effects: C++11-style move assignment.
  133. *
  134. * \b Complexity: Constant.
  135. *
  136. * */
  137. priority_queue& operator=( priority_queue&& rhs ) noexcept( std::is_nothrow_move_assignable< super_t >::value )
  138. {
  139. super_t::operator=( std::move( rhs ) );
  140. q_ = std::move( rhs.q_ );
  141. return *this;
  142. }
  143. /**
  144. * \b Effects: Assigns priority queue from rhs.
  145. *
  146. * \b Complexity: Linear.
  147. *
  148. * */
  149. priority_queue& operator=( priority_queue const& rhs )
  150. {
  151. static_cast< super_t& >( *this ) = static_cast< super_t const& >( rhs );
  152. q_ = rhs.q_;
  153. return *this;
  154. }
  155. /**
  156. * \b Effects: Returns true, if the priority queue contains no elements.
  157. *
  158. * \b Complexity: Constant.
  159. *
  160. * */
  161. bool empty( void ) const noexcept
  162. {
  163. return q_.empty();
  164. }
  165. /**
  166. * \b Effects: Returns the number of elements contained in the priority queue.
  167. *
  168. * \b Complexity: Constant.
  169. *
  170. * */
  171. size_type size( void ) const noexcept
  172. {
  173. return q_.size();
  174. }
  175. /**
  176. * \b Effects: Returns the maximum number of elements the priority queue can contain.
  177. *
  178. * \b Complexity: Constant.
  179. *
  180. * */
  181. size_type max_size( void ) const noexcept
  182. {
  183. return q_.max_size();
  184. }
  185. /**
  186. * \b Effects: Removes all elements from the priority queue.
  187. *
  188. * \b Complexity: Linear.
  189. *
  190. * */
  191. void clear( void ) noexcept
  192. {
  193. q_.clear();
  194. }
  195. /**
  196. * \b Effects: Returns allocator.
  197. *
  198. * \b Complexity: Constant.
  199. *
  200. * */
  201. allocator_type get_allocator( void ) const
  202. {
  203. return q_.get_allocator();
  204. }
  205. /**
  206. * \b Effects: Returns a const_reference to the maximum element.
  207. *
  208. * \b Complexity: Constant.
  209. *
  210. * */
  211. const_reference top( void ) const
  212. {
  213. BOOST_ASSERT( !empty() );
  214. return super_t::get_value( q_.front() );
  215. }
  216. /**
  217. * \b Effects: Adds a new element to the priority queue.
  218. *
  219. * \b Complexity: Logarithmic (amortized). Linear (worst case).
  220. *
  221. * */
  222. void push( value_type const& v )
  223. {
  224. q_.push_back( super_t::make_node( v ) );
  225. std::push_heap( q_.begin(), q_.end(), static_cast< super_t const& >( *this ) );
  226. }
  227. /**
  228. * \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place.
  229. *
  230. * \b Complexity: Logarithmic (amortized). Linear (worst case).
  231. *
  232. * */
  233. template < class... Args >
  234. void emplace( Args&&... args )
  235. {
  236. q_.emplace_back( super_t::make_node( std::forward< Args >( args )... ) );
  237. std::push_heap( q_.begin(), q_.end(), static_cast< super_t const& >( *this ) );
  238. }
  239. /**
  240. * \b Effects: Removes the top element from the priority queue.
  241. *
  242. * \b Complexity: Logarithmic (amortized). Linear (worst case).
  243. *
  244. * */
  245. void pop( void )
  246. {
  247. BOOST_ASSERT( !empty() );
  248. std::pop_heap( q_.begin(), q_.end(), static_cast< super_t const& >( *this ) );
  249. q_.pop_back();
  250. }
  251. /**
  252. * \b Effects: Swaps two priority queues.
  253. *
  254. * \b Complexity: Constant.
  255. *
  256. * */
  257. void swap( priority_queue& rhs ) noexcept( std::is_nothrow_move_constructible< super_t >::value
  258. && std::is_nothrow_move_assignable< super_t >::value )
  259. {
  260. super_t::swap( rhs );
  261. q_.swap( rhs.q_ );
  262. }
  263. /**
  264. * \b Effects: Returns an iterator to the first element contained in the priority queue.
  265. *
  266. * \b Complexity: Constant.
  267. *
  268. * */
  269. iterator begin( void ) const noexcept
  270. {
  271. return iterator( q_.begin() );
  272. }
  273. /**
  274. * \b Effects: Returns an iterator to the end of the priority queue.
  275. *
  276. * \b Complexity: Constant.
  277. *
  278. * */
  279. iterator end( void ) const noexcept
  280. {
  281. return iterator( q_.end() );
  282. }
  283. /**
  284. * \b Effects: Reserves memory for element_count elements
  285. *
  286. * \b Complexity: Linear.
  287. *
  288. * \b Node: Invalidates iterators
  289. *
  290. * */
  291. void reserve( size_type element_count )
  292. {
  293. q_.reserve( element_count );
  294. }
  295. /**
  296. * \b Effect: Returns the value_compare object used by the priority queue
  297. *
  298. * */
  299. value_compare const& value_comp( void ) const
  300. {
  301. return super_t::value_comp();
  302. }
  303. /**
  304. * \b Returns: Element-wise comparison of heap data structures
  305. *
  306. * \b Requirement: the \c value_compare object of both heaps must match.
  307. *
  308. * */
  309. template < typename HeapType >
  310. bool operator<( HeapType const& rhs ) const
  311. {
  312. return detail::heap_compare( *this, rhs );
  313. }
  314. /**
  315. * \b Returns: Element-wise comparison of heap data structures
  316. *
  317. * \b Requirement: the \c value_compare object of both heaps must match.
  318. *
  319. * */
  320. template < typename HeapType >
  321. bool operator>( HeapType const& rhs ) const
  322. {
  323. return detail::heap_compare( rhs, *this );
  324. }
  325. /**
  326. * \b Returns: Element-wise comparison of heap data structures
  327. *
  328. * \b Requirement: the \c value_compare object of both heaps must match.
  329. *
  330. * */
  331. template < typename HeapType >
  332. bool operator>=( HeapType const& rhs ) const
  333. {
  334. return !operator<( rhs );
  335. }
  336. /**
  337. * \b Returns: Element-wise comparison of heap data structures
  338. *
  339. * \b Requirement: the \c value_compare object of both heaps must match.
  340. *
  341. * */
  342. template < typename HeapType >
  343. bool operator<=( HeapType const& rhs ) const
  344. {
  345. return !operator>( rhs );
  346. }
  347. /** \brief Equivalent comparison
  348. * \b Returns: True, if both heap data structures are equivalent.
  349. *
  350. * \b Requirement: the \c value_compare object of both heaps must match.
  351. *
  352. * */
  353. template < typename HeapType >
  354. bool operator==( HeapType const& rhs ) const
  355. {
  356. return detail::heap_equality( *this, rhs );
  357. }
  358. /** \brief Equivalent comparison
  359. * \b Returns: True, if both heap data structures are not equivalent.
  360. *
  361. * \b Requirement: the \c value_compare object of both heaps must match.
  362. *
  363. * */
  364. template < typename HeapType >
  365. bool operator!=( HeapType const& rhs ) const
  366. {
  367. return !( *this == rhs );
  368. }
  369. };
  370. }} // namespace boost::heap
  371. #endif /* BOOST_HEAP_PRIORITY_QUEUE_HPP */