compressed_sparse_row_graph.hpp 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606
  1. // Copyright 2005-2009 The Trustees of Indiana University.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Jeremiah Willcock
  6. // Douglas Gregor
  7. // Andrew Lumsdaine
  8. // Compressed sparse row graph type
  9. #ifndef BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
  10. #define BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
  11. #include <vector>
  12. #include <utility>
  13. #include <algorithm>
  14. #include <climits>
  15. #include <boost/assert.hpp>
  16. #include <iterator>
  17. #if 0
  18. #include <iostream> // For some debugging code below
  19. #endif
  20. #include <boost/graph/graph_traits.hpp>
  21. #include <boost/graph/properties.hpp>
  22. #include <boost/graph/filtered_graph.hpp> // For keep_all
  23. #include <boost/graph/detail/indexed_properties.hpp>
  24. #include <boost/graph/detail/compressed_sparse_row_struct.hpp>
  25. #include <boost/graph/iteration_macros.hpp>
  26. #include <boost/iterator/counting_iterator.hpp>
  27. #include <boost/iterator/reverse_iterator.hpp>
  28. #include <boost/iterator/zip_iterator.hpp>
  29. #include <boost/iterator/transform_iterator.hpp>
  30. #include <boost/tuple/tuple.hpp>
  31. #include <boost/property_map/property_map.hpp>
  32. #include <boost/integer.hpp>
  33. #include <boost/iterator/iterator_facade.hpp>
  34. #include <boost/mpl/if.hpp>
  35. #include <boost/utility/enable_if.hpp>
  36. #include <boost/graph/graph_selectors.hpp>
  37. #include <boost/graph/detail/is_distributed_selector.hpp>
  38. #include <boost/graph/properties.hpp>
  39. #include <boost/static_assert.hpp>
  40. #include <boost/functional/hash.hpp>
  41. #include <boost/next_prior.hpp>
  42. #include <boost/property_map/transform_value_property_map.hpp>
  43. #include <boost/mpl/print.hpp>
  44. namespace boost {
  45. // A tag type indicating that the graph in question is a compressed
  46. // sparse row graph. This is an internal detail of the BGL.
  47. struct csr_graph_tag;
  48. // A type (edges_are_sorted_t) and a value (edges_are_sorted) used to indicate
  49. // that the edge list passed into the CSR graph is already sorted by source
  50. // vertex.
  51. enum edges_are_sorted_t {edges_are_sorted};
  52. // A type (edges_are_sorted_global_t) and a value (edges_are_sorted_global)
  53. // used to indicate that the edge list passed into the CSR graph is already
  54. // sorted by source vertex.
  55. enum edges_are_sorted_global_t {edges_are_sorted_global};
  56. // A type (edges_are_unsorted_t) and a value (edges_are_unsorted) used to
  57. // indicate that the edge list passed into the CSR graph is not sorted by
  58. // source vertex. This version caches the edge information in memory, and thus
  59. // requires only a single pass over the input data.
  60. enum edges_are_unsorted_t {edges_are_unsorted};
  61. // A type (edges_are_unsorted_multi_pass_t) and a value
  62. // (edges_are_unsorted_multi_pass) used to indicate that the edge list passed
  63. // into the CSR graph is not sorted by source vertex. This version uses less
  64. // memory but requires multi-pass capability on the iterators.
  65. enum edges_are_unsorted_multi_pass_t {edges_are_unsorted_multi_pass};
  66. // A type (edges_are_unsorted_multi_pass_global_t) and a value
  67. // (edges_are_unsorted_multi_pass_global) used to indicate that the edge list
  68. // passed into the CSR graph is not sorted by source vertex. This version uses
  69. // less memory but requires multi-pass capability on the iterators. The
  70. // global mapping and filtering is done here because it is often faster and it
  71. // greatly simplifies handling of edge properties.
  72. enum edges_are_unsorted_multi_pass_global_t {edges_are_unsorted_multi_pass_global};
  73. // A type (construct_inplace_from_sources_and_targets_t) and a value
  74. // (construct_inplace_from_sources_and_targets) used to indicate that mutable
  75. // vectors of sources and targets (and possibly edge properties) are being used
  76. // to construct the CSR graph. These vectors are sorted in-place and then the
  77. // targets and properties are swapped into the graph data structure.
  78. enum construct_inplace_from_sources_and_targets_t {construct_inplace_from_sources_and_targets};
  79. // A type (construct_inplace_from_sources_and_targets_global_t) and a value
  80. // (construct_inplace_from_sources_and_targets_global) used to indicate that
  81. // mutable vectors of sources and targets (and possibly edge properties) are
  82. // being used to construct the CSR graph. These vectors are sorted in-place
  83. // and then the targets and properties are swapped into the graph data
  84. // structure. It is assumed that global indices (for distributed CSR) are
  85. // used, and a map is required to convert those to local indices. This
  86. // constructor is intended for internal use by the various CSR graphs
  87. // (sequential and distributed).
  88. enum construct_inplace_from_sources_and_targets_global_t {construct_inplace_from_sources_and_targets_global};
  89. // A type (edges_are_unsorted_global_t) and a value (edges_are_unsorted_global)
  90. // used to indicate that the edge list passed into the CSR graph is not sorted
  91. // by source vertex. The data is also stored using global vertex indices, and
  92. // must be filtered to choose only local vertices. This constructor caches the
  93. // edge information in memory, and thus requires only a single pass over the
  94. // input data. This constructor is intended for internal use by the
  95. // distributed CSR constructors.
  96. enum edges_are_unsorted_global_t {edges_are_unsorted_global};
  97. /****************************************************************************
  98. * Local helper macros to reduce typing and clutter later on. *
  99. ****************************************************************************/
  100. #define BOOST_CSR_GRAPH_TEMPLATE_PARMS \
  101. typename Directed, typename VertexProperty, typename EdgeProperty, \
  102. typename GraphProperty, typename Vertex, typename EdgeIndex
  103. #define BOOST_CSR_GRAPH_TYPE \
  104. compressed_sparse_row_graph<Directed, VertexProperty, EdgeProperty, \
  105. GraphProperty, Vertex, EdgeIndex>
  106. #define BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS \
  107. typename VertexProperty, typename EdgeProperty, \
  108. typename GraphProperty, typename Vertex, typename EdgeIndex
  109. #define BOOST_DIR_CSR_GRAPH_TYPE \
  110. compressed_sparse_row_graph<directedS, VertexProperty, EdgeProperty, \
  111. GraphProperty, Vertex, EdgeIndex>
  112. #define BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS \
  113. typename VertexProperty, typename EdgeProperty, \
  114. typename GraphProperty, typename Vertex, typename EdgeIndex
  115. #define BOOST_BIDIR_CSR_GRAPH_TYPE \
  116. compressed_sparse_row_graph<bidirectionalS, VertexProperty, EdgeProperty, \
  117. GraphProperty, Vertex, EdgeIndex>
  118. namespace detail {
  119. template <typename T>
  120. struct default_construct_iterator: public boost::iterator_facade<default_construct_iterator<T>, T, boost::random_access_traversal_tag, const T&> {
  121. typedef boost::iterator_facade<default_construct_iterator<T>, T, std::random_access_iterator_tag, const T&> base_type;
  122. T saved_value;
  123. const T& dereference() const {return saved_value;}
  124. bool equal(default_construct_iterator /*i*/) const {return true;}
  125. void increment() {}
  126. void decrement() {}
  127. void advance(typename base_type::difference_type) {}
  128. typename base_type::difference_type distance_to(default_construct_iterator) const {return 0;}
  129. };
  130. template <typename Less>
  131. struct compare_first {
  132. Less less;
  133. compare_first(Less less = Less()): less(less) {}
  134. template <typename Tuple>
  135. bool operator()(const Tuple& a, const Tuple& b) const {
  136. return less(a.template get<0>(), b.template get<0>());
  137. }
  138. };
  139. template <int N, typename Result>
  140. struct my_tuple_get_class {
  141. typedef const Result& result_type;
  142. template <typename Tuple>
  143. result_type operator()(const Tuple& t) const {
  144. return t.template get<N>();
  145. }
  146. };
  147. }
  148. /** Compressed sparse row graph.
  149. *
  150. * Vertex and EdgeIndex should be unsigned integral types and should
  151. * specialize numeric_limits.
  152. */
  153. template<typename Directed = directedS,
  154. typename VertexProperty = no_property,
  155. typename EdgeProperty = no_property,
  156. typename GraphProperty = no_property,
  157. typename Vertex = std::size_t,
  158. typename EdgeIndex = Vertex>
  159. class compressed_sparse_row_graph; // Not defined
  160. template<typename VertexProperty,
  161. typename EdgeProperty,
  162. typename GraphProperty,
  163. typename Vertex,
  164. typename EdgeIndex>
  165. class compressed_sparse_row_graph<directedS, VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex>
  166. : public detail::indexed_vertex_properties<BOOST_DIR_CSR_GRAPH_TYPE,
  167. VertexProperty, Vertex, typed_identity_property_map<Vertex> >
  168. {
  169. public:
  170. typedef detail::indexed_vertex_properties<compressed_sparse_row_graph,
  171. VertexProperty, Vertex, typed_identity_property_map<Vertex> >
  172. inherited_vertex_properties;
  173. // Some tests to prevent use of "void" is a property type (as was done in some test cases):
  174. BOOST_STATIC_ASSERT((!is_same<VertexProperty, void>::value));
  175. BOOST_STATIC_ASSERT((!is_same<EdgeProperty, void>::value));
  176. BOOST_STATIC_ASSERT((!is_same<GraphProperty, void>::value));
  177. public:
  178. // For Property Graph
  179. typedef GraphProperty graph_property_type;
  180. typedef typename lookup_one_property<GraphProperty, graph_bundle_t>::type graph_bundled;
  181. typedef detail::compressed_sparse_row_structure<EdgeProperty, Vertex, EdgeIndex> forward_type;
  182. public:
  183. /* At this time, the compressed sparse row graph can only be used to
  184. * create directed and bidirectional graphs. In the future,
  185. * undirected CSR graphs will also be supported.
  186. */
  187. // BOOST_STATIC_ASSERT((is_same<Directed, directedS>::value));
  188. // Concept requirements:
  189. // For Graph
  190. typedef Vertex vertex_descriptor;
  191. typedef detail::csr_edge_descriptor<Vertex, EdgeIndex> edge_descriptor;
  192. typedef directed_tag directed_category;
  193. typedef allow_parallel_edge_tag edge_parallel_category;
  194. class traversal_category: public incidence_graph_tag,
  195. public adjacency_graph_tag,
  196. public vertex_list_graph_tag,
  197. public edge_list_graph_tag {};
  198. static vertex_descriptor null_vertex() { return vertex_descriptor(-1); }
  199. // For VertexListGraph
  200. typedef counting_iterator<Vertex> vertex_iterator;
  201. typedef Vertex vertices_size_type;
  202. // For EdgeListGraph
  203. typedef EdgeIndex edges_size_type;
  204. // For IncidenceGraph
  205. typedef detail::csr_out_edge_iterator<compressed_sparse_row_graph> out_edge_iterator;
  206. typedef EdgeIndex degree_size_type;
  207. // For AdjacencyGraph
  208. typedef typename std::vector<Vertex>::const_iterator adjacency_iterator;
  209. // For EdgeListGraph
  210. typedef detail::csr_edge_iterator<compressed_sparse_row_graph> edge_iterator;
  211. // For BidirectionalGraph (not implemented)
  212. typedef void in_edge_iterator;
  213. // For internal use
  214. typedef csr_graph_tag graph_tag;
  215. typedef typename forward_type::inherited_edge_properties::edge_bundled edge_bundled;
  216. typedef typename forward_type::inherited_edge_properties::edge_push_back_type edge_push_back_type;
  217. typedef typename forward_type::inherited_edge_properties::edge_property_type edge_property_type;
  218. // Constructors
  219. // Default constructor: an empty graph.
  220. compressed_sparse_row_graph(): m_property() {}
  221. // With numverts vertices
  222. compressed_sparse_row_graph(vertices_size_type numverts)
  223. : inherited_vertex_properties(numverts), m_forward(numverts) {}
  224. // From number of vertices and unsorted list of edges
  225. template <typename MultiPassInputIterator>
  226. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  227. MultiPassInputIterator edge_begin,
  228. MultiPassInputIterator edge_end,
  229. vertices_size_type numverts,
  230. const GraphProperty& prop = GraphProperty())
  231. : inherited_vertex_properties(numverts), m_property(prop)
  232. {
  233. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numverts, typed_identity_property_map<vertices_size_type>(), keep_all());
  234. }
  235. // From number of vertices and unsorted list of edges, plus edge properties
  236. template <typename MultiPassInputIterator, typename EdgePropertyIterator>
  237. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  238. MultiPassInputIterator edge_begin,
  239. MultiPassInputIterator edge_end,
  240. EdgePropertyIterator ep_iter,
  241. vertices_size_type numverts,
  242. const GraphProperty& prop = GraphProperty())
  243. : inherited_vertex_properties(numverts), m_forward(), m_property(prop)
  244. {
  245. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numverts, typed_identity_property_map<vertices_size_type>(), keep_all());
  246. }
  247. // From number of vertices and unsorted list of edges, with filter and
  248. // global-to-local map
  249. template <typename MultiPassInputIterator, typename GlobalToLocal, typename SourcePred>
  250. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t,
  251. MultiPassInputIterator edge_begin,
  252. MultiPassInputIterator edge_end,
  253. vertices_size_type numlocalverts,
  254. const GlobalToLocal& global_to_local,
  255. const SourcePred& source_pred,
  256. const GraphProperty& prop = GraphProperty())
  257. : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop)
  258. {
  259. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numlocalverts, global_to_local, source_pred);
  260. }
  261. // From number of vertices and unsorted list of edges, plus edge properties,
  262. // with filter and global-to-local map
  263. template <typename MultiPassInputIterator, typename EdgePropertyIterator, typename GlobalToLocal, typename SourcePred>
  264. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t,
  265. MultiPassInputIterator edge_begin,
  266. MultiPassInputIterator edge_end,
  267. EdgePropertyIterator ep_iter,
  268. vertices_size_type numlocalverts,
  269. const GlobalToLocal& global_to_local,
  270. const SourcePred& source_pred,
  271. const GraphProperty& prop = GraphProperty())
  272. : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop)
  273. {
  274. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numlocalverts, global_to_local, source_pred);
  275. }
  276. // From number of vertices and sorted list of edges (new interface)
  277. template<typename InputIterator>
  278. compressed_sparse_row_graph(edges_are_sorted_t,
  279. InputIterator edge_begin, InputIterator edge_end,
  280. vertices_size_type numverts,
  281. edges_size_type numedges = 0,
  282. const GraphProperty& prop = GraphProperty())
  283. : m_property(prop)
  284. {
  285. m_forward.assign_from_sorted_edges(edge_begin, edge_end, typed_identity_property_map<vertices_size_type>(), keep_all(), numverts, numedges);
  286. inherited_vertex_properties::resize(numverts);
  287. }
  288. // From number of vertices and sorted list of edges (new interface)
  289. template<typename InputIterator, typename EdgePropertyIterator>
  290. compressed_sparse_row_graph(edges_are_sorted_t,
  291. InputIterator edge_begin, InputIterator edge_end,
  292. EdgePropertyIterator ep_iter,
  293. vertices_size_type numverts,
  294. edges_size_type numedges = 0,
  295. const GraphProperty& prop = GraphProperty())
  296. : m_property(prop)
  297. {
  298. m_forward.assign_from_sorted_edges(edge_begin, edge_end, ep_iter, typed_identity_property_map<vertices_size_type>(), keep_all(), numverts, numedges);
  299. inherited_vertex_properties::resize(numverts);
  300. }
  301. // From number of vertices and sorted list of edges, filtered and global (new interface)
  302. template<typename InputIterator, typename GlobalToLocal, typename SourcePred>
  303. compressed_sparse_row_graph(edges_are_sorted_global_t,
  304. InputIterator edge_begin, InputIterator edge_end,
  305. const GlobalToLocal& global_to_local,
  306. const SourcePred& source_pred,
  307. vertices_size_type numverts,
  308. const GraphProperty& prop = GraphProperty())
  309. : m_property(prop)
  310. {
  311. m_forward.assign_from_sorted_edges(edge_begin, edge_end, global_to_local, source_pred, numverts, 0);
  312. inherited_vertex_properties::resize(numverts);
  313. }
  314. // From number of vertices and sorted list of edges (new interface)
  315. template<typename InputIterator, typename EdgePropertyIterator, typename GlobalToLocal, typename SourcePred>
  316. compressed_sparse_row_graph(edges_are_sorted_global_t,
  317. InputIterator edge_begin, InputIterator edge_end,
  318. EdgePropertyIterator ep_iter,
  319. const GlobalToLocal& global_to_local,
  320. const SourcePred& source_pred,
  321. vertices_size_type numverts,
  322. const GraphProperty& prop = GraphProperty())
  323. : m_property(prop)
  324. {
  325. m_forward.assign_from_sorted_edges(edge_begin, edge_end, ep_iter, global_to_local, source_pred, numverts, 0);
  326. inherited_vertex_properties::resize(numverts);
  327. }
  328. // From number of vertices and mutable vectors of sources and targets;
  329. // vectors are returned with unspecified contents but are guaranteed not to
  330. // share storage with the constructed graph.
  331. compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_t,
  332. std::vector<vertex_descriptor>& sources,
  333. std::vector<vertex_descriptor>& targets,
  334. vertices_size_type numverts,
  335. const GraphProperty& prop = GraphProperty())
  336. : inherited_vertex_properties(numverts), m_property(prop)
  337. {
  338. m_forward.assign_sources_and_targets_global(sources, targets, numverts, boost::typed_identity_property_map<vertices_size_type>());
  339. }
  340. // From number of vertices and mutable vectors of sources and targets,
  341. // expressed with global vertex indices; vectors are returned with
  342. // unspecified contents but are guaranteed not to share storage with the
  343. // constructed graph. This constructor should only be used by the
  344. // distributed CSR graph.
  345. template <typename GlobalToLocal>
  346. compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_global_t,
  347. std::vector<vertex_descriptor>& sources,
  348. std::vector<vertex_descriptor>& targets,
  349. vertices_size_type numlocalverts,
  350. GlobalToLocal global_to_local,
  351. const GraphProperty& prop = GraphProperty())
  352. : inherited_vertex_properties(numlocalverts), m_property(prop)
  353. {
  354. m_forward.assign_sources_and_targets_global(sources, targets, numlocalverts, global_to_local);
  355. }
  356. // From number of vertices and mutable vectors of sources, targets, and edge
  357. // properties; vectors are returned with unspecified contents but are
  358. // guaranteed not to share storage with the constructed graph.
  359. compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_t,
  360. std::vector<vertex_descriptor>& sources,
  361. std::vector<vertex_descriptor>& targets,
  362. std::vector<typename forward_type::inherited_edge_properties::edge_bundled>& edge_props,
  363. vertices_size_type numverts,
  364. const GraphProperty& prop = GraphProperty())
  365. : inherited_vertex_properties(numverts), m_property(prop)
  366. {
  367. m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numverts, boost::typed_identity_property_map<vertices_size_type>());
  368. }
  369. // From number of vertices and mutable vectors of sources and targets and
  370. // edge properties, expressed with global vertex indices; vectors are
  371. // returned with unspecified contents but are guaranteed not to share
  372. // storage with the constructed graph. This constructor should only be used
  373. // by the distributed CSR graph.
  374. template <typename GlobalToLocal>
  375. compressed_sparse_row_graph(construct_inplace_from_sources_and_targets_global_t,
  376. std::vector<vertex_descriptor>& sources,
  377. std::vector<vertex_descriptor>& targets,
  378. std::vector<typename forward_type::inherited_edge_properties::edge_bundled>& edge_props,
  379. vertices_size_type numlocalverts,
  380. GlobalToLocal global_to_local,
  381. const GraphProperty& prop = GraphProperty())
  382. : inherited_vertex_properties(numlocalverts), m_property(prop)
  383. {
  384. m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numlocalverts, global_to_local);
  385. }
  386. // From number of vertices and single-pass range of unsorted edges. Data is
  387. // cached in coordinate form before creating the actual graph.
  388. template<typename InputIterator>
  389. compressed_sparse_row_graph(edges_are_unsorted_t,
  390. InputIterator edge_begin, InputIterator edge_end,
  391. vertices_size_type numverts,
  392. const GraphProperty& prop = GraphProperty())
  393. : inherited_vertex_properties(numverts), m_property(prop)
  394. {
  395. std::vector<vertex_descriptor> sources, targets;
  396. boost::graph::detail::split_into_separate_coords
  397. (edge_begin, edge_end, sources, targets);
  398. m_forward.assign_sources_and_targets_global(sources, targets, numverts, boost::typed_identity_property_map<vertices_size_type>());
  399. }
  400. // From number of vertices and single-pass range of unsorted edges and
  401. // single-pass range of edge properties. Data is cached in coordinate form
  402. // before creating the actual graph.
  403. template<typename InputIterator, typename EdgePropertyIterator>
  404. compressed_sparse_row_graph(edges_are_unsorted_t,
  405. InputIterator edge_begin, InputIterator edge_end,
  406. EdgePropertyIterator ep_iter,
  407. vertices_size_type numverts,
  408. const GraphProperty& prop = GraphProperty())
  409. : inherited_vertex_properties(numverts), m_property(prop)
  410. {
  411. std::vector<vertex_descriptor> sources, targets;
  412. boost::graph::detail::split_into_separate_coords
  413. (edge_begin, edge_end, sources, targets);
  414. size_t numedges = sources.size();
  415. std::vector<typename forward_type::inherited_edge_properties::edge_bundled> edge_props(numedges);
  416. for (size_t i = 0; i < numedges; ++i) {
  417. edge_props[i] = *ep_iter++;
  418. }
  419. m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numverts, boost::typed_identity_property_map<vertices_size_type>());
  420. }
  421. // From number of vertices and single-pass range of unsorted edges. Data is
  422. // cached in coordinate form before creating the actual graph. Edges are
  423. // filtered and transformed for use in a distributed graph.
  424. template<typename InputIterator, typename GlobalToLocal, typename SourcePred>
  425. compressed_sparse_row_graph(edges_are_unsorted_global_t,
  426. InputIterator edge_begin, InputIterator edge_end,
  427. vertices_size_type numlocalverts,
  428. GlobalToLocal global_to_local,
  429. const SourcePred& source_pred,
  430. const GraphProperty& prop = GraphProperty())
  431. : inherited_vertex_properties(numlocalverts), m_property(prop)
  432. {
  433. std::vector<vertex_descriptor> sources, targets;
  434. boost::graph::detail::split_into_separate_coords_filtered
  435. (edge_begin, edge_end, sources, targets, source_pred);
  436. m_forward.assign_sources_and_targets_global(sources, targets, numlocalverts, global_to_local);
  437. }
  438. // From number of vertices and single-pass range of unsorted edges and
  439. // single-pass range of edge properties. Data is cached in coordinate form
  440. // before creating the actual graph. Edges are filtered and transformed for
  441. // use in a distributed graph.
  442. template<typename InputIterator, typename EdgePropertyIterator,
  443. typename GlobalToLocal, typename SourcePred>
  444. compressed_sparse_row_graph(edges_are_unsorted_global_t,
  445. InputIterator edge_begin, InputIterator edge_end,
  446. EdgePropertyIterator ep_iter,
  447. vertices_size_type numlocalverts,
  448. GlobalToLocal global_to_local,
  449. const SourcePred& source_pred,
  450. const GraphProperty& prop = GraphProperty())
  451. : inherited_vertex_properties(numlocalverts), m_property(prop)
  452. {
  453. std::vector<vertex_descriptor> sources, targets;
  454. std::vector<edge_bundled> edge_props;
  455. boost::graph::detail::split_into_separate_coords_filtered
  456. (edge_begin, edge_end, ep_iter, sources, targets, edge_props, source_pred);
  457. m_forward.assign_sources_and_targets_global(sources, targets, edge_props, numlocalverts, global_to_local);
  458. }
  459. // Requires IncidenceGraph and a vertex index map
  460. template<typename Graph, typename VertexIndexMap>
  461. compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi,
  462. vertices_size_type numverts,
  463. edges_size_type numedges)
  464. : m_property()
  465. {
  466. assign(g, vi, numverts, numedges);
  467. inherited_vertex_properties::resize(numverts);
  468. }
  469. // Requires VertexListGraph and EdgeListGraph
  470. template<typename Graph, typename VertexIndexMap>
  471. compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi)
  472. : m_property()
  473. {
  474. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  475. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  476. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  477. }
  478. vertices_size_type numverts = num_vertices(g);
  479. assign(g, vi, numverts, numedges);
  480. inherited_vertex_properties::resize(numverts);
  481. }
  482. // Requires vertex index map plus requirements of previous constructor
  483. template<typename Graph>
  484. explicit compressed_sparse_row_graph(const Graph& g)
  485. : m_property()
  486. {
  487. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  488. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  489. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  490. }
  491. assign(g, get(vertex_index, g), num_vertices(g), numedges);
  492. }
  493. // From any graph (slow and uses a lot of memory)
  494. // Requires IncidenceGraph and a vertex index map
  495. // Internal helper function
  496. // Note that numedges must be doubled for undirected source graphs
  497. template<typename Graph, typename VertexIndexMap>
  498. void
  499. assign(const Graph& g, const VertexIndexMap& vi,
  500. vertices_size_type numverts, edges_size_type numedges)
  501. {
  502. m_forward.assign(g, vi, numverts, numedges);
  503. inherited_vertex_properties::resize(numverts);
  504. }
  505. // Requires the above, plus VertexListGraph and EdgeListGraph
  506. template<typename Graph, typename VertexIndexMap>
  507. void assign(const Graph& g, const VertexIndexMap& vi)
  508. {
  509. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  510. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  511. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  512. }
  513. vertices_size_type numverts = num_vertices(g);
  514. m_forward.assign(g, vi, numverts, numedges);
  515. inherited_vertex_properties::resize(numverts);
  516. }
  517. // Requires the above, plus a vertex_index map.
  518. template<typename Graph>
  519. void assign(const Graph& g)
  520. {
  521. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  522. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  523. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  524. }
  525. vertices_size_type numverts = num_vertices(g);
  526. m_forward.assign(g, get(vertex_index, g), numverts, numedges);
  527. inherited_vertex_properties::resize(numverts);
  528. }
  529. // Add edges from a sorted (smallest sources first) range of pairs and edge
  530. // properties
  531. template <typename BidirectionalIteratorOrig, typename EPIterOrig,
  532. typename GlobalToLocal>
  533. void
  534. add_edges_sorted_internal(
  535. BidirectionalIteratorOrig first_sorted,
  536. BidirectionalIteratorOrig last_sorted,
  537. EPIterOrig ep_iter_sorted,
  538. const GlobalToLocal& global_to_local) {
  539. m_forward.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted, global_to_local);
  540. }
  541. template <typename BidirectionalIteratorOrig, typename EPIterOrig>
  542. void
  543. add_edges_sorted_internal(
  544. BidirectionalIteratorOrig first_sorted,
  545. BidirectionalIteratorOrig last_sorted,
  546. EPIterOrig ep_iter_sorted) {
  547. m_forward.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted, typed_identity_property_map<vertices_size_type>());
  548. }
  549. // Add edges from a sorted (smallest sources first) range of pairs
  550. template <typename BidirectionalIteratorOrig>
  551. void
  552. add_edges_sorted_internal(
  553. BidirectionalIteratorOrig first_sorted,
  554. BidirectionalIteratorOrig last_sorted) {
  555. m_forward.add_edges_sorted_internal(first_sorted, last_sorted, detail::default_construct_iterator<edge_bundled>());
  556. }
  557. template <typename BidirectionalIteratorOrig, typename GlobalToLocal>
  558. void
  559. add_edges_sorted_internal_global(
  560. BidirectionalIteratorOrig first_sorted,
  561. BidirectionalIteratorOrig last_sorted,
  562. const GlobalToLocal& global_to_local) {
  563. m_forward.add_edges_sorted_internal(first_sorted, last_sorted, detail::default_construct_iterator<edge_bundled>(), global_to_local);
  564. }
  565. template <typename BidirectionalIteratorOrig, typename EPIterOrig,
  566. typename GlobalToLocal>
  567. void
  568. add_edges_sorted_internal_global(
  569. BidirectionalIteratorOrig first_sorted,
  570. BidirectionalIteratorOrig last_sorted,
  571. EPIterOrig ep_iter_sorted,
  572. const GlobalToLocal& global_to_local) {
  573. m_forward.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted, global_to_local);
  574. }
  575. // Add edges from a range of (source, target) pairs that are unsorted
  576. template <typename InputIterator, typename GlobalToLocal>
  577. inline void
  578. add_edges_internal(InputIterator first, InputIterator last,
  579. const GlobalToLocal& global_to_local) {
  580. typedef compressed_sparse_row_graph Graph;
  581. typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
  582. typedef std::vector<std::pair<vertex_t, vertex_t> > edge_vector_t;
  583. edge_vector_t new_edges(first, last);
  584. if (new_edges.empty()) return;
  585. std::sort(new_edges.begin(), new_edges.end());
  586. this->add_edges_sorted_internal_global(new_edges.begin(), new_edges.end(), global_to_local);
  587. }
  588. template <typename InputIterator>
  589. inline void
  590. add_edges_internal(InputIterator first, InputIterator last) {
  591. this->add_edges_internal(first, last, typed_identity_property_map<vertices_size_type>());
  592. }
  593. // Add edges from a range of (source, target) pairs and edge properties that
  594. // are unsorted
  595. template <typename InputIterator, typename EPIterator, typename GlobalToLocal>
  596. inline void
  597. add_edges_internal(InputIterator first, InputIterator last,
  598. EPIterator ep_iter, EPIterator ep_iter_end,
  599. const GlobalToLocal& global_to_local) {
  600. typedef compressed_sparse_row_graph Graph;
  601. typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
  602. typedef std::pair<vertex_t, vertex_t> vertex_pair;
  603. typedef std::vector<
  604. boost::tuple<vertex_pair,
  605. edge_bundled> >
  606. edge_vector_t;
  607. edge_vector_t new_edges
  608. (boost::make_zip_iterator(boost::make_tuple(first, ep_iter)),
  609. boost::make_zip_iterator(boost::make_tuple(last, ep_iter_end)));
  610. if (new_edges.empty()) return;
  611. std::sort(new_edges.begin(), new_edges.end(),
  612. boost::detail::compare_first<
  613. std::less<vertex_pair> >());
  614. m_forward.add_edges_sorted_internal
  615. (boost::make_transform_iterator(
  616. new_edges.begin(),
  617. boost::detail::my_tuple_get_class<0, vertex_pair>()),
  618. boost::make_transform_iterator(
  619. new_edges.end(),
  620. boost::detail::my_tuple_get_class<0, vertex_pair>()),
  621. boost::make_transform_iterator(
  622. new_edges.begin(),
  623. boost::detail::my_tuple_get_class
  624. <1, edge_bundled>()),
  625. global_to_local);
  626. }
  627. // Add edges from a range of (source, target) pairs and edge properties that
  628. // are unsorted
  629. template <typename InputIterator, typename EPIterator>
  630. inline void
  631. add_edges_internal(InputIterator first, InputIterator last,
  632. EPIterator ep_iter, EPIterator ep_iter_end) {
  633. this->add_edges_internal(first, last, ep_iter, ep_iter_end, typed_identity_property_map<vertices_size_type>());
  634. }
  635. using inherited_vertex_properties::operator[];
  636. // Directly access a edge or edge bundle
  637. edge_push_back_type& operator[](const edge_descriptor& v)
  638. { return m_forward.m_edge_properties[get(edge_index, *this, v)]; }
  639. const edge_push_back_type& operator[](const edge_descriptor& v) const
  640. { return m_forward.m_edge_properties[get(edge_index, *this, v)]; }
  641. // Directly access a graph bundle
  642. graph_bundled& operator[](graph_bundle_t)
  643. { return get_property(*this); }
  644. const graph_bundled& operator[](graph_bundle_t) const
  645. { return get_property(*this); }
  646. // private: non-portable, requires friend templates
  647. inherited_vertex_properties& vertex_properties() {return *this;}
  648. const inherited_vertex_properties& vertex_properties() const {return *this;}
  649. typename forward_type::inherited_edge_properties& edge_properties() { return m_forward; }
  650. const typename forward_type::inherited_edge_properties& edge_properties() const { return m_forward; }
  651. forward_type m_forward;
  652. GraphProperty m_property;
  653. };
  654. template<typename VertexProperty,
  655. typename EdgeProperty,
  656. typename GraphProperty,
  657. typename Vertex,
  658. typename EdgeIndex>
  659. class compressed_sparse_row_graph<bidirectionalS, VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex>
  660. : public detail::indexed_vertex_properties<BOOST_BIDIR_CSR_GRAPH_TYPE,
  661. VertexProperty, Vertex, typed_identity_property_map<Vertex> >
  662. {
  663. public:
  664. typedef detail::indexed_vertex_properties<compressed_sparse_row_graph,
  665. VertexProperty, Vertex, typed_identity_property_map<Vertex> >
  666. inherited_vertex_properties;
  667. public:
  668. // For Property Graph
  669. typedef GraphProperty graph_property_type;
  670. typedef typename lookup_one_property<GraphProperty, graph_bundle_t>::type graph_bundled;
  671. // typedef GraphProperty graph_property_type;
  672. typedef detail::compressed_sparse_row_structure<EdgeProperty, Vertex, EdgeIndex> forward_type;
  673. typedef EdgeIndex /* typename boost::mpl::if_c<boost::is_same<EdgeProperty, boost::no_property>, boost::no_property, EdgeIndex> */ backward_edge_property;
  674. typedef detail::compressed_sparse_row_structure<backward_edge_property, Vertex, EdgeIndex> backward_type;
  675. public:
  676. // Concept requirements:
  677. // For Graph
  678. typedef Vertex vertex_descriptor;
  679. typedef detail::csr_edge_descriptor<Vertex, EdgeIndex> edge_descriptor;
  680. typedef bidirectional_tag directed_category;
  681. typedef allow_parallel_edge_tag edge_parallel_category;
  682. class traversal_category: public bidirectional_graph_tag,
  683. public adjacency_graph_tag,
  684. public vertex_list_graph_tag,
  685. public edge_list_graph_tag {};
  686. static vertex_descriptor null_vertex() { return vertex_descriptor(-1); }
  687. // For VertexListGraph
  688. typedef counting_iterator<Vertex> vertex_iterator;
  689. typedef Vertex vertices_size_type;
  690. // For EdgeListGraph
  691. typedef EdgeIndex edges_size_type;
  692. // For IncidenceGraph
  693. typedef detail::csr_out_edge_iterator<compressed_sparse_row_graph> out_edge_iterator;
  694. typedef EdgeIndex degree_size_type;
  695. // For AdjacencyGraph
  696. typedef typename std::vector<Vertex>::const_iterator adjacency_iterator;
  697. // For EdgeListGraph
  698. typedef detail::csr_edge_iterator<compressed_sparse_row_graph> edge_iterator;
  699. // For BidirectionalGraph (not implemented)
  700. typedef detail::csr_in_edge_iterator<compressed_sparse_row_graph> in_edge_iterator;
  701. // For internal use
  702. typedef csr_graph_tag graph_tag;
  703. typedef typename forward_type::inherited_edge_properties::edge_bundled edge_bundled;
  704. typedef typename forward_type::inherited_edge_properties::edge_push_back_type edge_push_back_type;
  705. typedef typename forward_type::inherited_edge_properties::edge_property_type edge_property_type;
  706. // Constructors
  707. // Default constructor: an empty graph.
  708. compressed_sparse_row_graph(): m_property() {}
  709. // With numverts vertices
  710. compressed_sparse_row_graph(vertices_size_type numverts)
  711. : inherited_vertex_properties(numverts),
  712. m_forward(numverts), m_backward(numverts) {}
  713. private:
  714. void set_up_backward_property_links() {
  715. std::pair<edge_iterator, edge_iterator> e = edges(*this);
  716. m_backward.assign_unsorted_multi_pass_edges
  717. (detail::transpose_edges(
  718. detail::make_edge_to_index_pair_iter
  719. (*this, get(vertex_index, *this), e.first)),
  720. detail::transpose_edges(
  721. detail::make_edge_to_index_pair_iter
  722. (*this, get(vertex_index, *this), e.second)),
  723. boost::counting_iterator<EdgeIndex>(0),
  724. m_forward.m_rowstart.size() - 1,
  725. typed_identity_property_map<Vertex>(),
  726. keep_all());
  727. }
  728. public:
  729. // From number of vertices and unsorted list of edges
  730. template <typename MultiPassInputIterator>
  731. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  732. MultiPassInputIterator edge_begin,
  733. MultiPassInputIterator edge_end,
  734. vertices_size_type numverts,
  735. const GraphProperty& prop = GraphProperty())
  736. : inherited_vertex_properties(numverts), m_property(prop)
  737. {
  738. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numverts, typed_identity_property_map<Vertex>(), keep_all());
  739. set_up_backward_property_links();
  740. }
  741. // From number of vertices and unsorted list of edges, plus edge properties
  742. template <typename MultiPassInputIterator, typename EdgePropertyIterator>
  743. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
  744. MultiPassInputIterator edge_begin,
  745. MultiPassInputIterator edge_end,
  746. EdgePropertyIterator ep_iter,
  747. vertices_size_type numverts,
  748. const GraphProperty& prop = GraphProperty())
  749. : inherited_vertex_properties(numverts), m_forward(), m_property(prop)
  750. {
  751. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numverts, typed_identity_property_map<Vertex>(), keep_all());
  752. set_up_backward_property_links();
  753. }
  754. // From number of vertices and unsorted list of edges, with filter and
  755. // global-to-local map
  756. template <typename MultiPassInputIterator, typename GlobalToLocal, typename SourcePred>
  757. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t,
  758. MultiPassInputIterator edge_begin,
  759. MultiPassInputIterator edge_end,
  760. vertices_size_type numlocalverts,
  761. const GlobalToLocal& global_to_local,
  762. const SourcePred& source_pred,
  763. const GraphProperty& prop = GraphProperty())
  764. : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop)
  765. {
  766. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, numlocalverts, global_to_local, source_pred);
  767. set_up_backward_property_links();
  768. }
  769. // From number of vertices and unsorted list of edges, plus edge properties,
  770. // with filter and global-to-local map
  771. template <typename MultiPassInputIterator, typename EdgePropertyIterator, typename GlobalToLocal, typename SourcePred>
  772. compressed_sparse_row_graph(edges_are_unsorted_multi_pass_global_t,
  773. MultiPassInputIterator edge_begin,
  774. MultiPassInputIterator edge_end,
  775. EdgePropertyIterator ep_iter,
  776. vertices_size_type numlocalverts,
  777. const GlobalToLocal& global_to_local,
  778. const SourcePred& source_pred,
  779. const GraphProperty& prop = GraphProperty())
  780. : inherited_vertex_properties(numlocalverts), m_forward(), m_property(prop)
  781. {
  782. m_forward.assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numlocalverts, global_to_local, source_pred);
  783. set_up_backward_property_links();
  784. }
  785. // Requires IncidenceGraph and a vertex index map
  786. template<typename Graph, typename VertexIndexMap>
  787. compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi,
  788. vertices_size_type numverts,
  789. edges_size_type numedges)
  790. : m_property()
  791. {
  792. assign(g, vi, numverts, numedges);
  793. inherited_vertex_properties::resize(numverts);
  794. }
  795. // Requires VertexListGraph and EdgeListGraph
  796. template<typename Graph, typename VertexIndexMap>
  797. compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi)
  798. : m_property()
  799. {
  800. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  801. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  802. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  803. }
  804. vertices_size_type numverts = num_vertices(g);
  805. assign(g, vi, numverts, numedges);
  806. inherited_vertex_properties::resize(numverts);
  807. }
  808. // Requires vertex index map plus requirements of previous constructor
  809. template<typename Graph>
  810. explicit compressed_sparse_row_graph(const Graph& g)
  811. : m_property()
  812. {
  813. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  814. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  815. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  816. }
  817. assign(g, get(vertex_index, g), num_vertices(g), numedges);
  818. }
  819. // From any graph (slow and uses a lot of memory)
  820. // Requires IncidenceGraph and a vertex index map
  821. // Internal helper function
  822. // Note that numedges must be doubled for undirected source graphs
  823. template<typename Graph, typename VertexIndexMap>
  824. void
  825. assign(const Graph& g, const VertexIndexMap& vi,
  826. vertices_size_type numverts, edges_size_type numedges)
  827. {
  828. m_forward.assign(g, vi, numverts, numedges);
  829. inherited_vertex_properties::resize(numverts);
  830. set_up_backward_property_links();
  831. }
  832. // Requires the above, plus VertexListGraph and EdgeListGraph
  833. template<typename Graph, typename VertexIndexMap>
  834. void assign(const Graph& g, const VertexIndexMap& vi)
  835. {
  836. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  837. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  838. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  839. }
  840. vertices_size_type numverts = num_vertices(g);
  841. m_forward.assign(g, vi, numverts, numedges);
  842. inherited_vertex_properties::resize(numverts);
  843. set_up_backward_property_links();
  844. }
  845. // Requires the above, plus a vertex_index map.
  846. template<typename Graph>
  847. void assign(const Graph& g)
  848. {
  849. typename graph_traits<Graph>::edges_size_type numedges = num_edges(g);
  850. if (is_same<typename graph_traits<Graph>::directed_category, undirectedS>::value) {
  851. numedges *= 2; // Double each edge (actual doubling done by out_edges function)
  852. }
  853. vertices_size_type numverts = num_vertices(g);
  854. m_forward.assign(g, get(vertex_index, g), numverts, numedges);
  855. inherited_vertex_properties::resize(numverts);
  856. set_up_backward_property_links();
  857. }
  858. using inherited_vertex_properties::operator[];
  859. // Directly access a edge or edge bundle
  860. edge_push_back_type& operator[](const edge_descriptor& v)
  861. { return m_forward.m_edge_properties[get(edge_index, *this, v)]; }
  862. const edge_push_back_type& operator[](const edge_descriptor& v) const
  863. { return m_forward.m_edge_properties[get(edge_index, *this, v)]; }
  864. // private: non-portable, requires friend templates
  865. inherited_vertex_properties& vertex_properties() {return *this;}
  866. const inherited_vertex_properties& vertex_properties() const {return *this;}
  867. typename forward_type::inherited_edge_properties& edge_properties() { return m_forward; }
  868. const typename forward_type::inherited_edge_properties& edge_properties() const { return m_forward; }
  869. forward_type m_forward;
  870. backward_type m_backward;
  871. GraphProperty m_property;
  872. };
  873. // Construction functions
  874. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  875. inline Vertex
  876. add_vertex(BOOST_CSR_GRAPH_TYPE& g) {
  877. add_vertex(g, typename BOOST_CSR_GRAPH_TYPE::vertex_bundled());
  878. }
  879. template<BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS>
  880. inline Vertex
  881. add_vertex(BOOST_DIR_CSR_GRAPH_TYPE& g,
  882. typename BOOST_DIR_CSR_GRAPH_TYPE::vertex_bundled const& p) {
  883. Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size();
  884. g.m_forward.m_rowstart.push_back(g.m_forward.m_rowstart.back());
  885. g.vertex_properties().push_back(p);
  886. return old_num_verts_plus_one - 1;
  887. }
  888. template<BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS>
  889. inline Vertex
  890. add_vertex(BOOST_BIDIR_CSR_GRAPH_TYPE& g,
  891. typename BOOST_BIDIR_CSR_GRAPH_TYPE::vertex_bundled const& p) {
  892. Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size();
  893. g.m_forward.m_rowstart.push_back(g.m_forward.m_rowstart.back());
  894. g.m_backward.m_rowstart.push_back(g.m_backward.m_rowstart.back());
  895. g.vertex_properties().push_back(p);
  896. return old_num_verts_plus_one - 1;
  897. }
  898. template<BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS>
  899. inline Vertex
  900. add_vertices(typename BOOST_DIR_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_DIR_CSR_GRAPH_TYPE& g) {
  901. Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size();
  902. EdgeIndex numedges = g.m_forward.m_rowstart.back();
  903. g.m_forward.m_rowstart.resize(old_num_verts_plus_one + count, numedges);
  904. g.vertex_properties().resize(num_vertices(g));
  905. return old_num_verts_plus_one - 1;
  906. }
  907. // Add edges from a sorted (smallest sources first) range of pairs and edge
  908. // properties
  909. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename BidirectionalIteratorOrig,
  910. typename EPIterOrig>
  911. void
  912. add_edges_sorted(
  913. BidirectionalIteratorOrig first_sorted,
  914. BidirectionalIteratorOrig last_sorted,
  915. EPIterOrig ep_iter_sorted,
  916. BOOST_DIR_CSR_GRAPH_TYPE& g) {
  917. g.add_edges_sorted_internal(first_sorted, last_sorted, ep_iter_sorted);
  918. }
  919. // Add edges from a sorted (smallest sources first) range of pairs
  920. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename BidirectionalIteratorOrig>
  921. void
  922. add_edges_sorted(
  923. BidirectionalIteratorOrig first_sorted,
  924. BidirectionalIteratorOrig last_sorted,
  925. BOOST_DIR_CSR_GRAPH_TYPE& g) {
  926. g.add_edges_sorted_internal(first_sorted, last_sorted);
  927. }
  928. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename BidirectionalIteratorOrig,
  929. typename EPIterOrig, typename GlobalToLocal>
  930. void
  931. add_edges_sorted_global(
  932. BidirectionalIteratorOrig first_sorted,
  933. BidirectionalIteratorOrig last_sorted,
  934. EPIterOrig ep_iter_sorted,
  935. const GlobalToLocal& global_to_local,
  936. BOOST_DIR_CSR_GRAPH_TYPE& g) {
  937. g.add_edges_sorted_internal_global(first_sorted, last_sorted, ep_iter_sorted,
  938. global_to_local);
  939. }
  940. // Add edges from a sorted (smallest sources first) range of pairs
  941. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename BidirectionalIteratorOrig,
  942. typename GlobalToLocal>
  943. void
  944. add_edges_sorted_global(
  945. BidirectionalIteratorOrig first_sorted,
  946. BidirectionalIteratorOrig last_sorted,
  947. const GlobalToLocal& global_to_local,
  948. BOOST_DIR_CSR_GRAPH_TYPE& g) {
  949. g.add_edges_sorted_internal_global(first_sorted, last_sorted, global_to_local);
  950. }
  951. // Add edges from a range of (source, target) pairs that are unsorted
  952. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator,
  953. typename GlobalToLocal>
  954. inline void
  955. add_edges_global(InputIterator first, InputIterator last,
  956. const GlobalToLocal& global_to_local, BOOST_DIR_CSR_GRAPH_TYPE& g) {
  957. g.add_edges_internal(first, last, global_to_local);
  958. }
  959. // Add edges from a range of (source, target) pairs that are unsorted
  960. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator>
  961. inline void
  962. add_edges(InputIterator first, InputIterator last, BOOST_DIR_CSR_GRAPH_TYPE& g) {
  963. g.add_edges_internal(first, last);
  964. }
  965. // Add edges from a range of (source, target) pairs and edge properties that
  966. // are unsorted
  967. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS,
  968. typename InputIterator, typename EPIterator>
  969. inline void
  970. add_edges(InputIterator first, InputIterator last,
  971. EPIterator ep_iter, EPIterator ep_iter_end,
  972. BOOST_DIR_CSR_GRAPH_TYPE& g) {
  973. g.add_edges_internal(first, last, ep_iter, ep_iter_end);
  974. }
  975. template <BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS,
  976. typename InputIterator, typename EPIterator, typename GlobalToLocal>
  977. inline void
  978. add_edges_global(InputIterator first, InputIterator last,
  979. EPIterator ep_iter, EPIterator ep_iter_end,
  980. const GlobalToLocal& global_to_local,
  981. BOOST_DIR_CSR_GRAPH_TYPE& g) {
  982. g.add_edges_internal(first, last, ep_iter, ep_iter_end, global_to_local);
  983. }
  984. // From VertexListGraph
  985. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  986. inline Vertex
  987. num_vertices(const BOOST_CSR_GRAPH_TYPE& g) {
  988. return g.m_forward.m_rowstart.size() - 1;
  989. }
  990. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  991. std::pair<counting_iterator<Vertex>, counting_iterator<Vertex> >
  992. inline vertices(const BOOST_CSR_GRAPH_TYPE& g) {
  993. return std::make_pair(counting_iterator<Vertex>(0),
  994. counting_iterator<Vertex>(num_vertices(g)));
  995. }
  996. // From IncidenceGraph
  997. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  998. inline Vertex
  999. source(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e,
  1000. const BOOST_CSR_GRAPH_TYPE&)
  1001. {
  1002. return e.src;
  1003. }
  1004. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1005. inline Vertex
  1006. target(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e,
  1007. const BOOST_CSR_GRAPH_TYPE& g)
  1008. {
  1009. return g.m_forward.m_column[e.idx];
  1010. }
  1011. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1012. inline std::pair<typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator,
  1013. typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator>
  1014. out_edges(Vertex v, const BOOST_CSR_GRAPH_TYPE& g)
  1015. {
  1016. typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor ed;
  1017. typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator it;
  1018. EdgeIndex v_row_start = g.m_forward.m_rowstart[v];
  1019. EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1];
  1020. return std::make_pair(it(ed(v, v_row_start)),
  1021. it(ed(v, next_row_start)));
  1022. }
  1023. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1024. inline EdgeIndex
  1025. out_degree(Vertex v, const BOOST_CSR_GRAPH_TYPE& g)
  1026. {
  1027. EdgeIndex v_row_start = g.m_forward.m_rowstart[v];
  1028. EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1];
  1029. return next_row_start - v_row_start;
  1030. }
  1031. template<BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS>
  1032. inline std::pair<typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator,
  1033. typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator>
  1034. in_edges(Vertex v, const BOOST_BIDIR_CSR_GRAPH_TYPE& g)
  1035. {
  1036. typedef typename BOOST_BIDIR_CSR_GRAPH_TYPE::in_edge_iterator it;
  1037. EdgeIndex v_row_start = g.m_backward.m_rowstart[v];
  1038. EdgeIndex next_row_start = g.m_backward.m_rowstart[v + 1];
  1039. return std::make_pair(it(g, v_row_start),
  1040. it(g, next_row_start));
  1041. }
  1042. template<BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS>
  1043. inline EdgeIndex
  1044. in_degree(Vertex v, const BOOST_BIDIR_CSR_GRAPH_TYPE& g)
  1045. {
  1046. EdgeIndex v_row_start = g.m_backward.m_rowstart[v];
  1047. EdgeIndex next_row_start = g.m_backward.m_rowstart[v + 1];
  1048. return next_row_start - v_row_start;
  1049. }
  1050. // From AdjacencyGraph
  1051. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1052. inline std::pair<typename BOOST_CSR_GRAPH_TYPE::adjacency_iterator,
  1053. typename BOOST_CSR_GRAPH_TYPE::adjacency_iterator>
  1054. adjacent_vertices(Vertex v, const BOOST_CSR_GRAPH_TYPE& g)
  1055. {
  1056. EdgeIndex v_row_start = g.m_forward.m_rowstart[v];
  1057. EdgeIndex next_row_start = g.m_forward.m_rowstart[v + 1];
  1058. return std::make_pair(g.m_forward.m_column.begin() + v_row_start,
  1059. g.m_forward.m_column.begin() + next_row_start);
  1060. }
  1061. // Extra, common functions
  1062. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1063. inline typename graph_traits<BOOST_CSR_GRAPH_TYPE>::vertex_descriptor
  1064. vertex(typename graph_traits<BOOST_CSR_GRAPH_TYPE>::vertex_descriptor i,
  1065. const BOOST_CSR_GRAPH_TYPE&)
  1066. {
  1067. return i;
  1068. }
  1069. // edge() can be provided in linear time for the new interface
  1070. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1071. inline std::pair<typename BOOST_CSR_GRAPH_TYPE::edge_descriptor, bool>
  1072. edge(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g)
  1073. {
  1074. typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter;
  1075. std::pair<out_edge_iter, out_edge_iter> range = out_edges(i, g);
  1076. for (; range.first != range.second; ++range.first) {
  1077. if (target(*range.first, g) == j)
  1078. return std::make_pair(*range.first, true);
  1079. }
  1080. return std::make_pair(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(),
  1081. false);
  1082. }
  1083. // Find an edge given its index in the graph
  1084. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1085. inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor
  1086. edge_from_index(EdgeIndex idx, const BOOST_CSR_GRAPH_TYPE& g)
  1087. {
  1088. typedef typename std::vector<EdgeIndex>::const_iterator row_start_iter;
  1089. BOOST_ASSERT (idx < num_edges(g));
  1090. row_start_iter src_plus_1 =
  1091. std::upper_bound(g.m_forward.m_rowstart.begin(),
  1092. g.m_forward.m_rowstart.end(),
  1093. idx);
  1094. // Get last source whose rowstart is at most idx
  1095. // upper_bound returns this position plus 1
  1096. Vertex src = (src_plus_1 - g.m_forward.m_rowstart.begin()) - 1;
  1097. return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, idx);
  1098. }
  1099. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1100. inline EdgeIndex
  1101. num_edges(const BOOST_CSR_GRAPH_TYPE& g)
  1102. {
  1103. return g.m_forward.m_column.size();
  1104. }
  1105. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1106. std::pair<typename BOOST_CSR_GRAPH_TYPE::edge_iterator,
  1107. typename BOOST_CSR_GRAPH_TYPE::edge_iterator>
  1108. edges(const BOOST_CSR_GRAPH_TYPE& g)
  1109. {
  1110. typedef typename BOOST_CSR_GRAPH_TYPE::edge_iterator ei;
  1111. typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edgedesc;
  1112. if (g.m_forward.m_rowstart.size() == 1 || g.m_forward.m_column.empty()) {
  1113. return std::make_pair(ei(), ei());
  1114. } else {
  1115. // Find the first vertex that has outgoing edges
  1116. Vertex src = 0;
  1117. while (g.m_forward.m_rowstart[src + 1] == 0) ++src;
  1118. return std::make_pair(ei(g, edgedesc(src, 0), g.m_forward.m_rowstart[src + 1]),
  1119. ei(g, edgedesc(num_vertices(g), g.m_forward.m_column.size()), 0));
  1120. }
  1121. }
  1122. // For Property Graph
  1123. // Graph properties
  1124. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag, class Value>
  1125. inline void
  1126. set_property(BOOST_CSR_GRAPH_TYPE& g, Tag tag, const Value& value)
  1127. {
  1128. get_property_value(g.m_property, tag) = value;
  1129. }
  1130. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag>
  1131. inline
  1132. typename graph_property<BOOST_CSR_GRAPH_TYPE, Tag>::type&
  1133. get_property(BOOST_CSR_GRAPH_TYPE& g, Tag tag)
  1134. {
  1135. return get_property_value(g.m_property, tag);
  1136. }
  1137. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS, class Tag>
  1138. inline
  1139. const
  1140. typename graph_property<BOOST_CSR_GRAPH_TYPE, Tag>::type&
  1141. get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag tag)
  1142. {
  1143. return get_property_value(g.m_property, tag);
  1144. }
  1145. template <typename G, typename Tag, typename Kind>
  1146. struct csr_property_map_helper {};
  1147. // Kind == void for invalid property tags, so we can use that to SFINAE out
  1148. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1149. struct csr_property_map_helper<BOOST_CSR_GRAPH_TYPE, Tag, vertex_property_tag> {
  1150. typedef vertex_all_t all_tag;
  1151. typedef typename property_traits<typename property_map<BOOST_CSR_GRAPH_TYPE, vertex_all_t>::type>::key_type key_type;
  1152. typedef VertexProperty plist_type;
  1153. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, vertex_all_t>::type all_type;
  1154. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, vertex_all_t>::const_type all_const_type;
  1155. typedef transform_value_property_map<detail::lookup_one_property_f<plist_type, Tag>, all_type> type;
  1156. typedef transform_value_property_map<detail::lookup_one_property_f<const plist_type, Tag>, all_const_type> const_type;
  1157. };
  1158. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1159. struct csr_property_map_helper<BOOST_CSR_GRAPH_TYPE, Tag, edge_property_tag> {
  1160. typedef edge_all_t all_tag;
  1161. typedef typename property_traits<typename property_map<BOOST_CSR_GRAPH_TYPE, edge_all_t>::type>::key_type key_type;
  1162. typedef EdgeProperty plist_type;
  1163. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, edge_all_t>::type all_type;
  1164. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, edge_all_t>::const_type all_const_type;
  1165. typedef transform_value_property_map<detail::lookup_one_property_f<plist_type, Tag>, all_type> type;
  1166. typedef transform_value_property_map<detail::lookup_one_property_f<const plist_type, Tag>, all_const_type> const_type;
  1167. };
  1168. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1169. struct csr_property_map_helper<BOOST_CSR_GRAPH_TYPE, Tag, graph_property_tag> {
  1170. typedef graph_all_t all_tag;
  1171. typedef BOOST_CSR_GRAPH_TYPE* key_type;
  1172. typedef GraphProperty plist_type;
  1173. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t>::type all_type;
  1174. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t>::const_type all_const_type;
  1175. typedef transform_value_property_map<detail::lookup_one_property_f<plist_type, Tag>, all_type> type;
  1176. typedef transform_value_property_map<detail::lookup_one_property_f<const plist_type, Tag>, all_const_type> const_type;
  1177. };
  1178. // disable_if isn't truly necessary but required to avoid ambiguity with specializations below
  1179. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1180. struct property_map<BOOST_CSR_GRAPH_TYPE, Tag, typename disable_if<detail::is_distributed_selector<Vertex> >::type>:
  1181. csr_property_map_helper<
  1182. BOOST_CSR_GRAPH_TYPE,
  1183. Tag,
  1184. typename detail::property_kind_from_graph<BOOST_CSR_GRAPH_TYPE, Tag>
  1185. ::type> {};
  1186. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1187. typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::type
  1188. get(Tag tag, BOOST_CSR_GRAPH_TYPE& g) {
  1189. return typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::type(tag, get(typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::all_tag(), g));
  1190. }
  1191. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1192. typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::const_type
  1193. get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g) {
  1194. return typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::const_type(tag, get(typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::all_tag(), g));
  1195. }
  1196. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1197. typename property_traits<typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::type>::reference
  1198. get(Tag tag, BOOST_CSR_GRAPH_TYPE& g, typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::key_type k) {
  1199. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::all_tag all_tag;
  1200. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, all_tag>::type outer_pm;
  1201. return lookup_one_property<typename property_traits<outer_pm>::value_type, Tag>::lookup(get(all_tag(), g, k), tag);
  1202. }
  1203. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1204. typename property_traits<typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::const_type>::reference
  1205. get(Tag tag, const BOOST_CSR_GRAPH_TYPE& g, typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::key_type k) {
  1206. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::all_tag all_tag;
  1207. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, all_tag>::const_type outer_pm;
  1208. return lookup_one_property<const typename property_traits<outer_pm>::value_type, Tag>::lookup(get(all_tag(), g, k), tag);
  1209. }
  1210. template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename Tag>
  1211. void
  1212. put(Tag tag,
  1213. BOOST_CSR_GRAPH_TYPE& g,
  1214. typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::key_type k,
  1215. typename lookup_one_property<typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::plist_type, Tag>::type val) {
  1216. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::all_tag all_tag;
  1217. lookup_one_property<typename property_map<BOOST_CSR_GRAPH_TYPE, Tag>::plist_type, Tag>::lookup(get(all_tag(), g, k), tag) = val;
  1218. }
  1219. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1220. struct property_map<BOOST_CSR_GRAPH_TYPE, vertex_index_t, typename disable_if<detail::is_distributed_selector<Vertex> >::type>
  1221. {
  1222. typedef typed_identity_property_map<Vertex> type;
  1223. typedef type const_type;
  1224. };
  1225. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1226. struct property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t, typename disable_if<detail::is_distributed_selector<Vertex> >::type>
  1227. {
  1228. typedef detail::csr_edge_index_map<Vertex, EdgeIndex> type;
  1229. typedef type const_type;
  1230. };
  1231. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1232. struct property_map<BOOST_CSR_GRAPH_TYPE, vertex_all_t, typename disable_if<detail::is_distributed_selector<Vertex> >::type>
  1233. {
  1234. typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::vertex_map_type type;
  1235. typedef typename BOOST_CSR_GRAPH_TYPE::inherited_vertex_properties::const_vertex_map_type const_type;
  1236. };
  1237. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1238. struct property_map<BOOST_CSR_GRAPH_TYPE, edge_all_t, typename disable_if<detail::is_distributed_selector<Vertex> >::type>
  1239. {
  1240. typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::edge_map_type type;
  1241. typedef typename BOOST_CSR_GRAPH_TYPE::forward_type::inherited_edge_properties::const_edge_map_type const_type;
  1242. };
  1243. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1244. struct property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t, typename disable_if<detail::is_distributed_selector<Vertex> >::type>
  1245. {
  1246. typedef boost::ref_property_map<BOOST_CSR_GRAPH_TYPE*, typename BOOST_CSR_GRAPH_TYPE::graph_property_type> type;
  1247. typedef boost::ref_property_map<BOOST_CSR_GRAPH_TYPE*, const typename BOOST_CSR_GRAPH_TYPE::graph_property_type> const_type;
  1248. };
  1249. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1250. inline typed_identity_property_map<Vertex>
  1251. get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&)
  1252. {
  1253. return typed_identity_property_map<Vertex>();
  1254. }
  1255. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1256. inline Vertex
  1257. get(vertex_index_t,
  1258. const BOOST_CSR_GRAPH_TYPE&, Vertex v)
  1259. {
  1260. return v;
  1261. }
  1262. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1263. inline typed_identity_property_map<Vertex>
  1264. get(vertex_index_t, BOOST_CSR_GRAPH_TYPE&)
  1265. {
  1266. return typed_identity_property_map<Vertex>();
  1267. }
  1268. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1269. inline Vertex
  1270. get(vertex_index_t,
  1271. BOOST_CSR_GRAPH_TYPE&, Vertex v)
  1272. {
  1273. return v;
  1274. }
  1275. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1276. inline typename property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t>::const_type
  1277. get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&)
  1278. {
  1279. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t>::const_type
  1280. result_type;
  1281. return result_type();
  1282. }
  1283. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1284. inline EdgeIndex
  1285. get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&,
  1286. typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e)
  1287. {
  1288. return e.idx;
  1289. }
  1290. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1291. inline typename property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t>::const_type
  1292. get(edge_index_t, BOOST_CSR_GRAPH_TYPE&)
  1293. {
  1294. typedef typename property_map<BOOST_CSR_GRAPH_TYPE, edge_index_t>::const_type
  1295. result_type;
  1296. return result_type();
  1297. }
  1298. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1299. inline EdgeIndex
  1300. get(edge_index_t, BOOST_CSR_GRAPH_TYPE&,
  1301. typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e)
  1302. {
  1303. return e.idx;
  1304. }
  1305. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1306. inline typename property_map<BOOST_CSR_GRAPH_TYPE, vertex_all_t>::type
  1307. get(vertex_all_t, BOOST_CSR_GRAPH_TYPE& g)
  1308. {
  1309. return g.get_vertex_bundle(get(vertex_index, g));
  1310. }
  1311. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1312. inline typename property_map<BOOST_CSR_GRAPH_TYPE, vertex_all_t>::const_type
  1313. get(vertex_all_t, const BOOST_CSR_GRAPH_TYPE& g)
  1314. {
  1315. return g.get_vertex_bundle(get(vertex_index, g));
  1316. }
  1317. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1318. inline VertexProperty&
  1319. get(vertex_all_t,
  1320. BOOST_CSR_GRAPH_TYPE& g, Vertex v)
  1321. {
  1322. return get(vertex_all, g)[v];
  1323. }
  1324. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1325. inline const VertexProperty&
  1326. get(vertex_all_t,
  1327. const BOOST_CSR_GRAPH_TYPE& g, Vertex v)
  1328. {
  1329. return get(vertex_all, g)[v];
  1330. }
  1331. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1332. inline void
  1333. put(vertex_all_t,
  1334. BOOST_CSR_GRAPH_TYPE& g,
  1335. Vertex v,
  1336. const VertexProperty& val)
  1337. {
  1338. put(get(vertex_all, g), v, val);
  1339. }
  1340. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1341. inline typename property_map<BOOST_CSR_GRAPH_TYPE, edge_all_t>::type
  1342. get(edge_all_t, BOOST_CSR_GRAPH_TYPE& g)
  1343. {
  1344. return g.m_forward.get_edge_bundle(get(edge_index, g));
  1345. }
  1346. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1347. inline typename property_map<BOOST_CSR_GRAPH_TYPE, edge_all_t>::const_type
  1348. get(edge_all_t, const BOOST_CSR_GRAPH_TYPE& g)
  1349. {
  1350. return g.m_forward.get_edge_bundle(get(edge_index, g));
  1351. }
  1352. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1353. inline EdgeProperty&
  1354. get(edge_all_t,
  1355. BOOST_CSR_GRAPH_TYPE& g,
  1356. const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e)
  1357. {
  1358. return get(edge_all, g)[e];
  1359. }
  1360. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1361. inline const EdgeProperty&
  1362. get(edge_all_t,
  1363. const BOOST_CSR_GRAPH_TYPE& g,
  1364. const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e)
  1365. {
  1366. return get(edge_all, g)[e];
  1367. }
  1368. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1369. inline void
  1370. put(edge_all_t,
  1371. BOOST_CSR_GRAPH_TYPE& g,
  1372. const typename BOOST_CSR_GRAPH_TYPE::edge_descriptor& e,
  1373. const EdgeProperty& val)
  1374. {
  1375. put(get(edge_all, g), e, val);
  1376. }
  1377. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1378. inline typename property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t>::type
  1379. get(graph_all_t, BOOST_CSR_GRAPH_TYPE& g)
  1380. {
  1381. return typename property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t>::type(g.m_property);
  1382. }
  1383. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1384. inline typename property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t>::const_type
  1385. get(graph_all_t, const BOOST_CSR_GRAPH_TYPE& g)
  1386. {
  1387. return typename property_map<BOOST_CSR_GRAPH_TYPE, graph_all_t>::const_type(g.m_property);
  1388. }
  1389. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1390. inline GraphProperty&
  1391. get(graph_all_t,
  1392. BOOST_CSR_GRAPH_TYPE& g,
  1393. BOOST_CSR_GRAPH_TYPE*)
  1394. {
  1395. return g.m_property;
  1396. }
  1397. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1398. inline const GraphProperty&
  1399. get(graph_all_t,
  1400. const BOOST_CSR_GRAPH_TYPE& g,
  1401. BOOST_CSR_GRAPH_TYPE*)
  1402. {
  1403. return g.m_property;
  1404. }
  1405. template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
  1406. inline void
  1407. put(graph_all_t,
  1408. BOOST_CSR_GRAPH_TYPE& g,
  1409. BOOST_CSR_GRAPH_TYPE*,
  1410. const GraphProperty& val)
  1411. {
  1412. g.m_property = val;
  1413. }
  1414. #undef BOOST_CSR_GRAPH_TYPE
  1415. #undef BOOST_CSR_GRAPH_TEMPLATE_PARMS
  1416. #undef BOOST_DIR_CSR_GRAPH_TYPE
  1417. #undef BOOST_DIR_CSR_GRAPH_TEMPLATE_PARMS
  1418. #undef BOOST_BIDIR_CSR_GRAPH_TYPE
  1419. #undef BOOST_BIDIR_CSR_GRAPH_TEMPLATE_PARMS
  1420. } // end namespace boost
  1421. #endif // BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP