Chris@16
|
1 // Copyright 2005 The Trustees of Indiana University.
|
Chris@16
|
2
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
4 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6
|
Chris@16
|
7 // Authors: Jeremiah Willcock
|
Chris@16
|
8 // Douglas Gregor
|
Chris@16
|
9 // Andrew Lumsdaine
|
Chris@16
|
10
|
Chris@16
|
11 // Indexed properties -- used for CSR and CSR-like graphs
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_GRAPH_INDEXED_PROPERTIES_HPP
|
Chris@16
|
14 #define BOOST_GRAPH_INDEXED_PROPERTIES_HPP
|
Chris@16
|
15
|
Chris@16
|
16 #include <vector>
|
Chris@16
|
17 #include <utility>
|
Chris@16
|
18 #include <algorithm>
|
Chris@16
|
19 #include <climits>
|
Chris@16
|
20 #include <iterator>
|
Chris@16
|
21 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
22 #include <boost/graph/properties.hpp>
|
Chris@16
|
23 #include <boost/iterator/counting_iterator.hpp>
|
Chris@16
|
24 #include <boost/integer.hpp>
|
Chris@16
|
25 #include <boost/iterator/iterator_facade.hpp>
|
Chris@16
|
26 #include <boost/property_map/property_map.hpp>
|
Chris@16
|
27 #include <boost/mpl/if.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 namespace boost {
|
Chris@16
|
30 namespace detail {
|
Chris@16
|
31
|
Chris@16
|
32 template<typename Derived, typename Property, typename Descriptor, typename IndexMap>
|
Chris@16
|
33 class indexed_vertex_properties
|
Chris@16
|
34 {
|
Chris@16
|
35 public:
|
Chris@16
|
36 typedef no_property vertex_property_type;
|
Chris@16
|
37 typedef Property vertex_bundled;
|
Chris@16
|
38 typedef iterator_property_map<
|
Chris@16
|
39 typename std::vector<Property>::iterator,
|
Chris@16
|
40 IndexMap> vertex_map_type;
|
Chris@16
|
41 typedef iterator_property_map<
|
Chris@16
|
42 typename std::vector<Property>::const_iterator,
|
Chris@16
|
43 IndexMap> const_vertex_map_type;
|
Chris@16
|
44
|
Chris@16
|
45 // Directly access a vertex or edge bundle
|
Chris@16
|
46 Property& operator[](Descriptor v)
|
Chris@16
|
47 { return m_vertex_properties[get(vertex_index, derived(), v)]; }
|
Chris@16
|
48
|
Chris@16
|
49 const Property& operator[](Descriptor v) const
|
Chris@16
|
50 { return m_vertex_properties[get(vertex_index, derived(), v)]; }
|
Chris@16
|
51
|
Chris@16
|
52 vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) {
|
Chris@16
|
53 return vertex_map_type(m_vertex_properties.begin(), index_map);
|
Chris@16
|
54 }
|
Chris@16
|
55
|
Chris@16
|
56 const_vertex_map_type get_vertex_bundle(const IndexMap& index_map = IndexMap()) const {
|
Chris@16
|
57 return const_vertex_map_type(m_vertex_properties.begin(), index_map);
|
Chris@16
|
58 }
|
Chris@16
|
59
|
Chris@16
|
60 protected:
|
Chris@16
|
61 // Default-construct with no property values
|
Chris@16
|
62 indexed_vertex_properties() {}
|
Chris@16
|
63
|
Chris@16
|
64 // Initialize with n default-constructed property values
|
Chris@16
|
65 indexed_vertex_properties(std::size_t n) : m_vertex_properties(n) { }
|
Chris@16
|
66
|
Chris@16
|
67 public:
|
Chris@16
|
68 // Clear the properties vector
|
Chris@16
|
69 void clear()
|
Chris@16
|
70 {
|
Chris@16
|
71 m_vertex_properties.clear();
|
Chris@16
|
72 }
|
Chris@16
|
73
|
Chris@16
|
74 // Resize the properties vector
|
Chris@16
|
75 void resize(std::size_t n)
|
Chris@16
|
76 {
|
Chris@16
|
77 m_vertex_properties.resize(n);
|
Chris@16
|
78 }
|
Chris@16
|
79
|
Chris@16
|
80 // Reserve space in the vector of properties
|
Chris@16
|
81 void reserve(std::size_t n)
|
Chris@16
|
82 {
|
Chris@16
|
83 m_vertex_properties.reserve(n);
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 // Add a new property value to the back
|
Chris@16
|
87 void push_back(const Property& prop)
|
Chris@16
|
88 {
|
Chris@16
|
89 m_vertex_properties.push_back(prop);
|
Chris@16
|
90 }
|
Chris@16
|
91
|
Chris@16
|
92 // Write an element by raw index
|
Chris@16
|
93 void write_by_index(std::size_t idx, const Property& prop)
|
Chris@16
|
94 {
|
Chris@16
|
95 m_vertex_properties[idx] = prop;
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 // Access to the derived object
|
Chris@16
|
99 Derived& derived() { return *static_cast<Derived*>(this); }
|
Chris@16
|
100
|
Chris@16
|
101 const Derived& derived() const
|
Chris@16
|
102 { return *static_cast<const Derived*>(this); }
|
Chris@16
|
103
|
Chris@16
|
104 public: // should be private, but friend templates not portable
|
Chris@16
|
105 std::vector<Property> m_vertex_properties;
|
Chris@16
|
106 };
|
Chris@16
|
107
|
Chris@16
|
108 template<typename Derived, typename Descriptor, typename IndexMap>
|
Chris@16
|
109 class indexed_vertex_properties<Derived, void, Descriptor, IndexMap>
|
Chris@16
|
110 {
|
Chris@16
|
111 struct secret {};
|
Chris@16
|
112
|
Chris@16
|
113 public:
|
Chris@16
|
114 typedef no_property vertex_property_type;
|
Chris@16
|
115 typedef void vertex_bundled;
|
Chris@16
|
116 typedef secret vertex_map_type;
|
Chris@16
|
117 typedef secret const_vertex_map_type;
|
Chris@16
|
118
|
Chris@16
|
119 secret operator[](secret) { return secret(); }
|
Chris@16
|
120
|
Chris@16
|
121 vertex_map_type get_vertex_bundle() const {
|
Chris@16
|
122 return vertex_map_type();
|
Chris@16
|
123 }
|
Chris@16
|
124
|
Chris@16
|
125 protected:
|
Chris@16
|
126 // All operations do nothing.
|
Chris@16
|
127 indexed_vertex_properties() { }
|
Chris@16
|
128 indexed_vertex_properties(std::size_t) { }
|
Chris@16
|
129
|
Chris@16
|
130 public:
|
Chris@16
|
131 void clear() { }
|
Chris@16
|
132 void resize(std::size_t) { }
|
Chris@16
|
133 void reserve(std::size_t) { }
|
Chris@16
|
134 };
|
Chris@16
|
135
|
Chris@16
|
136 template<typename Derived, typename Property, typename Descriptor, typename IndexMap>
|
Chris@16
|
137 class indexed_edge_properties
|
Chris@16
|
138 {
|
Chris@16
|
139 public:
|
Chris@16
|
140 typedef no_property edge_property_type;
|
Chris@16
|
141 typedef Property edge_bundled;
|
Chris@16
|
142 typedef Property edge_push_back_type;
|
Chris@16
|
143 typedef iterator_property_map<
|
Chris@16
|
144 typename std::vector<Property>::iterator,
|
Chris@16
|
145 IndexMap> edge_map_type;
|
Chris@16
|
146 typedef iterator_property_map<
|
Chris@16
|
147 typename std::vector<Property>::const_iterator,
|
Chris@16
|
148 IndexMap> const_edge_map_type;
|
Chris@16
|
149
|
Chris@16
|
150 // Directly access a edge or edge bundle
|
Chris@16
|
151 Property& operator[](Descriptor v)
|
Chris@16
|
152 { return m_edge_properties[get(edge_index, derived(), v)]; }
|
Chris@16
|
153
|
Chris@16
|
154 const Property& operator[](Descriptor v) const
|
Chris@16
|
155 { return m_edge_properties[get(edge_index, derived(), v)]; }
|
Chris@16
|
156
|
Chris@16
|
157 edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) {
|
Chris@16
|
158 return edge_map_type(m_edge_properties.begin(), index_map);
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 const_edge_map_type get_edge_bundle(const IndexMap& index_map = IndexMap()) const {
|
Chris@16
|
162 return const_edge_map_type(m_edge_properties.begin(), index_map);
|
Chris@16
|
163 }
|
Chris@16
|
164
|
Chris@16
|
165 protected:
|
Chris@16
|
166 // Default-construct with no property values
|
Chris@16
|
167 indexed_edge_properties() {}
|
Chris@16
|
168
|
Chris@16
|
169 // Initialize with n default-constructed property values
|
Chris@16
|
170 indexed_edge_properties(std::size_t n) : m_edge_properties(n) { }
|
Chris@16
|
171
|
Chris@16
|
172 // Get the size of the properties vector
|
Chris@16
|
173 std::size_t size() const
|
Chris@16
|
174 {
|
Chris@16
|
175 return m_edge_properties.size();
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 // Clear the properties vector
|
Chris@16
|
179 void clear()
|
Chris@16
|
180 {
|
Chris@16
|
181 m_edge_properties.clear();
|
Chris@16
|
182 }
|
Chris@16
|
183
|
Chris@16
|
184 // Resize the properties vector
|
Chris@16
|
185 void resize(std::size_t n)
|
Chris@16
|
186 {
|
Chris@16
|
187 m_edge_properties.resize(n);
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 // Reserve space in the vector of properties
|
Chris@16
|
191 void reserve(std::size_t n)
|
Chris@16
|
192 {
|
Chris@16
|
193 m_edge_properties.reserve(n);
|
Chris@16
|
194 }
|
Chris@16
|
195
|
Chris@16
|
196 // Write an element by raw index
|
Chris@16
|
197 void write_by_index(std::size_t idx, const Property& prop)
|
Chris@16
|
198 {
|
Chris@16
|
199 m_edge_properties[idx] = prop;
|
Chris@16
|
200 }
|
Chris@16
|
201
|
Chris@16
|
202 public:
|
Chris@16
|
203 // Add a new property value to the back
|
Chris@16
|
204 void push_back(const Property& prop)
|
Chris@16
|
205 {
|
Chris@16
|
206 m_edge_properties.push_back(prop);
|
Chris@16
|
207 }
|
Chris@16
|
208
|
Chris@16
|
209 // Move range of properties backwards
|
Chris@16
|
210 void move_range(std::size_t src_begin, std::size_t src_end, std::size_t dest_begin) {
|
Chris@16
|
211 std::copy_backward(
|
Chris@16
|
212 m_edge_properties.begin() + src_begin,
|
Chris@16
|
213 m_edge_properties.begin() + src_end,
|
Chris@16
|
214 m_edge_properties.begin() + dest_begin + (src_end - src_begin));
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 typedef typename std::vector<Property>::iterator iterator;
|
Chris@16
|
218 iterator begin() {return m_edge_properties.begin();}
|
Chris@16
|
219 iterator end() {return m_edge_properties.end();}
|
Chris@16
|
220
|
Chris@16
|
221 private:
|
Chris@16
|
222 // Access to the derived object
|
Chris@16
|
223 Derived& derived() { return *static_cast<Derived*>(this); }
|
Chris@16
|
224
|
Chris@16
|
225 const Derived& derived() const
|
Chris@16
|
226 { return *static_cast<const Derived*>(this); }
|
Chris@16
|
227
|
Chris@16
|
228 public: // should be private, but friend templates not portable
|
Chris@16
|
229 std::vector<Property> m_edge_properties;
|
Chris@16
|
230 };
|
Chris@16
|
231
|
Chris@16
|
232 struct dummy_no_property_iterator
|
Chris@16
|
233 : public boost::iterator_facade<dummy_no_property_iterator, no_property, std::random_access_iterator_tag> {
|
Chris@16
|
234 mutable no_property prop;
|
Chris@16
|
235 no_property& dereference() const {return prop;}
|
Chris@16
|
236 bool equal(const dummy_no_property_iterator&) const {return true;}
|
Chris@16
|
237 void increment() {}
|
Chris@16
|
238 void decrement() {}
|
Chris@16
|
239 void advance(std::ptrdiff_t) {}
|
Chris@16
|
240 std::ptrdiff_t distance_to(const dummy_no_property_iterator) const {return 0;}
|
Chris@16
|
241 };
|
Chris@16
|
242
|
Chris@16
|
243 template<typename Derived, typename Descriptor, typename IndexMap>
|
Chris@16
|
244 class indexed_edge_properties<Derived, void, Descriptor, IndexMap>
|
Chris@16
|
245 {
|
Chris@16
|
246 struct secret {};
|
Chris@16
|
247
|
Chris@16
|
248 public:
|
Chris@16
|
249 typedef no_property edge_property_type;
|
Chris@16
|
250 typedef void edge_bundled;
|
Chris@16
|
251 typedef void* edge_push_back_type;
|
Chris@16
|
252 typedef secret edge_map_type;
|
Chris@16
|
253 typedef secret const_edge_map_type;
|
Chris@16
|
254
|
Chris@16
|
255 secret operator[](secret) { return secret(); }
|
Chris@16
|
256 void write_by_index(std::size_t /*idx*/, const no_property& /*prop*/) {}
|
Chris@16
|
257
|
Chris@16
|
258 edge_map_type get_edge_bundle(const IndexMap& = IndexMap()) const {
|
Chris@16
|
259 return edge_map_type();
|
Chris@16
|
260 }
|
Chris@16
|
261
|
Chris@16
|
262 protected:
|
Chris@16
|
263 // All operations do nothing.
|
Chris@16
|
264 indexed_edge_properties() { }
|
Chris@16
|
265 indexed_edge_properties(std::size_t) { }
|
Chris@16
|
266 std::size_t size() const {return 0;}
|
Chris@16
|
267 void clear() { }
|
Chris@16
|
268 void resize(std::size_t) { }
|
Chris@16
|
269 void reserve(std::size_t) { }
|
Chris@16
|
270
|
Chris@16
|
271 public:
|
Chris@16
|
272 void push_back(const edge_push_back_type&) { }
|
Chris@16
|
273 void move_range(std::size_t /*src_begin*/, std::size_t /*src_end*/, std::size_t /*dest_begin*/) {}
|
Chris@16
|
274
|
Chris@16
|
275 typedef dummy_no_property_iterator iterator;
|
Chris@16
|
276 iterator begin() {return dummy_no_property_iterator();}
|
Chris@16
|
277 iterator end() {return dummy_no_property_iterator();}
|
Chris@16
|
278
|
Chris@16
|
279 };
|
Chris@16
|
280
|
Chris@16
|
281 }
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 #endif // BOOST_GRAPH_INDEXED_PROPERTIES_HPP
|