Chris@16
|
1 //=======================================================================
|
Chris@16
|
2 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
|
Chris@16
|
3 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8 //=======================================================================
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_GRAPH_EDGE_LIST_HPP
|
Chris@16
|
12 #define BOOST_GRAPH_EDGE_LIST_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <iterator>
|
Chris@16
|
15 #include <boost/config.hpp>
|
Chris@16
|
16 #include <boost/mpl/if.hpp>
|
Chris@16
|
17 #include <boost/mpl/bool.hpp>
|
Chris@16
|
18 #include <boost/range/irange.hpp>
|
Chris@16
|
19 #include <boost/graph/graph_traits.hpp>
|
Chris@16
|
20 #include <boost/graph/properties.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost {
|
Chris@16
|
23
|
Chris@16
|
24 //
|
Chris@16
|
25 // The edge_list class is an EdgeListGraph module that is constructed
|
Chris@16
|
26 // from a pair of iterators whose value type is a pair of vertex
|
Chris@16
|
27 // descriptors.
|
Chris@16
|
28 //
|
Chris@16
|
29 // For example:
|
Chris@16
|
30 //
|
Chris@16
|
31 // typedef std::pair<int,int> E;
|
Chris@16
|
32 // list<E> elist;
|
Chris@16
|
33 // ...
|
Chris@16
|
34 // typedef edge_list<list<E>::iterator> Graph;
|
Chris@16
|
35 // Graph g(elist.begin(), elist.end());
|
Chris@16
|
36 //
|
Chris@16
|
37 // If the iterators are random access, then Graph::edge_descriptor
|
Chris@16
|
38 // is of Integral type, otherwise it is a struct, though it is
|
Chris@16
|
39 // convertible to an Integral type.
|
Chris@16
|
40 //
|
Chris@16
|
41
|
Chris@16
|
42 struct edge_list_tag { };
|
Chris@16
|
43
|
Chris@16
|
44 // The implementation class for edge_list.
|
Chris@16
|
45 template <class G, class EdgeIter, class T, class D>
|
Chris@16
|
46 class edge_list_impl
|
Chris@16
|
47 {
|
Chris@16
|
48 public:
|
Chris@16
|
49 typedef D edge_id;
|
Chris@16
|
50 typedef T Vpair;
|
Chris@16
|
51 typedef typename Vpair::first_type V;
|
Chris@16
|
52 typedef V vertex_descriptor;
|
Chris@16
|
53 typedef edge_list_tag graph_tag;
|
Chris@16
|
54 typedef void edge_property_type;
|
Chris@16
|
55
|
Chris@16
|
56 struct edge_descriptor
|
Chris@16
|
57 {
|
Chris@16
|
58 edge_descriptor() { }
|
Chris@16
|
59 edge_descriptor(EdgeIter p, edge_id id) : _ptr(p), _id(id) { }
|
Chris@16
|
60 operator edge_id() { return _id; }
|
Chris@16
|
61 EdgeIter _ptr;
|
Chris@16
|
62 edge_id _id;
|
Chris@16
|
63 };
|
Chris@16
|
64 typedef edge_descriptor E;
|
Chris@16
|
65
|
Chris@16
|
66 struct edge_iterator
|
Chris@16
|
67 {
|
Chris@16
|
68 typedef edge_iterator self;
|
Chris@16
|
69 typedef E value_type;
|
Chris@16
|
70 typedef E& reference;
|
Chris@16
|
71 typedef E* pointer;
|
Chris@16
|
72 typedef std::ptrdiff_t difference_type;
|
Chris@16
|
73 typedef std::input_iterator_tag iterator_category;
|
Chris@16
|
74 edge_iterator() { }
|
Chris@16
|
75 edge_iterator(EdgeIter iter) : _iter(iter), _i(0) { }
|
Chris@16
|
76 E operator*() { return E(_iter, _i); }
|
Chris@16
|
77 self& operator++() { ++_iter; ++_i; return *this; }
|
Chris@16
|
78 self operator++(int) { self t = *this; ++(*this); return t; }
|
Chris@16
|
79 bool operator==(const self& x) { return _iter == x._iter; }
|
Chris@16
|
80 bool operator!=(const self& x) { return _iter != x._iter; }
|
Chris@16
|
81 EdgeIter _iter;
|
Chris@16
|
82 edge_id _i;
|
Chris@16
|
83 };
|
Chris@16
|
84 typedef void out_edge_iterator;
|
Chris@16
|
85 typedef void in_edge_iterator;
|
Chris@16
|
86 typedef void adjacency_iterator;
|
Chris@16
|
87 typedef void vertex_iterator;
|
Chris@16
|
88 };
|
Chris@16
|
89
|
Chris@16
|
90 template <class G, class EI, class T, class D>
|
Chris@16
|
91 std::pair<typename edge_list_impl<G,EI,T,D>::edge_iterator,
|
Chris@16
|
92 typename edge_list_impl<G,EI,T,D>::edge_iterator>
|
Chris@16
|
93 edges(const edge_list_impl<G,EI,T,D>& g_) {
|
Chris@16
|
94 const G& g = static_cast<const G&>(g_);
|
Chris@16
|
95 typedef typename edge_list_impl<G,EI,T,D>::edge_iterator edge_iterator;
|
Chris@16
|
96 return std::make_pair(edge_iterator(g._first), edge_iterator(g._last));
|
Chris@16
|
97 }
|
Chris@16
|
98 template <class G, class EI, class T, class D>
|
Chris@16
|
99 typename edge_list_impl<G,EI,T,D>::vertex_descriptor
|
Chris@16
|
100 source(typename edge_list_impl<G,EI,T,D>::edge_descriptor e,
|
Chris@16
|
101 const edge_list_impl<G,EI,T,D>&) {
|
Chris@16
|
102 return (*e._ptr).first;
|
Chris@16
|
103 }
|
Chris@16
|
104 template <class G, class EI, class T, class D>
|
Chris@16
|
105 typename edge_list_impl<G,EI,T,D>::vertex_descriptor
|
Chris@16
|
106 target(typename edge_list_impl<G,EI,T,D>::edge_descriptor e,
|
Chris@16
|
107 const edge_list_impl<G,EI,T,D>&) {
|
Chris@16
|
108 return (*e._ptr).second;
|
Chris@16
|
109 }
|
Chris@16
|
110
|
Chris@16
|
111 template <class D, class E>
|
Chris@16
|
112 class el_edge_property_map
|
Chris@16
|
113 : public put_get_helper<D, el_edge_property_map<D,E> >{
|
Chris@16
|
114 public:
|
Chris@16
|
115 typedef E key_type;
|
Chris@16
|
116 typedef D value_type;
|
Chris@16
|
117 typedef D reference;
|
Chris@16
|
118 typedef readable_property_map_tag category;
|
Chris@16
|
119
|
Chris@16
|
120 value_type operator[](key_type e) const {
|
Chris@16
|
121 return e._i;
|
Chris@16
|
122 }
|
Chris@16
|
123 };
|
Chris@16
|
124 struct edge_list_edge_property_selector {
|
Chris@16
|
125 template <class Graph, class Property, class Tag>
|
Chris@16
|
126 struct bind_ {
|
Chris@16
|
127 typedef el_edge_property_map<typename Graph::edge_id,
|
Chris@16
|
128 typename Graph::edge_descriptor> type;
|
Chris@16
|
129 typedef type const_type;
|
Chris@16
|
130 };
|
Chris@16
|
131 };
|
Chris@16
|
132 template <>
|
Chris@16
|
133 struct edge_property_selector<edge_list_tag> {
|
Chris@16
|
134 typedef edge_list_edge_property_selector type;
|
Chris@16
|
135 };
|
Chris@16
|
136
|
Chris@16
|
137 template <class G, class EI, class T, class D>
|
Chris@16
|
138 typename property_map< edge_list_impl<G,EI,T,D>, edge_index_t>::type
|
Chris@16
|
139 get(edge_index_t, const edge_list_impl<G,EI,T,D>&) {
|
Chris@16
|
140 typedef typename property_map< edge_list_impl<G,EI,T,D>,
|
Chris@16
|
141 edge_index_t>::type EdgeIndexMap;
|
Chris@16
|
142 return EdgeIndexMap();
|
Chris@16
|
143 }
|
Chris@16
|
144
|
Chris@16
|
145 template <class G, class EI, class T, class D>
|
Chris@16
|
146 inline D
|
Chris@16
|
147 get(edge_index_t, const edge_list_impl<G,EI,T,D>&,
|
Chris@16
|
148 typename edge_list_impl<G,EI,T,D>::edge_descriptor e) {
|
Chris@16
|
149 return e._i;
|
Chris@16
|
150 }
|
Chris@16
|
151
|
Chris@16
|
152 // A specialized implementation for when the iterators are random access.
|
Chris@16
|
153
|
Chris@16
|
154 struct edge_list_ra_tag { };
|
Chris@16
|
155
|
Chris@16
|
156 template <class G, class EdgeIter, class T, class D>
|
Chris@16
|
157 class edge_list_impl_ra
|
Chris@16
|
158 {
|
Chris@16
|
159 public:
|
Chris@16
|
160 typedef D edge_id;
|
Chris@16
|
161 typedef T Vpair;
|
Chris@16
|
162 typedef typename Vpair::first_type V;
|
Chris@16
|
163 typedef edge_list_ra_tag graph_tag;
|
Chris@16
|
164 typedef void edge_property_type;
|
Chris@16
|
165
|
Chris@16
|
166 typedef edge_id edge_descriptor;
|
Chris@16
|
167 typedef V vertex_descriptor;
|
Chris@16
|
168 typedef typename boost::integer_range<edge_id>::iterator edge_iterator;
|
Chris@16
|
169 typedef void out_edge_iterator;
|
Chris@16
|
170 typedef void in_edge_iterator;
|
Chris@16
|
171 typedef void adjacency_iterator;
|
Chris@16
|
172 typedef void vertex_iterator;
|
Chris@16
|
173 };
|
Chris@16
|
174
|
Chris@16
|
175 template <class G, class EI, class T, class D>
|
Chris@16
|
176 std::pair<typename edge_list_impl_ra<G,EI,T,D>::edge_iterator,
|
Chris@16
|
177 typename edge_list_impl_ra<G,EI,T,D>::edge_iterator>
|
Chris@16
|
178 edges(const edge_list_impl_ra<G,EI,T,D>& g_)
|
Chris@16
|
179 {
|
Chris@16
|
180 const G& g = static_cast<const G&>(g_);
|
Chris@16
|
181 typedef typename edge_list_impl_ra<G,EI,T,D>::edge_iterator edge_iterator;
|
Chris@16
|
182 return std::make_pair(edge_iterator(0), edge_iterator(g._last - g._first));
|
Chris@16
|
183 }
|
Chris@16
|
184 template <class G, class EI, class T, class D>
|
Chris@16
|
185 typename edge_list_impl_ra<G,EI,T,D>::vertex_descriptor
|
Chris@16
|
186 source(typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e,
|
Chris@16
|
187 const edge_list_impl_ra<G,EI,T,D>& g_)
|
Chris@16
|
188 {
|
Chris@16
|
189 const G& g = static_cast<const G&>(g_);
|
Chris@16
|
190 return g._first[e].first;
|
Chris@16
|
191 }
|
Chris@16
|
192 template <class G, class EI, class T, class D>
|
Chris@16
|
193 typename edge_list_impl_ra<G,EI,T,D>::vertex_descriptor
|
Chris@16
|
194 target(typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e,
|
Chris@16
|
195 const edge_list_impl_ra<G,EI,T,D>& g_)
|
Chris@16
|
196 {
|
Chris@16
|
197 const G& g = static_cast<const G&>(g_);
|
Chris@16
|
198 return g._first[e].second;
|
Chris@16
|
199 }
|
Chris@16
|
200 template <class E>
|
Chris@16
|
201 class el_ra_edge_property_map
|
Chris@16
|
202 : public put_get_helper<E, el_ra_edge_property_map<E> >{
|
Chris@16
|
203 public:
|
Chris@16
|
204 typedef E key_type;
|
Chris@16
|
205 typedef E value_type;
|
Chris@16
|
206 typedef E reference;
|
Chris@16
|
207 typedef readable_property_map_tag category;
|
Chris@16
|
208
|
Chris@16
|
209 value_type operator[](key_type e) const {
|
Chris@16
|
210 return e;
|
Chris@16
|
211 }
|
Chris@16
|
212 };
|
Chris@16
|
213 struct edge_list_ra_edge_property_selector {
|
Chris@16
|
214 template <class Graph, class Property, class Tag>
|
Chris@16
|
215 struct bind_ {
|
Chris@16
|
216 typedef el_ra_edge_property_map<typename Graph::edge_descriptor> type;
|
Chris@16
|
217 typedef type const_type;
|
Chris@16
|
218 };
|
Chris@16
|
219 };
|
Chris@16
|
220 template <>
|
Chris@16
|
221 struct edge_property_selector<edge_list_ra_tag> {
|
Chris@16
|
222 typedef edge_list_ra_edge_property_selector type;
|
Chris@16
|
223 };
|
Chris@16
|
224 template <class G, class EI, class T, class D>
|
Chris@16
|
225 inline
|
Chris@16
|
226 typename property_map< edge_list_impl_ra<G,EI,T,D>, edge_index_t>::type
|
Chris@16
|
227 get(edge_index_t, const edge_list_impl_ra<G,EI,T,D>&) {
|
Chris@16
|
228 typedef typename property_map< edge_list_impl_ra<G,EI,T,D>,
|
Chris@16
|
229 edge_index_t>::type EdgeIndexMap;
|
Chris@16
|
230 return EdgeIndexMap();
|
Chris@16
|
231 }
|
Chris@16
|
232
|
Chris@16
|
233 template <class G, class EI, class T, class D>
|
Chris@16
|
234 inline D
|
Chris@16
|
235 get(edge_index_t, const edge_list_impl_ra<G,EI,T,D>&,
|
Chris@16
|
236 typename edge_list_impl_ra<G,EI,T,D>::edge_descriptor e) {
|
Chris@16
|
237 return e;
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240
|
Chris@16
|
241 // Some helper classes for determining if the iterators are random access
|
Chris@16
|
242 template <class Cat>
|
Chris@16
|
243 struct is_random {
|
Chris@16
|
244 enum { RET = false };
|
Chris@16
|
245 typedef mpl::false_ type;
|
Chris@16
|
246 };
|
Chris@16
|
247 template <>
|
Chris@16
|
248 struct is_random<std::random_access_iterator_tag> {
|
Chris@16
|
249 enum { RET = true }; typedef mpl::true_ type;
|
Chris@16
|
250 };
|
Chris@16
|
251
|
Chris@16
|
252 // The edge_list class conditionally inherits from one of the
|
Chris@16
|
253 // above two classes.
|
Chris@16
|
254
|
Chris@16
|
255 template <class EdgeIter,
|
Chris@16
|
256 #if !defined BOOST_NO_STD_ITERATOR_TRAITS
|
Chris@16
|
257 class T = typename std::iterator_traits<EdgeIter>::value_type,
|
Chris@16
|
258 class D = typename std::iterator_traits<EdgeIter>::difference_type,
|
Chris@16
|
259 class Cat = typename std::iterator_traits<EdgeIter>::iterator_category>
|
Chris@16
|
260 #else
|
Chris@16
|
261 class T,
|
Chris@16
|
262 class D,
|
Chris@16
|
263 class Cat>
|
Chris@16
|
264 #endif
|
Chris@16
|
265 class edge_list
|
Chris@16
|
266 : public mpl::if_< typename is_random<Cat>::type,
|
Chris@16
|
267 edge_list_impl_ra< edge_list<EdgeIter,T,D,Cat>, EdgeIter,T,D>,
|
Chris@16
|
268 edge_list_impl< edge_list<EdgeIter,T,D,Cat>, EdgeIter,T,D>
|
Chris@16
|
269 >::type
|
Chris@16
|
270 {
|
Chris@16
|
271 public:
|
Chris@16
|
272 typedef directed_tag directed_category;
|
Chris@16
|
273 typedef allow_parallel_edge_tag edge_parallel_category;
|
Chris@16
|
274 typedef edge_list_graph_tag traversal_category;
|
Chris@16
|
275 typedef std::size_t edges_size_type;
|
Chris@16
|
276 typedef std::size_t vertices_size_type;
|
Chris@16
|
277 typedef std::size_t degree_size_type;
|
Chris@16
|
278 edge_list(EdgeIter first, EdgeIter last) : _first(first), _last(last) {
|
Chris@16
|
279 m_num_edges = std::distance(first, last);
|
Chris@16
|
280 }
|
Chris@16
|
281 edge_list(EdgeIter first, EdgeIter last, edges_size_type E)
|
Chris@16
|
282 : _first(first), _last(last), m_num_edges(E) { }
|
Chris@16
|
283
|
Chris@16
|
284 EdgeIter _first, _last;
|
Chris@16
|
285 edges_size_type m_num_edges;
|
Chris@16
|
286 };
|
Chris@16
|
287
|
Chris@16
|
288 template <class EdgeIter, class T, class D, class Cat>
|
Chris@16
|
289 std::size_t num_edges(const edge_list<EdgeIter, T, D, Cat>& el) {
|
Chris@16
|
290 return el.m_num_edges;
|
Chris@16
|
291 }
|
Chris@16
|
292
|
Chris@16
|
293 #ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
Chris@16
|
294 template <class EdgeIter>
|
Chris@16
|
295 inline edge_list<EdgeIter>
|
Chris@16
|
296 make_edge_list(EdgeIter first, EdgeIter last)
|
Chris@16
|
297 {
|
Chris@16
|
298 return edge_list<EdgeIter>(first, last);
|
Chris@16
|
299 }
|
Chris@16
|
300 #endif
|
Chris@16
|
301
|
Chris@16
|
302 } /* namespace boost */
|
Chris@16
|
303
|
Chris@16
|
304 #endif /* BOOST_GRAPH_EDGE_LIST_HPP */
|