compressed_sparse_row_graph.hpp 68 KB

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