Chris@16: // Chris@16: //======================================================================= Chris@16: // Copyright 1997, 1998, 1999, 2000 University of Notre Dame. Chris@16: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek 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: // Chris@16: // Chris@16: // Revision History: Chris@16: // 13 June 2001: Changed some names for clarity. (Jeremy Siek) Chris@16: // 01 April 2001: Modified to use new header. (JMaddock) Chris@16: // Chris@16: #ifndef BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP Chris@16: #define BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: template Chris@16: class bucket_sorter { Chris@16: public: Chris@16: typedef BucketType bucket_type; Chris@16: typedef ValueType value_type; Chris@16: typedef typename std::vector::size_type size_type; Chris@16: Chris@16: bucket_sorter(size_type _length, bucket_type _max_bucket, Chris@16: const Bucket& _bucket = Bucket(), Chris@16: const ValueIndexMap& _id = ValueIndexMap()) Chris@16: : head(_max_bucket, invalid_value()), Chris@16: next(_length, invalid_value()), Chris@16: prev(_length, invalid_value()), Chris@16: id_to_value(_length), Chris@16: bucket(_bucket), id(_id) { } Chris@16: Chris@16: void remove(const value_type& x) { Chris@16: const size_type i = get(id, x); Chris@16: const size_type& next_node = next[i]; Chris@16: const size_type& prev_node = prev[i]; Chris@16: Chris@16: //check if i is the end of the bucket list Chris@16: if ( next_node != invalid_value() ) Chris@16: prev[next_node] = prev_node; Chris@16: //check if i is the begin of the bucket list Chris@16: if ( prev_node != invalid_value() ) Chris@16: next[prev_node] = next_node; Chris@16: else //need update head of current bucket list Chris@16: head[ bucket[x] ] = next_node; Chris@16: } Chris@16: Chris@16: void push(const value_type& x) { Chris@16: id_to_value[get(id, x)] = x; Chris@16: (*this)[bucket[x]].push(x); Chris@16: } Chris@16: Chris@16: void update(const value_type& x) { Chris@16: remove(x); Chris@16: (*this)[bucket[x]].push(x); Chris@16: } Chris@16: // private: Chris@16: // with KCC, the nested stack class is having access problems Chris@16: // despite the friend decl. Chris@16: static size_type invalid_value() { Chris@16: return (std::numeric_limits::max)(); Chris@16: } Chris@16: Chris@16: typedef typename std::vector::iterator Iter; Chris@16: typedef typename std::vector::iterator IndexValueMap; Chris@16: Chris@16: public: Chris@16: friend class stack; Chris@16: Chris@16: class stack { Chris@16: public: Chris@16: stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v, Chris@16: const ValueIndexMap& _id) Chris@16: : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id) {} Chris@16: Chris@16: // Avoid using default arg for ValueIndexMap so that the default Chris@16: // constructor of the ValueIndexMap is not required if not used. Chris@16: stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v) Chris@16: : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v) {} Chris@16: Chris@16: void push(const value_type& x) { Chris@16: const size_type new_head = get(id, x); Chris@16: const size_type current = head[bucket_id]; Chris@16: if ( current != invalid_value() ) Chris@16: prev[current] = new_head; Chris@16: prev[new_head] = invalid_value(); Chris@16: next[new_head] = current; Chris@16: head[bucket_id] = new_head; Chris@16: } Chris@16: void pop() { Chris@16: size_type current = head[bucket_id]; Chris@16: size_type next_node = next[current]; Chris@16: head[bucket_id] = next_node; Chris@16: if ( next_node != invalid_value() ) Chris@16: prev[next_node] = invalid_value(); Chris@16: } Chris@16: value_type& top() { return value[ head[bucket_id] ]; } Chris@16: const value_type& top() const { return value[ head[bucket_id] ]; } Chris@16: bool empty() const { return head[bucket_id] == invalid_value(); } Chris@16: private: Chris@16: bucket_type bucket_id; Chris@16: Iter head; Chris@16: Iter next; Chris@16: Iter prev; Chris@16: IndexValueMap value; Chris@16: ValueIndexMap id; Chris@16: }; Chris@16: Chris@16: stack operator[](const bucket_type& i) { Chris@16: assert(i < head.size()); Chris@16: return stack(i, head.begin(), next.begin(), prev.begin(), Chris@16: id_to_value.begin(), id); Chris@16: } Chris@16: protected: Chris@16: std::vector head; Chris@16: std::vector next; Chris@16: std::vector prev; Chris@16: std::vector id_to_value; Chris@16: Bucket bucket; Chris@16: ValueIndexMap id; Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: #endif