Chris@16
|
1 //
|
Chris@16
|
2 //=======================================================================
|
Chris@16
|
3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
Chris@16
|
4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
Chris@16
|
5 //
|
Chris@16
|
6 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
7 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
8 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //=======================================================================
|
Chris@16
|
10 //
|
Chris@16
|
11 //
|
Chris@16
|
12 // Revision History:
|
Chris@16
|
13 // 13 June 2001: Changed some names for clarity. (Jeremy Siek)
|
Chris@16
|
14 // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
|
Chris@16
|
15 //
|
Chris@16
|
16 #ifndef BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
|
Chris@16
|
17 #define BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
|
Chris@16
|
18
|
Chris@16
|
19 #include <vector>
|
Chris@16
|
20 #include <cassert>
|
Chris@16
|
21 #include <boost/limits.hpp>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost {
|
Chris@16
|
24
|
Chris@16
|
25 template <class BucketType, class ValueType, class Bucket,
|
Chris@16
|
26 class ValueIndexMap>
|
Chris@16
|
27 class bucket_sorter {
|
Chris@16
|
28 public:
|
Chris@16
|
29 typedef BucketType bucket_type;
|
Chris@16
|
30 typedef ValueType value_type;
|
Chris@16
|
31 typedef typename std::vector<value_type>::size_type size_type;
|
Chris@16
|
32
|
Chris@16
|
33 bucket_sorter(size_type _length, bucket_type _max_bucket,
|
Chris@16
|
34 const Bucket& _bucket = Bucket(),
|
Chris@16
|
35 const ValueIndexMap& _id = ValueIndexMap())
|
Chris@16
|
36 : head(_max_bucket, invalid_value()),
|
Chris@16
|
37 next(_length, invalid_value()),
|
Chris@16
|
38 prev(_length, invalid_value()),
|
Chris@16
|
39 id_to_value(_length),
|
Chris@16
|
40 bucket(_bucket), id(_id) { }
|
Chris@16
|
41
|
Chris@16
|
42 void remove(const value_type& x) {
|
Chris@16
|
43 const size_type i = get(id, x);
|
Chris@16
|
44 const size_type& next_node = next[i];
|
Chris@16
|
45 const size_type& prev_node = prev[i];
|
Chris@16
|
46
|
Chris@16
|
47 //check if i is the end of the bucket list
|
Chris@16
|
48 if ( next_node != invalid_value() )
|
Chris@16
|
49 prev[next_node] = prev_node;
|
Chris@16
|
50 //check if i is the begin of the bucket list
|
Chris@16
|
51 if ( prev_node != invalid_value() )
|
Chris@16
|
52 next[prev_node] = next_node;
|
Chris@16
|
53 else //need update head of current bucket list
|
Chris@16
|
54 head[ bucket[x] ] = next_node;
|
Chris@16
|
55 }
|
Chris@16
|
56
|
Chris@16
|
57 void push(const value_type& x) {
|
Chris@16
|
58 id_to_value[get(id, x)] = x;
|
Chris@16
|
59 (*this)[bucket[x]].push(x);
|
Chris@16
|
60 }
|
Chris@16
|
61
|
Chris@16
|
62 void update(const value_type& x) {
|
Chris@16
|
63 remove(x);
|
Chris@16
|
64 (*this)[bucket[x]].push(x);
|
Chris@16
|
65 }
|
Chris@16
|
66 // private:
|
Chris@16
|
67 // with KCC, the nested stack class is having access problems
|
Chris@16
|
68 // despite the friend decl.
|
Chris@16
|
69 static size_type invalid_value() {
|
Chris@16
|
70 return (std::numeric_limits<size_type>::max)();
|
Chris@16
|
71 }
|
Chris@16
|
72
|
Chris@16
|
73 typedef typename std::vector<size_type>::iterator Iter;
|
Chris@16
|
74 typedef typename std::vector<value_type>::iterator IndexValueMap;
|
Chris@16
|
75
|
Chris@16
|
76 public:
|
Chris@16
|
77 friend class stack;
|
Chris@16
|
78
|
Chris@16
|
79 class stack {
|
Chris@16
|
80 public:
|
Chris@16
|
81 stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v,
|
Chris@16
|
82 const ValueIndexMap& _id)
|
Chris@16
|
83 : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v), id(_id) {}
|
Chris@16
|
84
|
Chris@16
|
85 // Avoid using default arg for ValueIndexMap so that the default
|
Chris@16
|
86 // constructor of the ValueIndexMap is not required if not used.
|
Chris@16
|
87 stack(bucket_type _bucket_id, Iter h, Iter n, Iter p, IndexValueMap v)
|
Chris@16
|
88 : bucket_id(_bucket_id), head(h), next(n), prev(p), value(v) {}
|
Chris@16
|
89
|
Chris@16
|
90 void push(const value_type& x) {
|
Chris@16
|
91 const size_type new_head = get(id, x);
|
Chris@16
|
92 const size_type current = head[bucket_id];
|
Chris@16
|
93 if ( current != invalid_value() )
|
Chris@16
|
94 prev[current] = new_head;
|
Chris@16
|
95 prev[new_head] = invalid_value();
|
Chris@16
|
96 next[new_head] = current;
|
Chris@16
|
97 head[bucket_id] = new_head;
|
Chris@16
|
98 }
|
Chris@16
|
99 void pop() {
|
Chris@16
|
100 size_type current = head[bucket_id];
|
Chris@16
|
101 size_type next_node = next[current];
|
Chris@16
|
102 head[bucket_id] = next_node;
|
Chris@16
|
103 if ( next_node != invalid_value() )
|
Chris@16
|
104 prev[next_node] = invalid_value();
|
Chris@16
|
105 }
|
Chris@16
|
106 value_type& top() { return value[ head[bucket_id] ]; }
|
Chris@16
|
107 const value_type& top() const { return value[ head[bucket_id] ]; }
|
Chris@16
|
108 bool empty() const { return head[bucket_id] == invalid_value(); }
|
Chris@16
|
109 private:
|
Chris@16
|
110 bucket_type bucket_id;
|
Chris@16
|
111 Iter head;
|
Chris@16
|
112 Iter next;
|
Chris@16
|
113 Iter prev;
|
Chris@16
|
114 IndexValueMap value;
|
Chris@16
|
115 ValueIndexMap id;
|
Chris@16
|
116 };
|
Chris@16
|
117
|
Chris@16
|
118 stack operator[](const bucket_type& i) {
|
Chris@16
|
119 assert(i < head.size());
|
Chris@16
|
120 return stack(i, head.begin(), next.begin(), prev.begin(),
|
Chris@16
|
121 id_to_value.begin(), id);
|
Chris@16
|
122 }
|
Chris@16
|
123 protected:
|
Chris@16
|
124 std::vector<size_type> head;
|
Chris@16
|
125 std::vector<size_type> next;
|
Chris@16
|
126 std::vector<size_type> prev;
|
Chris@16
|
127 std::vector<value_type> id_to_value;
|
Chris@16
|
128 Bucket bucket;
|
Chris@16
|
129 ValueIndexMap id;
|
Chris@16
|
130 };
|
Chris@16
|
131
|
Chris@16
|
132 }
|
Chris@16
|
133
|
Chris@16
|
134 #endif
|