Chris@16: // boost heap: wrapper for stl heap Chris@16: // Chris@16: // Copyright (C) 2010 Tim Blechmann Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_HEAP_PRIORITY_QUEUE_HPP Chris@16: #define BOOST_HEAP_PRIORITY_QUEUE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@101: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@101: #pragma once Chris@101: #endif Chris@101: Chris@101: Chris@16: namespace boost { Chris@16: namespace heap { Chris@16: namespace detail { Chris@16: Chris@16: typedef parameter::parameters, Chris@16: boost::parameter::optional, Chris@16: boost::parameter::optional, Chris@16: boost::parameter::optional Chris@16: > priority_queue_signature; Chris@16: } Chris@16: Chris@16: /** Chris@16: * \class priority_queue Chris@16: * \brief priority queue, based on stl heap functions Chris@16: * Chris@16: * The priority_queue class is a wrapper for the stl heap functions.
Chris@16: * The template parameter T is the type to be managed by the container. Chris@16: * The user can specify additional options and if no options are provided default options are used. Chris@16: * Chris@16: * The container supports the following options: Chris@16: * - \c boost::heap::compare<>, defaults to \c compare > Chris@16: * - \c boost::heap::stable<>, defaults to \c stable Chris@16: * - \c boost::heap::stability_counter_type<>, defaults to \c stability_counter_type Chris@16: * - \c boost::heap::allocator<>, defaults to \c allocator > Chris@16: * Chris@16: */ Chris@16: #ifdef BOOST_DOXYGEN_INVOKED Chris@16: template Chris@16: #else Chris@16: template Chris@16: #endif Chris@16: class priority_queue: Chris@16: private detail::make_heap_base::type, false>::type Chris@16: { Chris@16: typedef detail::make_heap_base::type, false> heap_base_maker; Chris@16: Chris@16: typedef typename heap_base_maker::type super_t; Chris@16: typedef typename super_t::internal_type internal_type; Chris@16: typedef typename heap_base_maker::allocator_argument::template rebind::other internal_type_allocator; Chris@16: typedef std::vector container_type; Chris@16: Chris@16: template Chris@16: friend struct detail::heap_merge_emulate; Chris@16: Chris@16: container_type q_; Chris@16: Chris@16: #ifndef BOOST_DOXYGEN_INVOKED Chris@16: struct implementation_defined: Chris@16: detail::extract_allocator_types Chris@16: { Chris@16: typedef typename heap_base_maker::compare_argument value_compare; Chris@16: typedef detail::stable_heap_iterator iterator; Chris@16: typedef iterator const_iterator; Chris@16: typedef typename container_type::allocator_type allocator_type; Chris@16: }; Chris@16: #endif Chris@16: Chris@16: public: Chris@16: typedef T value_type; Chris@16: typedef typename implementation_defined::size_type size_type; Chris@16: typedef typename implementation_defined::difference_type difference_type; Chris@16: typedef typename implementation_defined::value_compare value_compare; Chris@16: typedef typename implementation_defined::allocator_type allocator_type; Chris@16: typedef typename implementation_defined::reference reference; Chris@16: typedef typename implementation_defined::const_reference const_reference; Chris@16: typedef typename implementation_defined::pointer pointer; Chris@16: typedef typename implementation_defined::const_pointer const_pointer; Chris@16: /** Chris@16: * \b Note: The iterator does not traverse the priority queue in order of the priorities. Chris@16: * */ Chris@16: typedef typename implementation_defined::iterator iterator; Chris@16: typedef typename implementation_defined::const_iterator const_iterator; Chris@16: Chris@16: static const bool constant_time_size = true; Chris@16: static const bool has_ordered_iterators = false; Chris@16: static const bool is_mergable = false; Chris@16: static const bool is_stable = heap_base_maker::is_stable; Chris@16: static const bool has_reserve = true; Chris@16: Chris@16: /** Chris@16: * \b Effects: constructs an empty priority queue. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: explicit priority_queue(value_compare const & cmp = value_compare()): Chris@16: super_t(cmp) Chris@16: {} Chris@16: Chris@16: /** Chris@16: * \b Effects: copy-constructs priority queue from rhs. Chris@16: * Chris@16: * \b Complexity: Linear. Chris@16: * Chris@16: * */ Chris@16: priority_queue (priority_queue const & rhs): Chris@16: super_t(rhs), q_(rhs.q_) Chris@16: {} Chris@16: Chris@16: #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES Chris@16: /** Chris@16: * \b Effects: C++11-style move constructor. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * \b Note: Only available, if BOOST_NO_CXX11_RVALUE_REFERENCES is not defined Chris@16: * */ Chris@16: priority_queue(priority_queue && rhs): Chris@16: super_t(std::move(rhs)), q_(std::move(rhs.q_)) Chris@16: {} Chris@16: Chris@16: /** Chris@16: * \b Effects: C++11-style move assignment. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * \b Note: Only available, if BOOST_NO_CXX11_RVALUE_REFERENCES is not defined Chris@16: * */ Chris@16: priority_queue & operator=(priority_queue && rhs) Chris@16: { Chris@16: super_t::operator=(std::move(rhs)); Chris@16: q_ = std::move(rhs.q_); Chris@16: return *this; Chris@16: } Chris@16: #endif Chris@16: Chris@16: /** Chris@16: * \b Effects: Assigns priority queue from rhs. Chris@16: * Chris@16: * \b Complexity: Linear. Chris@16: * Chris@16: * */ Chris@16: priority_queue & operator=(priority_queue const & rhs) Chris@16: { Chris@16: static_cast(*this) = static_cast(rhs); Chris@16: q_ = rhs.q_; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns true, if the priority queue contains no elements. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: bool empty(void) const Chris@16: { Chris@16: return q_.empty(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns the number of elements contained in the priority queue. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: size_type size(void) const Chris@16: { Chris@16: return q_.size(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns the maximum number of elements the priority queue can contain. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: size_type max_size(void) const Chris@16: { Chris@16: return q_.max_size(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Removes all elements from the priority queue. Chris@16: * Chris@16: * \b Complexity: Linear. Chris@16: * Chris@16: * */ Chris@16: void clear(void) Chris@16: { Chris@16: q_.clear(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns allocator. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: allocator_type get_allocator(void) const Chris@16: { Chris@16: return q_.get_allocator(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns a const_reference to the maximum element. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: const_reference top(void) const Chris@16: { Chris@16: BOOST_ASSERT(!empty()); Chris@16: return super_t::get_value(q_.front()); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Adds a new element to the priority queue. Chris@16: * Chris@16: * \b Complexity: Logarithmic (amortized). Linear (worst case). Chris@16: * Chris@16: * */ Chris@16: void push(value_type const & v) Chris@16: { Chris@16: q_.push_back(super_t::make_node(v)); Chris@16: std::push_heap(q_.begin(), q_.end(), static_cast(*this)); Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@16: /** Chris@16: * \b Effects: Adds a new element to the priority queue. The element is directly constructed in-place. Chris@16: * Chris@16: * \b Complexity: Logarithmic (amortized). Linear (worst case). Chris@16: * Chris@16: * */ Chris@16: template Chris@16: void emplace(Args&&... args) Chris@16: { Chris@16: q_.emplace_back(super_t::make_node(std::forward(args)...)); Chris@16: std::push_heap(q_.begin(), q_.end(), static_cast(*this)); Chris@16: } Chris@16: #endif Chris@16: Chris@16: /** Chris@16: * \b Effects: Removes the top element from the priority queue. Chris@16: * Chris@16: * \b Complexity: Logarithmic (amortized). Linear (worst case). Chris@16: * Chris@16: * */ Chris@16: void pop(void) Chris@16: { Chris@16: BOOST_ASSERT(!empty()); Chris@16: std::pop_heap(q_.begin(), q_.end(), static_cast(*this)); Chris@16: q_.pop_back(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Swaps two priority queues. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: void swap(priority_queue & rhs) Chris@16: { Chris@16: super_t::swap(rhs); Chris@16: q_.swap(rhs.q_); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns an iterator to the first element contained in the priority queue. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: iterator begin(void) const Chris@16: { Chris@16: return iterator(q_.begin()); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Returns an iterator to the end of the priority queue. Chris@16: * Chris@16: * \b Complexity: Constant. Chris@16: * Chris@16: * */ Chris@16: iterator end(void) const Chris@16: { Chris@16: return iterator(q_.end()); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effects: Reserves memory for element_count elements Chris@16: * Chris@16: * \b Complexity: Linear. Chris@16: * Chris@16: * \b Node: Invalidates iterators Chris@16: * Chris@16: * */ Chris@16: void reserve(size_type element_count) Chris@16: { Chris@16: q_.reserve(element_count); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Effect: Returns the value_compare object used by the priority queue Chris@16: * Chris@16: * */ Chris@16: value_compare const & value_comp(void) const Chris@16: { Chris@16: return super_t::value_comp(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Returns: Element-wise comparison of heap data structures Chris@16: * Chris@16: * \b Requirement: the \c value_compare object of both heaps must match. Chris@16: * Chris@16: * */ Chris@16: template Chris@16: bool operator<(HeapType const & rhs) const Chris@16: { Chris@16: return detail::heap_compare(*this, rhs); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Returns: Element-wise comparison of heap data structures Chris@16: * Chris@16: * \b Requirement: the \c value_compare object of both heaps must match. Chris@16: * Chris@16: * */ Chris@16: template Chris@16: bool operator>(HeapType const & rhs) const Chris@16: { Chris@16: return detail::heap_compare(rhs, *this); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Returns: Element-wise comparison of heap data structures Chris@16: * Chris@16: * \b Requirement: the \c value_compare object of both heaps must match. Chris@16: * Chris@16: * */ Chris@16: template Chris@16: bool operator>=(HeapType const & rhs) const Chris@16: { Chris@16: return !operator<(rhs); Chris@16: } Chris@16: Chris@16: /** Chris@16: * \b Returns: Element-wise comparison of heap data structures Chris@16: * Chris@16: * \b Requirement: the \c value_compare object of both heaps must match. Chris@16: * Chris@16: * */ Chris@16: template Chris@16: bool operator<=(HeapType const & rhs) const Chris@16: { Chris@16: return !operator>(rhs); Chris@16: } Chris@16: Chris@16: /** \brief Equivalent comparison Chris@16: * \b Returns: True, if both heap data structures are equivalent. Chris@16: * Chris@16: * \b Requirement: the \c value_compare object of both heaps must match. Chris@16: * Chris@16: * */ Chris@16: template Chris@16: bool operator==(HeapType const & rhs) const Chris@16: { Chris@16: return detail::heap_equality(*this, rhs); Chris@16: } Chris@16: Chris@16: /** \brief Equivalent comparison Chris@16: * \b Returns: True, if both heap data structures are not equivalent. Chris@16: * Chris@16: * \b Requirement: the \c value_compare object of both heaps must match. Chris@16: * Chris@16: * */ Chris@16: template Chris@16: bool operator!=(HeapType const & rhs) const Chris@16: { Chris@16: return !(*this == rhs); Chris@16: } Chris@16: }; Chris@16: Chris@16: } /* namespace heap */ Chris@16: } /* namespace boost */ Chris@16: Chris@16: #endif /* BOOST_HEAP_PRIORITY_QUEUE_HPP */