undirected_graph.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. // (C) Copyright 2007-2009 Andrew Sutton
  2. //
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0 (See accompanying file
  5. // LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
  7. #define BOOST_GRAPH_UNDIRECTED_GRAPH_HPP
  8. #include <boost/graph/adjacency_list.hpp>
  9. #include <boost/graph/properties.hpp>
  10. #include <boost/pending/property.hpp>
  11. #include <boost/property_map/transform_value_property_map.hpp>
  12. #include <boost/type_traits.hpp>
  13. #include <boost/mpl/if.hpp>
  14. namespace boost
  15. {
  16. struct undirected_graph_tag
  17. {
  18. };
  19. /**
  20. * The undirected_graph class template is a simplified version of the BGL
  21. * adjacency list. This class is provided for ease of use, but may not
  22. * perform as well as custom-defined adjacency list classes. Instances of
  23. * this template model the VertexIndexGraph, and EdgeIndexGraph concepts. The
  24. * graph is also fully mutable, supporting both insertions and removals of
  25. * vertices and edges.
  26. *
  27. * @note Special care must be taken when removing vertices or edges since
  28. * those operations can invalidate the numbering of vertices.
  29. */
  30. template < typename VertexProp = no_property, typename EdgeProp = no_property,
  31. typename GraphProp = no_property >
  32. class undirected_graph
  33. {
  34. public:
  35. typedef GraphProp graph_property_type;
  36. typedef VertexProp vertex_property_type;
  37. typedef EdgeProp edge_property_type;
  38. typedef typename lookup_one_property< GraphProp, graph_bundle_t >::type
  39. graph_bundled;
  40. typedef typename lookup_one_property< VertexProp, vertex_bundle_t >::type
  41. vertex_bundled;
  42. typedef typename lookup_one_property< EdgeProp, edge_bundle_t >::type
  43. edge_bundled;
  44. public:
  45. // Embed indices into the vertex type.
  46. typedef property< vertex_index_t, unsigned, vertex_property_type >
  47. internal_vertex_property;
  48. typedef property< edge_index_t, unsigned, edge_property_type >
  49. internal_edge_property;
  50. public:
  51. typedef adjacency_list< listS, listS, undirectedS, internal_vertex_property,
  52. internal_edge_property, GraphProp, listS >
  53. graph_type;
  54. private:
  55. // storage selectors
  56. typedef typename graph_type::vertex_list_selector vertex_list_selector;
  57. typedef typename graph_type::edge_list_selector edge_list_selector;
  58. typedef typename graph_type::out_edge_list_selector out_edge_list_selector;
  59. typedef typename graph_type::directed_selector directed_selector;
  60. public:
  61. // more commonly used graph types
  62. typedef typename graph_type::stored_vertex stored_vertex;
  63. typedef typename graph_type::vertices_size_type vertices_size_type;
  64. typedef typename graph_type::edges_size_type edges_size_type;
  65. typedef typename graph_type::degree_size_type degree_size_type;
  66. typedef typename graph_type::vertex_descriptor vertex_descriptor;
  67. typedef typename graph_type::edge_descriptor edge_descriptor;
  68. // iterator types
  69. typedef typename graph_type::vertex_iterator vertex_iterator;
  70. typedef typename graph_type::edge_iterator edge_iterator;
  71. typedef typename graph_type::out_edge_iterator out_edge_iterator;
  72. typedef typename graph_type::in_edge_iterator in_edge_iterator;
  73. typedef typename graph_type::adjacency_iterator adjacency_iterator;
  74. // miscellaneous types
  75. typedef undirected_graph_tag graph_tag;
  76. typedef typename graph_type::directed_category directed_category;
  77. typedef typename graph_type::edge_parallel_category edge_parallel_category;
  78. typedef typename graph_type::traversal_category traversal_category;
  79. typedef std::size_t vertex_index_type;
  80. typedef std::size_t edge_index_type;
  81. inline undirected_graph(GraphProp const& p = GraphProp())
  82. : m_graph(p)
  83. , m_num_vertices(0)
  84. , m_num_edges(0)
  85. , m_max_vertex_index(0)
  86. , m_max_edge_index(0)
  87. {
  88. }
  89. inline undirected_graph(undirected_graph const& x)
  90. : m_graph(x.m_graph)
  91. , m_num_vertices(x.m_num_vertices)
  92. , m_num_edges(x.m_num_edges)
  93. , m_max_vertex_index(x.m_max_vertex_index)
  94. , m_max_edge_index(x.m_max_edge_index)
  95. {
  96. }
  97. inline undirected_graph(
  98. vertices_size_type n, GraphProp const& p = GraphProp())
  99. : m_graph(n, p)
  100. , m_num_vertices(n)
  101. , m_num_edges(0)
  102. , m_max_vertex_index(n)
  103. , m_max_edge_index(0)
  104. {
  105. renumber_vertex_indices();
  106. }
  107. template < typename EdgeIterator >
  108. inline undirected_graph(EdgeIterator f, EdgeIterator l,
  109. vertices_size_type n, edges_size_type m = 0,
  110. GraphProp const& p = GraphProp())
  111. : m_graph(f, l, n, m, p)
  112. , m_num_vertices(n)
  113. , m_num_edges(0)
  114. , m_max_vertex_index(n)
  115. , m_max_edge_index(0)
  116. {
  117. // Unfortunately, we have to renumber to ensure correct indexing.
  118. renumber_indices();
  119. // Can't always guarantee that the number of edges is actually
  120. // m if distance(f, l) != m (or is undefined).
  121. m_num_edges = m_max_edge_index = boost::num_edges(m_graph);
  122. }
  123. undirected_graph& operator=(undirected_graph const& g)
  124. {
  125. if (&g != this)
  126. {
  127. m_graph = g.m_graph;
  128. m_num_vertices = g.m_num_vertices;
  129. m_num_edges = g.m_num_edges;
  130. m_max_vertex_index = g.m_max_vertex_index;
  131. }
  132. return *this;
  133. }
  134. // The impl_() methods are not part of the public interface.
  135. graph_type& impl() { return m_graph; }
  136. graph_type const& impl() const { return m_graph; }
  137. // The following methods are not part of the public interface
  138. vertices_size_type num_vertices() const { return m_num_vertices; }
  139. private:
  140. // This helper function manages the attribution of vertex indices.
  141. vertex_descriptor make_index(vertex_descriptor v)
  142. {
  143. boost::put(vertex_index, m_graph, v, m_max_vertex_index);
  144. m_num_vertices++;
  145. m_max_vertex_index++;
  146. return v;
  147. }
  148. public:
  149. vertex_descriptor add_vertex()
  150. {
  151. return make_index(boost::add_vertex(m_graph));
  152. }
  153. vertex_descriptor add_vertex(vertex_property_type const& p)
  154. {
  155. return make_index(
  156. boost::add_vertex(internal_vertex_property(0u, p), m_graph));
  157. }
  158. void clear_vertex(vertex_descriptor v)
  159. {
  160. std::pair< out_edge_iterator, out_edge_iterator > p
  161. = boost::out_edges(v, m_graph);
  162. m_num_edges -= std::distance(p.first, p.second);
  163. boost::clear_vertex(v, m_graph);
  164. }
  165. void remove_vertex(vertex_descriptor v)
  166. {
  167. boost::remove_vertex(v, m_graph);
  168. --m_num_vertices;
  169. }
  170. edges_size_type num_edges() const { return m_num_edges; }
  171. private:
  172. // A helper fucntion for managing edge index attributes.
  173. std::pair< edge_descriptor, bool > const& make_index(
  174. std::pair< edge_descriptor, bool > const& x)
  175. {
  176. if (x.second)
  177. {
  178. boost::put(edge_index, m_graph, x.first, m_max_edge_index);
  179. ++m_num_edges;
  180. ++m_max_edge_index;
  181. }
  182. return x;
  183. }
  184. public:
  185. std::pair< edge_descriptor, bool > add_edge(
  186. vertex_descriptor u, vertex_descriptor v)
  187. {
  188. return make_index(boost::add_edge(u, v, m_graph));
  189. }
  190. std::pair< edge_descriptor, bool > add_edge(
  191. vertex_descriptor u, vertex_descriptor v, edge_property_type const& p)
  192. {
  193. return make_index(
  194. boost::add_edge(u, v, internal_edge_property(0u, p), m_graph));
  195. }
  196. void remove_edge(vertex_descriptor u, vertex_descriptor v)
  197. {
  198. // find all edges, (u, v)
  199. std::vector< edge_descriptor > edges;
  200. out_edge_iterator i, i_end;
  201. for (boost::tie(i, i_end) = boost::out_edges(u, m_graph); i != i_end;
  202. ++i)
  203. {
  204. if (boost::target(*i, m_graph) == v)
  205. {
  206. edges.push_back(*i);
  207. }
  208. }
  209. // remove all edges, (u, v)
  210. typename std::vector< edge_descriptor >::iterator j = edges.begin(),
  211. j_end = edges.end();
  212. for (; j != j_end; ++j)
  213. {
  214. remove_edge(*j);
  215. }
  216. }
  217. void remove_edge(edge_iterator i) { remove_edge(*i); }
  218. void remove_edge(edge_descriptor e)
  219. {
  220. boost::remove_edge(e, m_graph);
  221. --m_num_edges;
  222. }
  223. vertex_index_type max_vertex_index() const { return m_max_vertex_index; }
  224. void renumber_vertex_indices()
  225. {
  226. vertex_iterator i, i_end;
  227. boost::tie(i, i_end) = vertices(m_graph);
  228. m_max_vertex_index = renumber_vertex_indices(i, i_end, 0);
  229. }
  230. void remove_vertex_and_renumber_indices(vertex_iterator i)
  231. {
  232. vertex_iterator j = next(i), end = vertices(m_graph).second;
  233. vertex_index_type n = get(vertex_index, m_graph, *i);
  234. // remove the offending vertex and renumber everything after
  235. remove_vertex(*i);
  236. m_max_vertex_index = renumber_vertex_indices(j, end, n);
  237. }
  238. edge_index_type max_edge_index() const { return m_max_edge_index; }
  239. void renumber_edge_indices()
  240. {
  241. edge_iterator i, end;
  242. boost::tie(i, end) = edges(m_graph);
  243. m_max_edge_index = renumber_edge_indices(i, end, 0);
  244. }
  245. void remove_edge_and_renumber_indices(edge_iterator i)
  246. {
  247. edge_iterator j = next(i), end = edges(m_graph.second);
  248. edge_index_type n = get(edge_index, m_graph, *i);
  249. // remove the edge and renumber everything after it
  250. remove_edge(*i);
  251. m_max_edge_index = renumber_edge_indices(j, end, n);
  252. }
  253. void renumber_indices()
  254. {
  255. renumber_vertex_indices();
  256. renumber_edge_indices();
  257. }
  258. // bundled property support
  259. #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
  260. vertex_bundled& operator[](vertex_descriptor v) { return m_graph[v]; }
  261. vertex_bundled const& operator[](vertex_descriptor v) const
  262. {
  263. return m_graph[v];
  264. }
  265. edge_bundled& operator[](edge_descriptor e) { return m_graph[e]; }
  266. edge_bundled const& operator[](edge_descriptor e) const
  267. {
  268. return m_graph[e];
  269. }
  270. graph_bundled& operator[](graph_bundle_t) { return get_property(*this); }
  271. graph_bundled const& operator[](graph_bundle_t) const
  272. {
  273. return get_property(*this);
  274. }
  275. #endif
  276. // Graph concepts
  277. static vertex_descriptor null_vertex() { return graph_type::null_vertex(); }
  278. void clear()
  279. {
  280. m_graph.clear();
  281. m_num_vertices = m_max_vertex_index = 0;
  282. m_num_edges = m_max_edge_index = 0;
  283. }
  284. void swap(undirected_graph& g)
  285. {
  286. m_graph.swap(g.m_graph);
  287. std::swap(m_num_vertices, g.m_num_vertices);
  288. std::swap(m_max_vertex_index, g.m_max_vertex_index);
  289. std::swap(m_num_edges, g.m_num_edges);
  290. std::swap(m_max_edge_index, g.m_max_edge_index);
  291. }
  292. private:
  293. vertices_size_type renumber_vertex_indices(
  294. vertex_iterator i, vertex_iterator end, vertices_size_type n)
  295. {
  296. typedef
  297. typename property_map< graph_type, vertex_index_t >::type IndexMap;
  298. IndexMap indices = get(vertex_index, m_graph);
  299. for (; i != end; ++i)
  300. {
  301. indices[*i] = n++;
  302. }
  303. return n;
  304. }
  305. edges_size_type renumber_edge_indices(
  306. edge_iterator i, edge_iterator end, edges_size_type n)
  307. {
  308. typedef
  309. typename property_map< graph_type, edge_index_t >::type IndexMap;
  310. IndexMap indices = get(edge_index, m_graph);
  311. for (; i != end; ++i)
  312. {
  313. indices[*i] = n++;
  314. }
  315. return n;
  316. }
  317. graph_type m_graph;
  318. vertices_size_type m_num_vertices;
  319. edges_size_type m_num_edges;
  320. vertex_index_type m_max_vertex_index;
  321. edge_index_type m_max_edge_index;
  322. };
  323. #define UNDIRECTED_GRAPH_PARAMS typename VP, typename EP, typename GP
  324. #define UNDIRECTED_GRAPH undirected_graph< VP, EP, GP >
  325. // IncidenceGraph concepts
  326. template < UNDIRECTED_GRAPH_PARAMS >
  327. inline typename UNDIRECTED_GRAPH::vertex_descriptor source(
  328. typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g)
  329. {
  330. return source(e, g.impl());
  331. }
  332. template < UNDIRECTED_GRAPH_PARAMS >
  333. inline typename UNDIRECTED_GRAPH::vertex_descriptor target(
  334. typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH const& g)
  335. {
  336. return target(e, g.impl());
  337. }
  338. template < UNDIRECTED_GRAPH_PARAMS >
  339. inline typename UNDIRECTED_GRAPH::degree_size_type out_degree(
  340. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  341. {
  342. return out_degree(v, g.impl());
  343. }
  344. template < UNDIRECTED_GRAPH_PARAMS >
  345. inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator,
  346. typename UNDIRECTED_GRAPH::out_edge_iterator >
  347. out_edges(
  348. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  349. {
  350. return out_edges(v, g.impl());
  351. }
  352. // BidirectionalGraph concepts
  353. template < UNDIRECTED_GRAPH_PARAMS >
  354. inline typename UNDIRECTED_GRAPH::degree_size_type in_degree(
  355. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  356. {
  357. return in_degree(v, g.impl());
  358. }
  359. template < UNDIRECTED_GRAPH_PARAMS >
  360. inline std::pair< typename UNDIRECTED_GRAPH::in_edge_iterator,
  361. typename UNDIRECTED_GRAPH::in_edge_iterator >
  362. in_edges(
  363. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  364. {
  365. return in_edges(v, g.impl());
  366. }
  367. template < UNDIRECTED_GRAPH_PARAMS >
  368. inline std::pair< typename UNDIRECTED_GRAPH::out_edge_iterator,
  369. typename UNDIRECTED_GRAPH::out_edge_iterator >
  370. incident_edges(
  371. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  372. {
  373. return out_edges(v, g.impl());
  374. }
  375. template < UNDIRECTED_GRAPH_PARAMS >
  376. inline typename UNDIRECTED_GRAPH::degree_size_type degree(
  377. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  378. {
  379. return degree(v, g.impl());
  380. }
  381. // AdjacencyGraph concepts
  382. template < UNDIRECTED_GRAPH_PARAMS >
  383. inline std::pair< typename UNDIRECTED_GRAPH::adjacency_iterator,
  384. typename UNDIRECTED_GRAPH::adjacency_iterator >
  385. adjacent_vertices(
  386. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  387. {
  388. return adjacent_vertices(v, g.impl());
  389. }
  390. template < UNDIRECTED_GRAPH_PARAMS >
  391. typename UNDIRECTED_GRAPH::vertex_descriptor vertex(
  392. typename UNDIRECTED_GRAPH::vertices_size_type n, UNDIRECTED_GRAPH const& g)
  393. {
  394. return vertex(n, g.impl());
  395. }
  396. template < UNDIRECTED_GRAPH_PARAMS >
  397. std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > edge(
  398. typename UNDIRECTED_GRAPH::vertex_descriptor u,
  399. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  400. {
  401. return edge(u, v, g.impl());
  402. }
  403. // VertexListGraph concepts
  404. template < UNDIRECTED_GRAPH_PARAMS >
  405. inline typename UNDIRECTED_GRAPH::vertices_size_type num_vertices(
  406. UNDIRECTED_GRAPH const& g)
  407. {
  408. return g.num_vertices();
  409. }
  410. template < UNDIRECTED_GRAPH_PARAMS >
  411. inline std::pair< typename UNDIRECTED_GRAPH::vertex_iterator,
  412. typename UNDIRECTED_GRAPH::vertex_iterator >
  413. vertices(UNDIRECTED_GRAPH const& g)
  414. {
  415. return vertices(g.impl());
  416. }
  417. // EdgeListGraph concepts
  418. template < UNDIRECTED_GRAPH_PARAMS >
  419. inline typename UNDIRECTED_GRAPH::edges_size_type num_edges(
  420. UNDIRECTED_GRAPH const& g)
  421. {
  422. return g.num_edges();
  423. }
  424. template < UNDIRECTED_GRAPH_PARAMS >
  425. inline std::pair< typename UNDIRECTED_GRAPH::edge_iterator,
  426. typename UNDIRECTED_GRAPH::edge_iterator >
  427. edges(UNDIRECTED_GRAPH const& g)
  428. {
  429. return edges(g.impl());
  430. }
  431. // MutableGraph concepts
  432. template < UNDIRECTED_GRAPH_PARAMS >
  433. inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex(
  434. UNDIRECTED_GRAPH& g)
  435. {
  436. return g.add_vertex();
  437. }
  438. template < UNDIRECTED_GRAPH_PARAMS >
  439. inline typename UNDIRECTED_GRAPH::vertex_descriptor add_vertex(
  440. typename UNDIRECTED_GRAPH::vertex_property_type const& p,
  441. UNDIRECTED_GRAPH& g)
  442. {
  443. return g.add_vertex(p);
  444. }
  445. template < UNDIRECTED_GRAPH_PARAMS >
  446. inline void clear_vertex(
  447. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
  448. {
  449. return g.clear_vertex(v);
  450. }
  451. template < UNDIRECTED_GRAPH_PARAMS >
  452. inline void remove_vertex(
  453. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
  454. {
  455. return g.remove_vertex(v);
  456. }
  457. template < UNDIRECTED_GRAPH_PARAMS >
  458. inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge(
  459. typename UNDIRECTED_GRAPH::vertex_descriptor u,
  460. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
  461. {
  462. return g.add_edge(u, v);
  463. }
  464. template < UNDIRECTED_GRAPH_PARAMS >
  465. inline std::pair< typename UNDIRECTED_GRAPH::edge_descriptor, bool > add_edge(
  466. typename UNDIRECTED_GRAPH::vertex_descriptor u,
  467. typename UNDIRECTED_GRAPH::vertex_descriptor v,
  468. typename UNDIRECTED_GRAPH::edge_property_type const& p, UNDIRECTED_GRAPH& g)
  469. {
  470. return g.add_edge(u, v, p);
  471. }
  472. template < UNDIRECTED_GRAPH_PARAMS >
  473. inline void remove_edge(typename UNDIRECTED_GRAPH::vertex_descriptor u,
  474. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH& g)
  475. {
  476. return g.remove_edge(u, v);
  477. }
  478. template < UNDIRECTED_GRAPH_PARAMS >
  479. inline void remove_edge(
  480. typename UNDIRECTED_GRAPH::edge_descriptor e, UNDIRECTED_GRAPH& g)
  481. {
  482. return g.remove_edge(e);
  483. }
  484. template < UNDIRECTED_GRAPH_PARAMS >
  485. inline void remove_edge(
  486. typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
  487. {
  488. return g.remove_edge(i);
  489. }
  490. template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
  491. inline void remove_edge_if(Predicate pred, UNDIRECTED_GRAPH& g)
  492. {
  493. return remove_edge_if(pred, g.impl());
  494. }
  495. template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
  496. inline void remove_incident_edge_if(
  497. typename UNDIRECTED_GRAPH::vertex_descriptor v, Predicate pred,
  498. UNDIRECTED_GRAPH& g)
  499. {
  500. return remove_out_edge_if(v, pred, g.impl());
  501. }
  502. template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
  503. inline void remove_out_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
  504. Predicate pred, UNDIRECTED_GRAPH& g)
  505. {
  506. return remove_out_edge_if(v, pred, g.impl());
  507. }
  508. template < UNDIRECTED_GRAPH_PARAMS, class Predicate >
  509. inline void remove_in_edge_if(typename UNDIRECTED_GRAPH::vertex_descriptor v,
  510. Predicate pred, UNDIRECTED_GRAPH& g)
  511. {
  512. return remove_in_edge_if(v, pred, g.impl());
  513. }
  514. template < UNDIRECTED_GRAPH_PARAMS, typename Property >
  515. struct property_map< UNDIRECTED_GRAPH, Property >
  516. : property_map< typename UNDIRECTED_GRAPH::graph_type, Property >
  517. {
  518. };
  519. template < UNDIRECTED_GRAPH_PARAMS >
  520. struct property_map< UNDIRECTED_GRAPH, vertex_all_t >
  521. {
  522. typedef transform_value_property_map< detail::remove_first_property,
  523. typename property_map< typename UNDIRECTED_GRAPH::graph_type,
  524. vertex_all_t >::const_type >
  525. const_type;
  526. typedef transform_value_property_map< detail::remove_first_property,
  527. typename property_map< typename UNDIRECTED_GRAPH::graph_type,
  528. vertex_all_t >::type >
  529. type;
  530. };
  531. template < UNDIRECTED_GRAPH_PARAMS >
  532. struct property_map< UNDIRECTED_GRAPH, edge_all_t >
  533. {
  534. typedef transform_value_property_map< detail::remove_first_property,
  535. typename property_map< typename UNDIRECTED_GRAPH::graph_type,
  536. edge_all_t >::const_type >
  537. const_type;
  538. typedef transform_value_property_map< detail::remove_first_property,
  539. typename property_map< typename UNDIRECTED_GRAPH::graph_type,
  540. edge_all_t >::type >
  541. type;
  542. };
  543. // PropertyGraph concepts
  544. template < UNDIRECTED_GRAPH_PARAMS, typename Property >
  545. inline typename property_map< UNDIRECTED_GRAPH, Property >::type get(
  546. Property p, UNDIRECTED_GRAPH& g)
  547. {
  548. return get(p, g.impl());
  549. }
  550. template < UNDIRECTED_GRAPH_PARAMS, typename Property >
  551. inline typename property_map< UNDIRECTED_GRAPH, Property >::const_type get(
  552. Property p, UNDIRECTED_GRAPH const& g)
  553. {
  554. return get(p, g.impl());
  555. }
  556. template < UNDIRECTED_GRAPH_PARAMS >
  557. inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type get(
  558. vertex_all_t, UNDIRECTED_GRAPH& g)
  559. {
  560. return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::type(
  561. detail::remove_first_property(), get(vertex_all, g.impl()));
  562. }
  563. template < UNDIRECTED_GRAPH_PARAMS >
  564. inline typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type get(
  565. vertex_all_t, UNDIRECTED_GRAPH const& g)
  566. {
  567. return typename property_map< UNDIRECTED_GRAPH, vertex_all_t >::const_type(
  568. detail::remove_first_property(), get(vertex_all, g.impl()));
  569. }
  570. template < UNDIRECTED_GRAPH_PARAMS >
  571. inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type get(
  572. edge_all_t, UNDIRECTED_GRAPH& g)
  573. {
  574. return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::type(
  575. detail::remove_first_property(), get(edge_all, g.impl()));
  576. }
  577. template < UNDIRECTED_GRAPH_PARAMS >
  578. inline typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type get(
  579. edge_all_t, UNDIRECTED_GRAPH const& g)
  580. {
  581. return typename property_map< UNDIRECTED_GRAPH, edge_all_t >::const_type(
  582. detail::remove_first_property(), get(edge_all, g.impl()));
  583. }
  584. template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key >
  585. inline typename property_traits< typename property_map<
  586. typename UNDIRECTED_GRAPH::graph_type, Property >::const_type >::value_type
  587. get(Property p, UNDIRECTED_GRAPH const& g, Key const& k)
  588. {
  589. return get(p, g.impl(), k);
  590. }
  591. template < UNDIRECTED_GRAPH_PARAMS, typename Key >
  592. inline typename property_traits<
  593. typename property_map< typename UNDIRECTED_GRAPH::graph_type,
  594. vertex_all_t >::const_type >::value_type
  595. get(vertex_all_t, UNDIRECTED_GRAPH const& g, Key const& k)
  596. {
  597. return get(vertex_all, g.impl(), k).m_base;
  598. }
  599. template < UNDIRECTED_GRAPH_PARAMS, typename Key >
  600. inline typename property_traits<
  601. typename property_map< typename UNDIRECTED_GRAPH::graph_type,
  602. edge_all_t >::const_type >::value_type
  603. get(edge_all_t, UNDIRECTED_GRAPH const& g, Key const& k)
  604. {
  605. return get(edge_all, g.impl(), k).m_base;
  606. }
  607. template < UNDIRECTED_GRAPH_PARAMS, typename Property, typename Key,
  608. typename Value >
  609. inline void put(Property p, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
  610. {
  611. put(p, g.impl(), k, v);
  612. }
  613. template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value >
  614. inline void put(vertex_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
  615. {
  616. put(vertex_all, g.impl(), k,
  617. typename UNDIRECTED_GRAPH::internal_vertex_property(
  618. get(vertex_index, g.impl(), k), v));
  619. }
  620. template < UNDIRECTED_GRAPH_PARAMS, typename Key, typename Value >
  621. inline void put(edge_all_t, UNDIRECTED_GRAPH& g, Key const& k, Value const& v)
  622. {
  623. put(edge_all, g.impl(), k,
  624. typename UNDIRECTED_GRAPH::internal_vertex_property(
  625. get(edge_index, g.impl(), k), v));
  626. }
  627. template < UNDIRECTED_GRAPH_PARAMS, class Property >
  628. inline typename graph_property< UNDIRECTED_GRAPH, Property >::type&
  629. get_property(UNDIRECTED_GRAPH& g, Property p)
  630. {
  631. return get_property(g.impl(), p);
  632. }
  633. template < UNDIRECTED_GRAPH_PARAMS, class Property >
  634. inline typename graph_property< UNDIRECTED_GRAPH, Property >::type const&
  635. get_property(UNDIRECTED_GRAPH const& g, Property p)
  636. {
  637. return get_property(g.impl(), p);
  638. }
  639. template < UNDIRECTED_GRAPH_PARAMS, class Property, class Value >
  640. inline void set_property(UNDIRECTED_GRAPH& g, Property p, Value v)
  641. {
  642. return set_property(g.impl(), p, v);
  643. }
  644. // Indexed Vertex graph
  645. template < UNDIRECTED_GRAPH_PARAMS >
  646. inline typename UNDIRECTED_GRAPH::vertex_index_type get_vertex_index(
  647. typename UNDIRECTED_GRAPH::vertex_descriptor v, UNDIRECTED_GRAPH const& g)
  648. {
  649. return get(vertex_index, g, v);
  650. }
  651. template < UNDIRECTED_GRAPH_PARAMS >
  652. typename UNDIRECTED_GRAPH::vertex_index_type max_vertex_index(
  653. UNDIRECTED_GRAPH const& g)
  654. {
  655. return g.max_vertex_index();
  656. }
  657. template < UNDIRECTED_GRAPH_PARAMS >
  658. inline void renumber_vertex_indices(UNDIRECTED_GRAPH& g)
  659. {
  660. g.renumber_vertex_indices();
  661. }
  662. template < UNDIRECTED_GRAPH_PARAMS >
  663. inline void remove_vertex_and_renumber_indices(
  664. typename UNDIRECTED_GRAPH::vertex_iterator i, UNDIRECTED_GRAPH& g)
  665. {
  666. g.remove_vertex_and_renumber_indices(i);
  667. }
  668. // Edge index management
  669. template < UNDIRECTED_GRAPH_PARAMS >
  670. inline typename UNDIRECTED_GRAPH::edge_index_type get_edge_index(
  671. typename UNDIRECTED_GRAPH::edge_descriptor v, UNDIRECTED_GRAPH const& g)
  672. {
  673. return get(edge_index, g, v);
  674. }
  675. template < UNDIRECTED_GRAPH_PARAMS >
  676. typename UNDIRECTED_GRAPH::edge_index_type max_edge_index(
  677. UNDIRECTED_GRAPH const& g)
  678. {
  679. return g.max_edge_index();
  680. }
  681. template < UNDIRECTED_GRAPH_PARAMS >
  682. inline void renumber_edge_indices(UNDIRECTED_GRAPH& g)
  683. {
  684. g.renumber_edge_indices();
  685. }
  686. template < UNDIRECTED_GRAPH_PARAMS >
  687. inline void remove_edge_and_renumber_indices(
  688. typename UNDIRECTED_GRAPH::edge_iterator i, UNDIRECTED_GRAPH& g)
  689. {
  690. g.remove_edge_and_renumber_indices(i);
  691. }
  692. // Index management
  693. template < UNDIRECTED_GRAPH_PARAMS >
  694. inline void renumber_indices(UNDIRECTED_GRAPH& g)
  695. {
  696. g.renumber_indices();
  697. }
  698. // Mutability Traits
  699. template < UNDIRECTED_GRAPH_PARAMS >
  700. struct graph_mutability_traits< UNDIRECTED_GRAPH >
  701. {
  702. typedef mutable_property_graph_tag category;
  703. };
  704. #undef UNDIRECTED_GRAPH_PARAMS
  705. #undef UNDIRECTED_GRAPH
  706. } /* namespace boost */
  707. #endif