1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
|
//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Copyright 2006 The Trustees of Indiana University.
// Copyright (C) 2001 Vladimir Prus <ghost@cs.msu.su>
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Douglas Gregor
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
// The mutating functions (add_edge, etc.) were added by Vladimir Prus.
#ifndef BOOST_VECTOR_AS_GRAPH_HPP
#define BOOST_VECTOR_AS_GRAPH_HPP
#include <cassert>
#include <utility>
#include <vector>
#include <cstddef>
#include <boost/iterator.hpp>
#include <boost/range/irange.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/properties.hpp>
#include <algorithm>
/*
This module implements the VertexListGraph concept using a
std::vector as the "back-bone" of the graph (the vector *is* the
graph object). The edge-lists type of the graph is templated, so the
user can choose any STL container, so long as the value_type of the
container is convertible to the size_type of the vector. For now any
graph properties must be stored seperately.
This module requires the C++ compiler to support partial
specialization for the graph_traits class, so this is not portable
to VC++.
*/
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#error The vector-as-graph module requires a compiler that supports partial specialization
#endif
namespace boost {
namespace detail {
template <class EdgeList> struct val_out_edge_ret;
template <class EdgeList> struct val_out_edge_iter;
template <class EdgeList> struct val_edge;
}
}
#if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
struct vector_as_graph_traversal_tag
: public vertex_list_graph_tag,
public adjacency_graph_tag,
public incidence_graph_tag { };
template <class EdgeList>
struct graph_traits< std::vector<EdgeList> >
{
typedef typename EdgeList::value_type V;
typedef V vertex_descriptor;
typedef typename detail::val_edge<EdgeList>::type edge_descriptor;
typedef typename EdgeList::const_iterator adjacency_iterator;
typedef typename detail::val_out_edge_iter<EdgeList>::type
out_edge_iterator;
typedef void in_edge_iterator;
typedef void edge_iterator;
typedef typename integer_range<V>::iterator vertex_iterator;
typedef directed_tag directed_category;
typedef allow_parallel_edge_tag edge_parallel_category;
typedef vector_as_graph_traversal_tag traversal_category;
typedef typename std::vector<EdgeList>::size_type vertices_size_type;
typedef void edges_size_type;
typedef typename EdgeList::size_type degree_size_type;
};
template <class EdgeList>
struct edge_property_type< std::vector<EdgeList> >
{
typedef void type;
};
template <class EdgeList>
struct vertex_property_type< std::vector<EdgeList> >
{
typedef void type;
};
template <class EdgeList>
struct graph_property_type< std::vector<EdgeList> >
{
typedef void type;
};
}
#endif
namespace boost {
namespace detail {
// "val" is short for Vector Adjacency List
template <class EdgeList>
struct val_edge
{
typedef typename EdgeList::value_type V;
typedef std::pair<V,V> type;
};
// need rewrite this using boost::iterator_adaptor
template <class V, class Iter>
class val_out_edge_iterator
: public boost::iterator<std::input_iterator_tag, std::pair<V,V>,
std::ptrdiff_t, std::pair<V,V>*, const std::pair<V,V> >
{
typedef val_out_edge_iterator self;
typedef std::pair<V,V> Edge;
public:
val_out_edge_iterator() { }
val_out_edge_iterator(V s, Iter i) : _source(s), _iter(i) { }
Edge operator*() const { return Edge(_source, *_iter); }
self& operator++() { ++_iter; return *this; }
self operator++(int) { self t = *this; ++_iter; return t; }
bool operator==(const self& x) const { return _iter == x._iter; }
bool operator!=(const self& x) const { return _iter != x._iter; }
protected:
V _source;
Iter _iter;
};
template <class EdgeList>
struct val_out_edge_iter
{
typedef typename EdgeList::value_type V;
typedef typename EdgeList::const_iterator Iter;
typedef val_out_edge_iterator<V,Iter> type;
};
template <class EdgeList>
struct val_out_edge_ret
{
typedef typename val_out_edge_iter<EdgeList>::type IncIter;
typedef std::pair<IncIter,IncIter> type;
};
} // namesapce detail
template <class EdgeList, class Alloc>
typename detail::val_out_edge_ret<EdgeList>::type
out_edges(typename EdgeList::value_type v,
const std::vector<EdgeList, Alloc>& g)
{
typedef typename detail::val_out_edge_iter<EdgeList>::type Iter;
typedef typename detail::val_out_edge_ret<EdgeList>::type return_type;
return return_type(Iter(v, g[v].begin()), Iter(v, g[v].end()));
}
template <class EdgeList, class Alloc>
typename EdgeList::size_type
out_degree(typename EdgeList::value_type v,
const std::vector<EdgeList, Alloc>& g)
{
return g[v].size();
}
template <class EdgeList, class Alloc>
std::pair<typename EdgeList::const_iterator,
typename EdgeList::const_iterator>
adjacent_vertices(typename EdgeList::value_type v,
const std::vector<EdgeList, Alloc>& g)
{
return std::make_pair(g[v].begin(), g[v].end());
}
// source() and target() already provided for pairs in graph_traits.hpp
template <class EdgeList, class Alloc>
std::pair<typename boost::integer_range<typename EdgeList::value_type>
::iterator,
typename boost::integer_range<typename EdgeList::value_type>
::iterator >
vertices(const std::vector<EdgeList, Alloc>& v)
{
typedef typename boost::integer_range<typename EdgeList::value_type>
::iterator Iter;
return std::make_pair(Iter(0), Iter(v.size()));
}
template <class EdgeList, class Alloc>
typename std::vector<EdgeList, Alloc>::size_type
num_vertices(const std::vector<EdgeList, Alloc>& v)
{
return v.size();
}
template<class EdgeList, class Allocator>
typename std::pair<typename detail::val_edge<EdgeList>::type, bool>
add_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
std::vector<EdgeList, Allocator>& g)
{
typedef typename detail::val_edge<EdgeList>::type edge_type;
g[u].insert(g[u].end(), v);
return std::make_pair(edge_type(u, v), true);
}
template<class EdgeList, class Allocator>
typename std::pair<typename detail::val_edge<EdgeList>::type, bool>
edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
std::vector<EdgeList, Allocator>& g)
{
typedef typename detail::val_edge<EdgeList>::type edge_type;
typename EdgeList::iterator i = g[u].begin(), end = g[u].end();
for (; i != end; ++i)
if (*i == v)
return std::make_pair(edge_type(u, v), true);
return std::make_pair(edge_type(), false);
}
template<class EdgeList, class Allocator>
void
remove_edge(typename EdgeList::value_type u, typename EdgeList::value_type v,
std::vector<EdgeList, Allocator>& g)
{
typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
if (i != g[u].end())
g[u].erase(i, g[u].end());
}
template<class EdgeList, class Allocator>
void
remove_edge(typename detail::val_edge<EdgeList>::type e,
std::vector<EdgeList, Allocator>& g)
{
typename EdgeList::value_type u, v;
u = e.first;
v = e.second;
// FIXME: edge type does not fully specify the edge to be deleted
typename EdgeList::iterator i = std::remove(g[u].begin(), g[u].end(), v);
if (i != g[u].end())
g[u].erase(i, g[u].end());
}
template<class EdgeList, class Allocator, class Predicate>
void
remove_edge_if(Predicate p,
std::vector<EdgeList, Allocator>& g)
{
for (std::size_t u = 0; u < g.size(); ++u) {
// Oops! gcc gets internal compiler error on compose_.......
typedef typename EdgeList::iterator iterator;
iterator b = g[u].begin(), e = g[u].end();
if (!g[u].empty()) {
for(; b != e;) {
if (p(std::make_pair(u, *b))) {
--e;
if (b == e)
break;
else
iter_swap(b, e);
} else {
++b;
}
}
}
if (e != g[u].end())
g[u].erase(e, g[u].end());
}
}
template<class EdgeList, class Allocator>
typename EdgeList::value_type
add_vertex(std::vector<EdgeList, Allocator>& g)
{
g.resize(g.size()+1);
return g.size()-1;
}
template<class EdgeList, class Allocator>
void
clear_vertex(typename EdgeList::value_type u,
std::vector<EdgeList, Allocator>& g)
{
g[u].clear();
for (std::size_t i = 0; i < g.size(); ++i)
remove_edge(i, u, g);
}
template<class EdgeList, class Allocator>
void
remove_vertex(typename EdgeList::value_type u,
std::vector<EdgeList, Allocator>& g)
{
typedef typename EdgeList::iterator iterator;
clear_vertex(u, g);
g.erase(g.begin() + u);
for (std::size_t i = 0; i < g.size(); ++i)
for ( iterator it = g[i].begin(); it != g[i].end(); ++it )
// after clear_vertex *it is never equal to u
if ( *it > u )
--*it;
}
template<typename EdgeList, typename Allocator>
struct property_map<std::vector<EdgeList, Allocator>, vertex_index_t>
{
typedef identity_property_map type;
typedef type const_type;
};
template<typename EdgeList, typename Allocator>
identity_property_map
get(vertex_index_t, const std::vector<EdgeList, Allocator>&)
{
return identity_property_map();
}
template<typename EdgeList, typename Allocator>
identity_property_map
get(vertex_index_t, std::vector<EdgeList, Allocator>&)
{
return identity_property_map();
}
} // namespace boost
#endif // BOOST_VECTOR_AS_GRAPH_HPP
|