sl@0: // sl@0: //======================================================================= sl@0: // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. sl@0: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: //======================================================================= sl@0: // sl@0: #ifndef BOOST_MUTABLE_QUEUE_HPP sl@0: #define BOOST_MUTABLE_QUEUE_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { sl@0: sl@0: // The mutable queue whose elements are indexed sl@0: // sl@0: // This adaptor provides a special kind of priority queue that has sl@0: // and update operation. This allows the ordering of the items to sl@0: // change. After the ordering criteria for item x changes, one must sl@0: // call the Q.update(x) sl@0: // sl@0: // In order to efficiently find x in the queue, a functor must be sl@0: // provided to map value_type to a unique ID, which the sl@0: // mutable_queue will then use to map to the location of the sl@0: // item. The ID's generated must be between 0 and N, where N is the sl@0: // value passed to the constructor of mutable_queue sl@0: sl@0: template , sl@0: class Comp = std::less, sl@0: class ID = identity_property_map > sl@0: class mutable_queue { sl@0: public: sl@0: typedef IndexedType value_type; sl@0: typedef typename RandomAccessContainer::size_type size_type; sl@0: protected: sl@0: typedef typename RandomAccessContainer::iterator iterator; sl@0: #if !defined BOOST_NO_STD_ITERATOR_TRAITS sl@0: typedef adstl::array_binary_tree_node Node; sl@0: #else sl@0: typedef adstl::array_binary_tree_node Node; sl@0: #endif sl@0: typedef adstl::compare_array_node Compare; sl@0: typedef std::vector IndexArray; sl@0: public: sl@0: typedef Compare value_compare; sl@0: typedef ID id_generator; sl@0: sl@0: mutable_queue(size_type n, const Comp& x, const ID& _id) sl@0: : index_array(n), comp(x), id(_id) { sl@0: c.reserve(n); sl@0: } sl@0: template sl@0: mutable_queue(ForwardIterator first, ForwardIterator last, sl@0: const Comp& x, const ID& _id) sl@0: : index_array(std::distance(first, last)), comp(x), id(_id) sl@0: { sl@0: while( first != last ) { sl@0: push(*first); sl@0: ++first; sl@0: } sl@0: } sl@0: sl@0: bool empty() const { return c.empty(); } sl@0: sl@0: void pop() { sl@0: value_type tmp = c.back(); sl@0: c.back() = c.front(); sl@0: c.front() = tmp; sl@0: sl@0: size_type id_f = get(id, c.back()); sl@0: size_type id_b = get(id, tmp); sl@0: size_type i = index_array[ id_b ]; sl@0: index_array[ id_b ] = index_array[ id_f ]; sl@0: index_array[ id_f ] = i; sl@0: sl@0: c.pop_back(); sl@0: Node node(c.begin(), c.end(), c.begin(), id); sl@0: down_heap(node, comp, index_array); sl@0: } sl@0: void push(const IndexedType& x) { sl@0: c.push_back(x); sl@0: /*set index-array*/ sl@0: index_array[ get(id, x) ] = c.size()-1; sl@0: Node node(c.begin(), c.end(), c.end() - 1, id); sl@0: up_heap(node, comp, index_array); sl@0: } sl@0: sl@0: void update(const IndexedType& x) { sl@0: size_type current_pos = index_array[ get(id, x) ]; sl@0: c[current_pos] = x; sl@0: sl@0: Node node(c.begin(), c.end(), c.begin()+current_pos, id); sl@0: update_heap(node, comp, index_array); sl@0: } sl@0: sl@0: value_type& front() { return c.front(); } sl@0: value_type& top() { return c.front(); } sl@0: sl@0: const value_type& front() const { return c.front(); } sl@0: const value_type& top() const { return c.front(); } sl@0: sl@0: size_type size() const { return c.size(); } sl@0: sl@0: void clear() { c.clear(); } sl@0: sl@0: #if 0 sl@0: // dwa 2003/7/11 - I don't know what compiler is supposed to sl@0: // be able to compile this, but is_heap is not standard!! sl@0: bool test() { sl@0: return std::is_heap(c.begin(), c.end(), Comp()); sl@0: } sl@0: #endif sl@0: sl@0: protected: sl@0: IndexArray index_array; sl@0: Compare comp; sl@0: RandomAccessContainer c; sl@0: ID id; sl@0: }; sl@0: sl@0: sl@0: } sl@0: sl@0: #endif // BOOST_MUTABLE_QUEUE_HPP