adjacency_list.hpp 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911
  1. // -*- c++ -*-
  2. //=======================================================================
  3. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  4. // Copyright 2010 Thomas Claveirole
  5. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek, Thomas Claveirole
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See
  8. // accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //=======================================================================
  11. #ifndef BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
  12. #define BOOST_GRAPH_DETAIL_ADJACENCY_LIST_HPP
  13. #include <map> // for vertex_map in copy_impl
  14. #include <boost/config.hpp>
  15. #include <boost/detail/workaround.hpp>
  16. #include <boost/operators.hpp>
  17. #include <boost/property_map/property_map.hpp>
  18. #include <boost/pending/container_traits.hpp>
  19. #include <boost/range/irange.hpp>
  20. #include <boost/graph/graph_traits.hpp>
  21. #include <memory>
  22. #include <iterator>
  23. #include <algorithm>
  24. #include <boost/limits.hpp>
  25. #include <boost/iterator/iterator_adaptor.hpp>
  26. #include <boost/mpl/if.hpp>
  27. #include <boost/mpl/not.hpp>
  28. #include <boost/mpl/and.hpp>
  29. #include <boost/graph/graph_concepts.hpp>
  30. #include <boost/pending/container_traits.hpp>
  31. #include <boost/graph/detail/adj_list_edge_iterator.hpp>
  32. #include <boost/graph/properties.hpp>
  33. #include <boost/pending/property.hpp>
  34. #include <boost/graph/adjacency_iterator.hpp>
  35. #include <boost/static_assert.hpp>
  36. #include <boost/assert.hpp>
  37. #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
  38. #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (x)
  39. #else
  40. #include <utility>
  41. #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (std::move((x)))
  42. #endif
  43. /*
  44. Outline for this file:
  45. out_edge_iterator and in_edge_iterator implementation
  46. edge_iterator for undirected graph
  47. stored edge types (these object live in the out-edge/in-edge lists)
  48. directed edges helper class
  49. directed graph helper class
  50. undirected graph helper class
  51. bidirectional graph helper class
  52. bidirectional graph helper class (without edge properties)
  53. bidirectional graph helper class (with edge properties)
  54. adjacency_list helper class
  55. adj_list_impl class
  56. vec_adj_list_impl class
  57. adj_list_gen class
  58. vertex property map
  59. edge property map
  60. Note: it would be nice to merge some of the undirected and
  61. bidirectional code... it is awful similar.
  62. */
  63. namespace boost
  64. {
  65. namespace detail
  66. {
  67. template < typename DirectedS > struct directed_category_traits
  68. {
  69. typedef directed_tag directed_category;
  70. };
  71. template <> struct directed_category_traits< directedS >
  72. {
  73. typedef directed_tag directed_category;
  74. };
  75. template <> struct directed_category_traits< undirectedS >
  76. {
  77. typedef undirected_tag directed_category;
  78. };
  79. template <> struct directed_category_traits< bidirectionalS >
  80. {
  81. typedef bidirectional_tag directed_category;
  82. };
  83. template < class Vertex > struct target_is
  84. {
  85. target_is(const Vertex& v) : m_target(v) {}
  86. template < class StoredEdge > bool operator()(const StoredEdge& e) const
  87. {
  88. return e.get_target() == m_target;
  89. }
  90. Vertex m_target;
  91. };
  92. // O(E/V)
  93. template < class EdgeList, class vertex_descriptor >
  94. void erase_from_incidence_list(
  95. EdgeList& el, vertex_descriptor v, allow_parallel_edge_tag)
  96. {
  97. boost::graph_detail::erase_if(
  98. el, detail::target_is< vertex_descriptor >(v));
  99. }
  100. // O(log(E/V))
  101. template < class EdgeList, class vertex_descriptor >
  102. void erase_from_incidence_list(
  103. EdgeList& el, vertex_descriptor v, disallow_parallel_edge_tag)
  104. {
  105. typedef typename EdgeList::value_type StoredEdge;
  106. el.erase(StoredEdge(v));
  107. }
  108. //=========================================================================
  109. // Out-Edge and In-Edge Iterator Implementation
  110. template < class BaseIter, class VertexDescriptor, class EdgeDescriptor,
  111. class Difference >
  112. struct out_edge_iter
  113. : iterator_adaptor< out_edge_iter< BaseIter, VertexDescriptor,
  114. EdgeDescriptor, Difference >,
  115. BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
  116. {
  117. typedef iterator_adaptor< out_edge_iter< BaseIter, VertexDescriptor,
  118. EdgeDescriptor, Difference >,
  119. BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
  120. super_t;
  121. inline out_edge_iter() {}
  122. inline out_edge_iter(const BaseIter& i, const VertexDescriptor& src)
  123. : super_t(i), m_src(src)
  124. {
  125. }
  126. inline EdgeDescriptor dereference() const
  127. {
  128. return EdgeDescriptor(m_src, (*this->base()).get_target(),
  129. &(*this->base()).get_property());
  130. }
  131. VertexDescriptor m_src;
  132. };
  133. template < class BaseIter, class VertexDescriptor, class EdgeDescriptor,
  134. class Difference >
  135. struct in_edge_iter
  136. : iterator_adaptor< in_edge_iter< BaseIter, VertexDescriptor,
  137. EdgeDescriptor, Difference >,
  138. BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
  139. {
  140. typedef iterator_adaptor< in_edge_iter< BaseIter, VertexDescriptor,
  141. EdgeDescriptor, Difference >,
  142. BaseIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
  143. super_t;
  144. inline in_edge_iter() {}
  145. inline in_edge_iter(const BaseIter& i, const VertexDescriptor& src)
  146. : super_t(i), m_src(src)
  147. {
  148. }
  149. inline EdgeDescriptor dereference() const
  150. {
  151. return EdgeDescriptor((*this->base()).get_target(), m_src,
  152. &this->base()->get_property());
  153. }
  154. VertexDescriptor m_src;
  155. };
  156. //=========================================================================
  157. // Undirected Edge Iterator Implementation
  158. template < class EdgeIter, class EdgeDescriptor, class Difference >
  159. struct undirected_edge_iter
  160. : iterator_adaptor<
  161. undirected_edge_iter< EdgeIter, EdgeDescriptor, Difference >,
  162. EdgeIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
  163. {
  164. typedef iterator_adaptor<
  165. undirected_edge_iter< EdgeIter, EdgeDescriptor, Difference >,
  166. EdgeIter, EdgeDescriptor, use_default, EdgeDescriptor, Difference >
  167. super_t;
  168. undirected_edge_iter() {}
  169. explicit undirected_edge_iter(EdgeIter i) : super_t(i) {}
  170. inline EdgeDescriptor dereference() const
  171. {
  172. return EdgeDescriptor((*this->base()).m_source,
  173. (*this->base()).m_target, &this->base()->get_property());
  174. }
  175. };
  176. //=========================================================================
  177. // Edge Storage Types (stored in the out-edge/in-edge lists)
  178. template < class Vertex >
  179. class stored_edge
  180. : public boost::equality_comparable1< stored_edge< Vertex >,
  181. boost::less_than_comparable1< stored_edge< Vertex > > >
  182. {
  183. public:
  184. typedef no_property property_type;
  185. inline stored_edge() {}
  186. inline stored_edge(Vertex target, const no_property& = no_property())
  187. : m_target(target)
  188. {
  189. }
  190. inline Vertex& get_target() const { return m_target; }
  191. inline const no_property& get_property() const { return s_prop; }
  192. inline bool operator==(const stored_edge& x) const
  193. {
  194. return m_target == x.get_target();
  195. }
  196. inline bool operator<(const stored_edge& x) const
  197. {
  198. return m_target < x.get_target();
  199. }
  200. // protected: need to add hash<> as a friend
  201. static no_property s_prop;
  202. // Sometimes target not used as key in the set, and in that case
  203. // it is ok to change the target.
  204. mutable Vertex m_target;
  205. };
  206. template < class Vertex > no_property stored_edge< Vertex >::s_prop;
  207. #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) \
  208. || defined(BOOST_NO_CXX11_SMART_PTR)
  209. template < class Vertex, class Property >
  210. class stored_edge_property : public stored_edge< Vertex >
  211. {
  212. typedef stored_edge_property self;
  213. typedef stored_edge< Vertex > Base;
  214. public:
  215. typedef Property property_type;
  216. inline stored_edge_property() {}
  217. inline stored_edge_property(
  218. Vertex target, const Property& p = Property())
  219. : stored_edge< Vertex >(target), m_property(new Property(p))
  220. {
  221. }
  222. stored_edge_property(const self& x)
  223. : Base(static_cast< Base const& >(x))
  224. , m_property(const_cast< self& >(x).m_property)
  225. {
  226. }
  227. self& operator=(const self& x)
  228. {
  229. // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug
  230. // 55771 of Mozilla).
  231. static_cast< Base& >(*this) = static_cast< Base const& >(x);
  232. m_property = const_cast< self& >(x).m_property;
  233. return *this;
  234. }
  235. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  236. // NOTE Don't rely on default operators, their behavior is broken on
  237. // several compilers (GCC 4.6).
  238. stored_edge_property(self&& x)
  239. : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property))
  240. {
  241. }
  242. self& operator=(self&& x)
  243. {
  244. // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug
  245. // 55771 of Mozilla).
  246. static_cast< Base& >(*this) = static_cast< Base&& >(x);
  247. m_property = std::move(x.m_property);
  248. return *this;
  249. }
  250. #endif
  251. inline Property& get_property() { return *m_property; }
  252. inline const Property& get_property() const { return *m_property; }
  253. protected:
  254. // Holding the property by-value causes edge-descriptor
  255. // invalidation for add_edge() with EdgeList=vecS. Instead we
  256. // hold a pointer to the property. std::auto_ptr is not
  257. // a perfect fit for the job, but it is darn close.
  258. #ifdef BOOST_NO_AUTO_PTR
  259. std::unique_ptr< Property > m_property;
  260. #else
  261. std::auto_ptr< Property > m_property;
  262. #endif
  263. };
  264. #else
  265. template < class Vertex, class Property >
  266. class stored_edge_property : public stored_edge< Vertex >
  267. {
  268. typedef stored_edge_property self;
  269. typedef stored_edge< Vertex > Base;
  270. public:
  271. typedef Property property_type;
  272. inline stored_edge_property() {}
  273. inline stored_edge_property(
  274. Vertex target, const Property& p = Property())
  275. : stored_edge< Vertex >(target), m_property(new Property(p))
  276. {
  277. }
  278. stored_edge_property(self&& x)
  279. : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property))
  280. {
  281. }
  282. stored_edge_property(self const& x)
  283. : Base(static_cast< Base const& >(x))
  284. , m_property(std::move(const_cast< self& >(x).m_property))
  285. {
  286. }
  287. self& operator=(self&& x)
  288. {
  289. // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug
  290. // 55771 of Mozilla).
  291. static_cast< Base& >(*this) = static_cast< Base&& >(x);
  292. m_property = std::move(x.m_property);
  293. return *this;
  294. }
  295. self& operator=(self const& x)
  296. {
  297. // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug
  298. // 55771 of Mozilla).
  299. static_cast< Base& >(*this) = static_cast< Base const& >(x);
  300. m_property = std::move(const_cast< self& >(x).m_property);
  301. return *this;
  302. }
  303. inline Property& get_property() { return *m_property; }
  304. inline const Property& get_property() const { return *m_property; }
  305. protected:
  306. std::unique_ptr< Property > m_property;
  307. };
  308. #endif
  309. template < class Vertex, class Iter, class Property >
  310. class stored_edge_iter : public stored_edge< Vertex >
  311. {
  312. public:
  313. typedef Property property_type;
  314. inline stored_edge_iter() {}
  315. inline stored_edge_iter(Vertex v) : stored_edge< Vertex >(v) {}
  316. inline stored_edge_iter(Vertex v, Iter i, void* = 0)
  317. : stored_edge< Vertex >(v), m_iter(i)
  318. {
  319. }
  320. inline Property& get_property() { return m_iter->get_property(); }
  321. inline const Property& get_property() const
  322. {
  323. return m_iter->get_property();
  324. }
  325. inline Iter get_iter() const { return m_iter; }
  326. protected:
  327. Iter m_iter;
  328. };
  329. // For when the EdgeList is a std::vector.
  330. // Want to make the iterator stable, so use an offset
  331. // instead of an iterator into a std::vector
  332. template < class Vertex, class EdgeVec, class Property >
  333. class stored_ra_edge_iter : public stored_edge< Vertex >
  334. {
  335. typedef typename EdgeVec::iterator Iter;
  336. public:
  337. typedef Property property_type;
  338. inline stored_ra_edge_iter() {}
  339. inline explicit stored_ra_edge_iter(
  340. Vertex v) // Only used for comparisons
  341. : stored_edge< Vertex >(v), m_i(0), m_vec(0)
  342. {
  343. }
  344. inline stored_ra_edge_iter(Vertex v, Iter i, EdgeVec* edge_vec)
  345. : stored_edge< Vertex >(v), m_i(i - edge_vec->begin()), m_vec(edge_vec)
  346. {
  347. }
  348. inline Property& get_property()
  349. {
  350. BOOST_ASSERT((m_vec != 0));
  351. return (*m_vec)[m_i].get_property();
  352. }
  353. inline const Property& get_property() const
  354. {
  355. BOOST_ASSERT((m_vec != 0));
  356. return (*m_vec)[m_i].get_property();
  357. }
  358. inline Iter get_iter() const
  359. {
  360. BOOST_ASSERT((m_vec != 0));
  361. return m_vec->begin() + m_i;
  362. }
  363. protected:
  364. std::size_t m_i;
  365. EdgeVec* m_vec;
  366. };
  367. } // namespace detail
  368. template < class Tag, class Vertex, class Property >
  369. const typename property_value< Property, Tag >::type& get(
  370. Tag property_tag, const detail::stored_edge_property< Vertex, Property >& e)
  371. {
  372. return get_property_value(e.get_property(), property_tag);
  373. }
  374. template < class Tag, class Vertex, class Iter, class Property >
  375. const typename property_value< Property, Tag >::type& get(Tag property_tag,
  376. const detail::stored_edge_iter< Vertex, Iter, Property >& e)
  377. {
  378. return get_property_value(e.get_property(), property_tag);
  379. }
  380. template < class Tag, class Vertex, class EdgeVec, class Property >
  381. const typename property_value< Property, Tag >::type& get(Tag property_tag,
  382. const detail::stored_ra_edge_iter< Vertex, EdgeVec, Property >& e)
  383. {
  384. return get_property_value(e.get_property(), property_tag);
  385. }
  386. //=========================================================================
  387. // Directed Edges Helper Class
  388. namespace detail
  389. {
  390. // O(E/V)
  391. template < class edge_descriptor, class EdgeList, class StoredProperty >
  392. inline void remove_directed_edge_dispatch(
  393. edge_descriptor, EdgeList& el, StoredProperty& p)
  394. {
  395. for (typename EdgeList::iterator i = el.begin(); i != el.end(); ++i)
  396. if (&(*i).get_property() == &p)
  397. {
  398. el.erase(i);
  399. return;
  400. }
  401. }
  402. template < class incidence_iterator, class EdgeList, class Predicate >
  403. inline void remove_directed_edge_if_dispatch(incidence_iterator first,
  404. incidence_iterator last, EdgeList& el, Predicate pred,
  405. boost::allow_parallel_edge_tag)
  406. {
  407. // remove_if
  408. while (first != last && !pred(*first))
  409. ++first;
  410. incidence_iterator i = first;
  411. if (first != last)
  412. for (++i; i != last; ++i)
  413. if (!pred(*i))
  414. {
  415. *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
  416. ++first;
  417. }
  418. el.erase(first.base(), el.end());
  419. }
  420. template < class incidence_iterator, class EdgeList, class Predicate >
  421. inline void remove_directed_edge_if_dispatch(incidence_iterator first,
  422. incidence_iterator last, EdgeList& el, Predicate pred,
  423. boost::disallow_parallel_edge_tag)
  424. {
  425. for (incidence_iterator next = first; first != last; first = next)
  426. {
  427. ++next;
  428. if (pred(*first))
  429. el.erase(first.base());
  430. }
  431. }
  432. template < class PropT, class Graph, class incidence_iterator,
  433. class EdgeList, class Predicate >
  434. inline void undirected_remove_out_edge_if_dispatch(Graph& g,
  435. incidence_iterator first, incidence_iterator last, EdgeList& el,
  436. Predicate pred, boost::allow_parallel_edge_tag)
  437. {
  438. typedef typename Graph::global_edgelist_selector EdgeListS;
  439. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  440. // remove_if
  441. while (first != last && !pred(*first))
  442. ++first;
  443. incidence_iterator i = first;
  444. bool self_loop_removed = false;
  445. if (first != last)
  446. for (; i != last; ++i)
  447. {
  448. if (self_loop_removed)
  449. {
  450. /* With self loops, the descriptor will show up
  451. * twice. The first time it will be removed, and now it
  452. * will be skipped.
  453. */
  454. self_loop_removed = false;
  455. }
  456. else if (!pred(*i))
  457. {
  458. *first.base() = BOOST_GRAPH_MOVE_IF_POSSIBLE(*i.base());
  459. ++first;
  460. }
  461. else
  462. {
  463. if (source(*i, g) == target(*i, g))
  464. self_loop_removed = true;
  465. else
  466. {
  467. // Remove the edge from the target
  468. detail::remove_directed_edge_dispatch(*i,
  469. g.out_edge_list(target(*i, g)),
  470. *(PropT*)(*i).get_property());
  471. }
  472. // Erase the edge property
  473. g.m_edges.erase((*i.base()).get_iter());
  474. }
  475. }
  476. el.erase(first.base(), el.end());
  477. }
  478. template < class PropT, class Graph, class incidence_iterator,
  479. class EdgeList, class Predicate >
  480. inline void undirected_remove_out_edge_if_dispatch(Graph& g,
  481. incidence_iterator first, incidence_iterator last, EdgeList& el,
  482. Predicate pred, boost::disallow_parallel_edge_tag)
  483. {
  484. typedef typename Graph::global_edgelist_selector EdgeListS;
  485. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  486. for (incidence_iterator next = first; first != last; first = next)
  487. {
  488. ++next;
  489. if (pred(*first))
  490. {
  491. if (source(*first, g) != target(*first, g))
  492. {
  493. // Remove the edge from the target
  494. detail::remove_directed_edge_dispatch(*first,
  495. g.out_edge_list(target(*first, g)),
  496. *(PropT*)(*first).get_property());
  497. }
  498. // Erase the edge property
  499. g.m_edges.erase((*first.base()).get_iter());
  500. // Erase the edge in the source
  501. el.erase(first.base());
  502. }
  503. }
  504. }
  505. // O(E/V)
  506. template < class edge_descriptor, class EdgeList, class StoredProperty >
  507. inline void remove_directed_edge_dispatch(
  508. edge_descriptor e, EdgeList& el, no_property&)
  509. {
  510. for (typename EdgeList::iterator i = el.begin(); i != el.end(); ++i)
  511. if ((*i).get_target() == e.m_target)
  512. {
  513. el.erase(i);
  514. return;
  515. }
  516. }
  517. } // namespace detail
  518. template < class Config > struct directed_edges_helper
  519. {
  520. // Placement of these overloaded remove_edge() functions
  521. // inside the class avoids a VC++ bug.
  522. // O(E/V)
  523. inline void remove_edge(typename Config::edge_descriptor e)
  524. {
  525. typedef typename Config::graph_type graph_type;
  526. graph_type& g = static_cast< graph_type& >(*this);
  527. typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
  528. typedef typename Config::OutEdgeList::value_type::property_type PType;
  529. detail::remove_directed_edge_dispatch(e, el, *(PType*)e.get_property());
  530. }
  531. // O(1)
  532. inline void remove_edge(typename Config::out_edge_iterator iter)
  533. {
  534. typedef typename Config::graph_type graph_type;
  535. graph_type& g = static_cast< graph_type& >(*this);
  536. typename Config::edge_descriptor e = *iter;
  537. typename Config::OutEdgeList& el = g.out_edge_list(source(e, g));
  538. el.erase(iter.base());
  539. }
  540. };
  541. // O(1)
  542. template < class Config >
  543. inline std::pair< typename Config::edge_iterator,
  544. typename Config::edge_iterator >
  545. edges(const directed_edges_helper< Config >& g_)
  546. {
  547. typedef typename Config::graph_type graph_type;
  548. typedef typename Config::edge_iterator edge_iterator;
  549. const graph_type& cg = static_cast< const graph_type& >(g_);
  550. graph_type& g = const_cast< graph_type& >(cg);
  551. return std::make_pair(edge_iterator(g.vertex_set().begin(),
  552. g.vertex_set().begin(), g.vertex_set().end(), g),
  553. edge_iterator(g.vertex_set().begin(), g.vertex_set().end(),
  554. g.vertex_set().end(), g));
  555. }
  556. //=========================================================================
  557. // Directed Graph Helper Class
  558. struct adj_list_dir_traversal_tag : public virtual vertex_list_graph_tag,
  559. public virtual incidence_graph_tag,
  560. public virtual adjacency_graph_tag,
  561. public virtual edge_list_graph_tag
  562. {
  563. };
  564. template < class Config >
  565. struct directed_graph_helper : public directed_edges_helper< Config >
  566. {
  567. typedef typename Config::edge_descriptor edge_descriptor;
  568. typedef adj_list_dir_traversal_tag traversal_category;
  569. };
  570. // O(E/V)
  571. template < class Config >
  572. inline void remove_edge(typename Config::vertex_descriptor u,
  573. typename Config::vertex_descriptor v, directed_graph_helper< Config >& g_)
  574. {
  575. typedef typename Config::graph_type graph_type;
  576. typedef typename Config::edge_parallel_category Cat;
  577. graph_type& g = static_cast< graph_type& >(g_);
  578. detail::erase_from_incidence_list(g.out_edge_list(u), v, Cat());
  579. }
  580. template < class Config, class Predicate >
  581. inline void remove_out_edge_if(typename Config::vertex_descriptor u,
  582. Predicate pred, directed_graph_helper< Config >& g_)
  583. {
  584. typedef typename Config::graph_type graph_type;
  585. graph_type& g = static_cast< graph_type& >(g_);
  586. typename Config::out_edge_iterator first, last;
  587. boost::tie(first, last) = out_edges(u, g);
  588. typedef typename Config::edge_parallel_category edge_parallel_category;
  589. detail::remove_directed_edge_if_dispatch(
  590. first, last, g.out_edge_list(u), pred, edge_parallel_category());
  591. }
  592. template < class Config, class Predicate >
  593. inline void remove_edge_if(Predicate pred, directed_graph_helper< Config >& g_)
  594. {
  595. typedef typename Config::graph_type graph_type;
  596. graph_type& g = static_cast< graph_type& >(g_);
  597. typename Config::vertex_iterator vi, vi_end;
  598. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  599. remove_out_edge_if(*vi, pred, g);
  600. }
  601. template < class EdgeOrIter, class Config >
  602. inline void remove_edge(
  603. EdgeOrIter e_or_iter, directed_graph_helper< Config >& g_)
  604. {
  605. g_.remove_edge(e_or_iter);
  606. }
  607. // O(V + E) for allow_parallel_edges
  608. // O(V * log(E/V)) for disallow_parallel_edges
  609. template < class Config >
  610. inline void clear_vertex(
  611. typename Config::vertex_descriptor u, directed_graph_helper< Config >& g_)
  612. {
  613. typedef typename Config::graph_type graph_type;
  614. typedef typename Config::edge_parallel_category Cat;
  615. graph_type& g = static_cast< graph_type& >(g_);
  616. typename Config::vertex_iterator vi, viend;
  617. for (boost::tie(vi, viend) = vertices(g); vi != viend; ++vi)
  618. detail::erase_from_incidence_list(g.out_edge_list(*vi), u, Cat());
  619. g.out_edge_list(u).clear();
  620. // clear() should be a req of Sequence and AssociativeContainer,
  621. // or maybe just Container
  622. }
  623. template < class Config >
  624. inline void clear_out_edges(
  625. typename Config::vertex_descriptor u, directed_graph_helper< Config >& g_)
  626. {
  627. typedef typename Config::graph_type graph_type;
  628. graph_type& g = static_cast< graph_type& >(g_);
  629. g.out_edge_list(u).clear();
  630. // clear() should be a req of Sequence and AssociativeContainer,
  631. // or maybe just Container
  632. }
  633. // O(V), could do better...
  634. template < class Config >
  635. inline typename Config::edges_size_type num_edges(
  636. const directed_graph_helper< Config >& g_)
  637. {
  638. typedef typename Config::graph_type graph_type;
  639. const graph_type& g = static_cast< const graph_type& >(g_);
  640. typename Config::edges_size_type num_e = 0;
  641. typename Config::vertex_iterator vi, vi_end;
  642. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  643. num_e += out_degree(*vi, g);
  644. return num_e;
  645. }
  646. // O(1) for allow_parallel_edge_tag
  647. // O(log(E/V)) for disallow_parallel_edge_tag
  648. template < class Config >
  649. inline std::pair< typename directed_graph_helper< Config >::edge_descriptor,
  650. bool >
  651. add_edge(typename Config::vertex_descriptor u,
  652. typename Config::vertex_descriptor v,
  653. const typename Config::edge_property_type& p,
  654. directed_graph_helper< Config >& g_)
  655. {
  656. typedef typename Config::edge_descriptor edge_descriptor;
  657. typedef typename Config::graph_type graph_type;
  658. typedef typename Config::StoredEdge StoredEdge;
  659. graph_type& g = static_cast< graph_type& >(g_);
  660. typename Config::OutEdgeList::iterator i;
  661. bool inserted;
  662. boost::tie(i, inserted)
  663. = boost::graph_detail::push(g.out_edge_list(u), StoredEdge(v, p));
  664. return std::make_pair(
  665. edge_descriptor(u, v, &(*i).get_property()), inserted);
  666. }
  667. // Did not use default argument here because that
  668. // causes Visual C++ to get confused.
  669. template < class Config >
  670. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  671. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  672. directed_graph_helper< Config >& g_)
  673. {
  674. typename Config::edge_property_type p;
  675. return add_edge(u, v, p, g_);
  676. }
  677. //=========================================================================
  678. // Undirected Graph Helper Class
  679. template < class Config > struct undirected_graph_helper;
  680. struct undir_adj_list_traversal_tag : public virtual vertex_list_graph_tag,
  681. public virtual incidence_graph_tag,
  682. public virtual adjacency_graph_tag,
  683. public virtual edge_list_graph_tag,
  684. public virtual bidirectional_graph_tag
  685. {
  686. };
  687. namespace detail
  688. {
  689. // using class with specialization for dispatch is a VC++ workaround.
  690. template < class StoredProperty > struct remove_undirected_edge_dispatch
  691. {
  692. // O(E/V)
  693. template < class edge_descriptor, class Config >
  694. static void apply(edge_descriptor e,
  695. undirected_graph_helper< Config >& g_, StoredProperty& p)
  696. {
  697. typedef typename Config::global_edgelist_selector EdgeListS;
  698. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  699. typedef typename Config::graph_type graph_type;
  700. graph_type& g = static_cast< graph_type& >(g_);
  701. typename Config::OutEdgeList& out_el
  702. = g.out_edge_list(source(e, g));
  703. typename Config::OutEdgeList::iterator out_i = out_el.begin();
  704. typename Config::EdgeIter edge_iter_to_erase;
  705. for (; out_i != out_el.end(); ++out_i)
  706. if (&(*out_i).get_property() == &p)
  707. {
  708. edge_iter_to_erase = (*out_i).get_iter();
  709. out_el.erase(out_i);
  710. break;
  711. }
  712. typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
  713. typename Config::OutEdgeList::iterator in_i = in_el.begin();
  714. for (; in_i != in_el.end(); ++in_i)
  715. if (&(*in_i).get_property() == &p)
  716. {
  717. in_el.erase(in_i);
  718. break;
  719. }
  720. g.m_edges.erase(edge_iter_to_erase);
  721. }
  722. };
  723. template <> struct remove_undirected_edge_dispatch< no_property >
  724. {
  725. // O(E/V)
  726. template < class edge_descriptor, class Config >
  727. static void apply(edge_descriptor e,
  728. undirected_graph_helper< Config >& g_, no_property&)
  729. {
  730. typedef typename Config::global_edgelist_selector EdgeListS;
  731. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  732. typedef typename Config::graph_type graph_type;
  733. graph_type& g = static_cast< graph_type& >(g_);
  734. no_property* p = (no_property*)e.get_property();
  735. typename Config::OutEdgeList& out_el
  736. = g.out_edge_list(source(e, g));
  737. typename Config::OutEdgeList::iterator out_i = out_el.begin();
  738. typename Config::EdgeIter edge_iter_to_erase;
  739. for (; out_i != out_el.end(); ++out_i)
  740. if (&(*out_i).get_property() == p)
  741. {
  742. edge_iter_to_erase = (*out_i).get_iter();
  743. out_el.erase(out_i);
  744. break;
  745. }
  746. typename Config::OutEdgeList& in_el = g.out_edge_list(target(e, g));
  747. typename Config::OutEdgeList::iterator in_i = in_el.begin();
  748. for (; in_i != in_el.end(); ++in_i)
  749. if (&(*in_i).get_property() == p)
  750. {
  751. in_el.erase(in_i);
  752. break;
  753. }
  754. g.m_edges.erase(edge_iter_to_erase);
  755. }
  756. };
  757. // O(E/V)
  758. template < class Graph, class EdgeList, class Vertex >
  759. inline void remove_edge_and_property(
  760. Graph& g, EdgeList& el, Vertex v, boost::allow_parallel_edge_tag cat)
  761. {
  762. typedef typename Graph::global_edgelist_selector EdgeListS;
  763. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  764. typename EdgeList::iterator i = el.begin(), end = el.end();
  765. for (; i != end; ++i)
  766. {
  767. if ((*i).get_target() == v)
  768. {
  769. // NOTE: Wihtout this skip, this loop will double-delete
  770. // properties of loop edges. This solution is based on the
  771. // observation that the incidence edges of a vertex with a loop
  772. // are adjacent in the out edge list. This *may* actually hold
  773. // for multisets also.
  774. bool skip = (boost::next(i) != end
  775. && i->get_iter() == boost::next(i)->get_iter());
  776. g.m_edges.erase((*i).get_iter());
  777. if (skip)
  778. ++i;
  779. }
  780. }
  781. detail::erase_from_incidence_list(el, v, cat);
  782. }
  783. // O(log(E/V))
  784. template < class Graph, class EdgeList, class Vertex >
  785. inline void remove_edge_and_property(
  786. Graph& g, EdgeList& el, Vertex v, boost::disallow_parallel_edge_tag)
  787. {
  788. typedef typename Graph::global_edgelist_selector EdgeListS;
  789. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  790. typedef typename EdgeList::value_type StoredEdge;
  791. typename EdgeList::iterator i = el.find(StoredEdge(v)), end = el.end();
  792. if (i != end)
  793. {
  794. g.m_edges.erase((*i).get_iter());
  795. el.erase(i);
  796. }
  797. }
  798. } // namespace detail
  799. template < class Vertex, class EdgeProperty >
  800. struct list_edge // short name due to VC++ truncation and linker problems
  801. : public boost::detail::edge_base< boost::undirected_tag, Vertex >
  802. {
  803. typedef EdgeProperty property_type;
  804. typedef boost::detail::edge_base< boost::undirected_tag, Vertex > Base;
  805. list_edge(Vertex u, Vertex v, const EdgeProperty& p = EdgeProperty())
  806. : Base(u, v), m_property(p)
  807. {
  808. }
  809. EdgeProperty& get_property() { return m_property; }
  810. const EdgeProperty& get_property() const { return m_property; }
  811. // the following methods should never be used, but are needed
  812. // to make SGI MIPSpro C++ happy
  813. list_edge() {}
  814. bool operator==(const list_edge&) const { return false; }
  815. bool operator<(const list_edge&) const { return false; }
  816. EdgeProperty m_property;
  817. };
  818. template < class Config > struct undirected_graph_helper
  819. {
  820. typedef undir_adj_list_traversal_tag traversal_category;
  821. // Placement of these overloaded remove_edge() functions
  822. // inside the class avoids a VC++ bug.
  823. // O(E/V)
  824. inline void remove_edge(typename Config::edge_descriptor e)
  825. {
  826. typedef typename Config::global_edgelist_selector EdgeListS;
  827. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  828. typedef typename Config::OutEdgeList::value_type::property_type PType;
  829. detail::remove_undirected_edge_dispatch< PType >::apply(
  830. e, *this, *(PType*)e.get_property());
  831. }
  832. // O(E/V)
  833. inline void remove_edge(typename Config::out_edge_iterator iter)
  834. {
  835. this->remove_edge(*iter);
  836. }
  837. };
  838. // Had to make these non-members to avoid accidental instantiation
  839. // on SGI MIPSpro C++
  840. template < class C >
  841. inline typename C::InEdgeList& in_edge_list(
  842. undirected_graph_helper< C >&, typename C::vertex_descriptor v)
  843. {
  844. typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
  845. return sv->m_out_edges;
  846. }
  847. template < class C >
  848. inline const typename C::InEdgeList& in_edge_list(
  849. const undirected_graph_helper< C >&, typename C::vertex_descriptor v)
  850. {
  851. typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
  852. return sv->m_out_edges;
  853. }
  854. // O(E/V)
  855. template < class EdgeOrIter, class Config >
  856. inline void remove_edge(EdgeOrIter e, undirected_graph_helper< Config >& g_)
  857. {
  858. typedef typename Config::global_edgelist_selector EdgeListS;
  859. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  860. g_.remove_edge(e);
  861. }
  862. // O(E/V) or O(log(E/V))
  863. template < class Config >
  864. void remove_edge(typename Config::vertex_descriptor u,
  865. typename Config::vertex_descriptor v, undirected_graph_helper< Config >& g_)
  866. {
  867. typedef typename Config::global_edgelist_selector EdgeListS;
  868. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  869. typedef typename Config::graph_type graph_type;
  870. graph_type& g = static_cast< graph_type& >(g_);
  871. typedef typename Config::edge_parallel_category Cat;
  872. detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
  873. detail::erase_from_incidence_list(g.out_edge_list(v), u, Cat());
  874. }
  875. template < class Config, class Predicate >
  876. void remove_out_edge_if(typename Config::vertex_descriptor u, Predicate pred,
  877. undirected_graph_helper< Config >& g_)
  878. {
  879. typedef typename Config::global_edgelist_selector EdgeListS;
  880. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  881. typedef typename Config::graph_type graph_type;
  882. typedef typename Config::OutEdgeList::value_type::property_type PropT;
  883. graph_type& g = static_cast< graph_type& >(g_);
  884. typename Config::out_edge_iterator first, last;
  885. boost::tie(first, last) = out_edges(u, g);
  886. typedef typename Config::edge_parallel_category Cat;
  887. detail::undirected_remove_out_edge_if_dispatch< PropT >(
  888. g, first, last, g.out_edge_list(u), pred, Cat());
  889. }
  890. template < class Config, class Predicate >
  891. void remove_in_edge_if(typename Config::vertex_descriptor u, Predicate pred,
  892. undirected_graph_helper< Config >& g_)
  893. {
  894. typedef typename Config::global_edgelist_selector EdgeListS;
  895. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  896. remove_out_edge_if(u, pred, g_);
  897. }
  898. // O(E/V * E) or O(log(E/V) * E)
  899. template < class Predicate, class Config >
  900. void remove_edge_if(Predicate pred, undirected_graph_helper< Config >& g_)
  901. {
  902. typedef typename Config::global_edgelist_selector EdgeListS;
  903. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  904. typedef typename Config::graph_type graph_type;
  905. graph_type& g = static_cast< graph_type& >(g_);
  906. typename Config::edge_iterator ei, ei_end, next;
  907. boost::tie(ei, ei_end) = edges(g);
  908. for (next = ei; ei != ei_end; ei = next)
  909. {
  910. ++next;
  911. if (pred(*ei))
  912. remove_edge(*ei, g);
  913. }
  914. }
  915. // O(1)
  916. template < class Config >
  917. inline std::pair< typename Config::edge_iterator,
  918. typename Config::edge_iterator >
  919. edges(const undirected_graph_helper< Config >& g_)
  920. {
  921. typedef typename Config::graph_type graph_type;
  922. typedef typename Config::edge_iterator edge_iterator;
  923. const graph_type& cg = static_cast< const graph_type& >(g_);
  924. graph_type& g = const_cast< graph_type& >(cg);
  925. return std::make_pair(
  926. edge_iterator(g.m_edges.begin()), edge_iterator(g.m_edges.end()));
  927. }
  928. // O(1)
  929. template < class Config >
  930. inline typename Config::edges_size_type num_edges(
  931. const undirected_graph_helper< Config >& g_)
  932. {
  933. typedef typename Config::graph_type graph_type;
  934. const graph_type& g = static_cast< const graph_type& >(g_);
  935. return g.m_edges.size();
  936. }
  937. // O(E/V * E/V)
  938. template < class Config >
  939. inline void clear_vertex(
  940. typename Config::vertex_descriptor u, undirected_graph_helper< Config >& g_)
  941. {
  942. typedef typename Config::global_edgelist_selector EdgeListS;
  943. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  944. typedef typename Config::graph_type graph_type;
  945. graph_type& g = static_cast< graph_type& >(g_);
  946. while (true)
  947. {
  948. typename Config::out_edge_iterator ei, ei_end;
  949. boost::tie(ei, ei_end) = out_edges(u, g);
  950. if (ei == ei_end)
  951. break;
  952. remove_edge(*ei, g);
  953. }
  954. }
  955. // O(1) for allow_parallel_edge_tag
  956. // O(log(E/V)) for disallow_parallel_edge_tag
  957. template < class Config >
  958. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  959. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  960. const typename Config::edge_property_type& p,
  961. undirected_graph_helper< Config >& g_)
  962. {
  963. typedef typename Config::StoredEdge StoredEdge;
  964. typedef typename Config::edge_descriptor edge_descriptor;
  965. typedef typename Config::graph_type graph_type;
  966. graph_type& g = static_cast< graph_type& >(g_);
  967. bool inserted;
  968. typename Config::EdgeContainer::value_type e(u, v, p);
  969. typename Config::EdgeContainer::iterator p_iter
  970. = graph_detail::push(g.m_edges, e).first;
  971. typename Config::OutEdgeList::iterator i;
  972. boost::tie(i, inserted) = boost::graph_detail::push(
  973. g.out_edge_list(u), StoredEdge(v, p_iter, &g.m_edges));
  974. if (inserted)
  975. {
  976. boost::graph_detail::push(
  977. g.out_edge_list(v), StoredEdge(u, p_iter, &g.m_edges));
  978. return std::make_pair(
  979. edge_descriptor(u, v, &p_iter->get_property()), true);
  980. }
  981. else
  982. {
  983. g.m_edges.erase(p_iter);
  984. return std::make_pair(
  985. edge_descriptor(u, v, &i->get_iter()->get_property()), false);
  986. }
  987. }
  988. template < class Config >
  989. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  990. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  991. undirected_graph_helper< Config >& g_)
  992. {
  993. typename Config::edge_property_type p;
  994. return add_edge(u, v, p, g_);
  995. }
  996. // O(1)
  997. template < class Config >
  998. inline typename Config::degree_size_type degree(
  999. typename Config::vertex_descriptor u,
  1000. const undirected_graph_helper< Config >& g_)
  1001. {
  1002. typedef typename Config::graph_type Graph;
  1003. const Graph& g = static_cast< const Graph& >(g_);
  1004. return out_degree(u, g);
  1005. }
  1006. template < class Config >
  1007. inline std::pair< typename Config::in_edge_iterator,
  1008. typename Config::in_edge_iterator >
  1009. in_edges(typename Config::vertex_descriptor u,
  1010. const undirected_graph_helper< Config >& g_)
  1011. {
  1012. typedef typename Config::graph_type Graph;
  1013. const Graph& cg = static_cast< const Graph& >(g_);
  1014. Graph& g = const_cast< Graph& >(cg);
  1015. typedef typename Config::in_edge_iterator in_edge_iterator;
  1016. return std::make_pair(in_edge_iterator(g.out_edge_list(u).begin(), u),
  1017. in_edge_iterator(g.out_edge_list(u).end(), u));
  1018. }
  1019. template < class Config >
  1020. inline typename Config::degree_size_type in_degree(
  1021. typename Config::vertex_descriptor u,
  1022. const undirected_graph_helper< Config >& g_)
  1023. {
  1024. return degree(u, g_);
  1025. }
  1026. //=========================================================================
  1027. // Bidirectional Graph Helper Class
  1028. struct bidir_adj_list_traversal_tag : public virtual vertex_list_graph_tag,
  1029. public virtual incidence_graph_tag,
  1030. public virtual adjacency_graph_tag,
  1031. public virtual edge_list_graph_tag,
  1032. public virtual bidirectional_graph_tag
  1033. {
  1034. };
  1035. template < class Config >
  1036. struct bidirectional_graph_helper : public directed_edges_helper< Config >
  1037. {
  1038. typedef bidir_adj_list_traversal_tag traversal_category;
  1039. };
  1040. // Had to make these non-members to avoid accidental instantiation
  1041. // on SGI MIPSpro C++
  1042. template < class C >
  1043. inline typename C::InEdgeList& in_edge_list(
  1044. bidirectional_graph_helper< C >&, typename C::vertex_descriptor v)
  1045. {
  1046. typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
  1047. return sv->m_in_edges;
  1048. }
  1049. template < class C >
  1050. inline const typename C::InEdgeList& in_edge_list(
  1051. const bidirectional_graph_helper< C >&, typename C::vertex_descriptor v)
  1052. {
  1053. typename C::stored_vertex* sv = (typename C::stored_vertex*)v;
  1054. return sv->m_in_edges;
  1055. }
  1056. template < class Predicate, class Config >
  1057. inline void remove_edge_if(
  1058. Predicate pred, bidirectional_graph_helper< Config >& g_)
  1059. {
  1060. typedef typename Config::global_edgelist_selector EdgeListS;
  1061. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1062. typedef typename Config::graph_type graph_type;
  1063. graph_type& g = static_cast< graph_type& >(g_);
  1064. typename Config::edge_iterator ei, ei_end, next;
  1065. boost::tie(ei, ei_end) = edges(g);
  1066. for (next = ei; ei != ei_end; ei = next)
  1067. {
  1068. ++next;
  1069. if (pred(*ei))
  1070. remove_edge(*ei, g);
  1071. }
  1072. }
  1073. template < class Config >
  1074. inline std::pair< typename Config::in_edge_iterator,
  1075. typename Config::in_edge_iterator >
  1076. in_edges(typename Config::vertex_descriptor u,
  1077. const bidirectional_graph_helper< Config >& g_)
  1078. {
  1079. typedef typename Config::graph_type graph_type;
  1080. const graph_type& cg = static_cast< const graph_type& >(g_);
  1081. graph_type& g = const_cast< graph_type& >(cg);
  1082. typedef typename Config::in_edge_iterator in_edge_iterator;
  1083. return std::make_pair(in_edge_iterator(in_edge_list(g, u).begin(), u),
  1084. in_edge_iterator(in_edge_list(g, u).end(), u));
  1085. }
  1086. // O(1)
  1087. template < class Config >
  1088. inline std::pair< typename Config::edge_iterator,
  1089. typename Config::edge_iterator >
  1090. edges(const bidirectional_graph_helper< Config >& g_)
  1091. {
  1092. typedef typename Config::graph_type graph_type;
  1093. typedef typename Config::edge_iterator edge_iterator;
  1094. const graph_type& cg = static_cast< const graph_type& >(g_);
  1095. graph_type& g = const_cast< graph_type& >(cg);
  1096. return std::make_pair(
  1097. edge_iterator(g.m_edges.begin()), edge_iterator(g.m_edges.end()));
  1098. }
  1099. //=========================================================================
  1100. // Bidirectional Graph Helper Class (with edge properties)
  1101. template < class Config >
  1102. struct bidirectional_graph_helper_with_property
  1103. : public bidirectional_graph_helper< Config >
  1104. {
  1105. typedef typename Config::graph_type graph_type;
  1106. typedef typename Config::out_edge_iterator out_edge_iterator;
  1107. std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
  1108. typename Config::edge_descriptor e, const graph_type& g, void*)
  1109. {
  1110. return out_edges(source(e, g), g);
  1111. }
  1112. std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
  1113. typename Config::edge_descriptor e, const graph_type& g, setS*)
  1114. {
  1115. return edge_range(source(e, g), target(e, g), g);
  1116. }
  1117. std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
  1118. typename Config::edge_descriptor e, const graph_type& g, multisetS*)
  1119. {
  1120. return edge_range(source(e, g), target(e, g), g);
  1121. }
  1122. std::pair< out_edge_iterator, out_edge_iterator > get_parallel_edge_sublist(
  1123. typename Config::edge_descriptor e, const graph_type& g, hash_setS*)
  1124. {
  1125. return edge_range(source(e, g), target(e, g), g);
  1126. }
  1127. // Placement of these overloaded remove_edge() functions
  1128. // inside the class avoids a VC++ bug.
  1129. // O(E/V) or O(log(E/V))
  1130. void remove_edge(typename Config::edge_descriptor e)
  1131. {
  1132. typedef typename Config::global_edgelist_selector EdgeListS;
  1133. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1134. graph_type& g = static_cast< graph_type& >(*this);
  1135. typedef typename Config::edgelist_selector OutEdgeListS;
  1136. std::pair< out_edge_iterator, out_edge_iterator > rng
  1137. = get_parallel_edge_sublist(e, g, (OutEdgeListS*)(0));
  1138. rng.first = std::find(rng.first, rng.second, e);
  1139. BOOST_ASSERT(rng.first != rng.second);
  1140. remove_edge(rng.first);
  1141. }
  1142. inline void remove_edge(typename Config::out_edge_iterator iter)
  1143. {
  1144. typedef typename Config::global_edgelist_selector EdgeListS;
  1145. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1146. typedef typename Config::graph_type graph_type;
  1147. graph_type& g = static_cast< graph_type& >(*this);
  1148. typename Config::edge_descriptor e = *iter;
  1149. typename Config::OutEdgeList& oel = g.out_edge_list(source(e, g));
  1150. typename Config::InEdgeList& iel = in_edge_list(g, target(e, g));
  1151. typedef typename Config::OutEdgeList::value_type::property_type PType;
  1152. PType& p = *(PType*)e.get_property();
  1153. detail::remove_directed_edge_dispatch(*iter, iel, p);
  1154. g.m_edges.erase(iter.base()->get_iter());
  1155. oel.erase(iter.base());
  1156. }
  1157. };
  1158. // O(E/V) for allow_parallel_edge_tag
  1159. // O(log(E/V)) for disallow_parallel_edge_tag
  1160. template < class Config >
  1161. inline void remove_edge(typename Config::vertex_descriptor u,
  1162. typename Config::vertex_descriptor v,
  1163. bidirectional_graph_helper_with_property< Config >& g_)
  1164. {
  1165. typedef typename Config::global_edgelist_selector EdgeListS;
  1166. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1167. typedef typename Config::graph_type graph_type;
  1168. graph_type& g = static_cast< graph_type& >(g_);
  1169. typedef typename Config::edge_parallel_category Cat;
  1170. detail::remove_edge_and_property(g, g.out_edge_list(u), v, Cat());
  1171. detail::erase_from_incidence_list(in_edge_list(g, v), u, Cat());
  1172. }
  1173. // O(E/V) or O(log(E/V))
  1174. template < class EdgeOrIter, class Config >
  1175. inline void remove_edge(
  1176. EdgeOrIter e, bidirectional_graph_helper_with_property< Config >& g_)
  1177. {
  1178. typedef typename Config::global_edgelist_selector EdgeListS;
  1179. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1180. g_.remove_edge(e);
  1181. }
  1182. template < class Config, class Predicate >
  1183. inline void remove_out_edge_if(typename Config::vertex_descriptor u,
  1184. Predicate pred, bidirectional_graph_helper_with_property< Config >& g_)
  1185. {
  1186. typedef typename Config::global_edgelist_selector EdgeListS;
  1187. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1188. typedef typename Config::graph_type graph_type;
  1189. typedef typename Config::OutEdgeList::value_type::property_type PropT;
  1190. graph_type& g = static_cast< graph_type& >(g_);
  1191. typedef typename Config::EdgeIter EdgeIter;
  1192. typedef std::vector< EdgeIter > Garbage;
  1193. Garbage garbage;
  1194. // First remove the edges from the targets' in-edge lists and
  1195. // from the graph's edge set list.
  1196. typename Config::out_edge_iterator out_i, out_end;
  1197. for (boost::tie(out_i, out_end) = out_edges(u, g); out_i != out_end;
  1198. ++out_i)
  1199. if (pred(*out_i))
  1200. {
  1201. detail::remove_directed_edge_dispatch(*out_i,
  1202. in_edge_list(g, target(*out_i, g)),
  1203. *(PropT*)(*out_i).get_property());
  1204. // Put in garbage to delete later. Will need the properties
  1205. // for the remove_if of the out-edges.
  1206. garbage.push_back((*out_i.base()).get_iter());
  1207. }
  1208. // Now remove the edges from this out-edge list.
  1209. typename Config::out_edge_iterator first, last;
  1210. boost::tie(first, last) = out_edges(u, g);
  1211. typedef typename Config::edge_parallel_category Cat;
  1212. detail::remove_directed_edge_if_dispatch(
  1213. first, last, g.out_edge_list(u), pred, Cat());
  1214. // Now delete the edge properties from the g.m_edges list
  1215. for (typename Garbage::iterator i = garbage.begin(); i != garbage.end();
  1216. ++i)
  1217. g.m_edges.erase(*i);
  1218. }
  1219. template < class Config, class Predicate >
  1220. inline void remove_in_edge_if(typename Config::vertex_descriptor v,
  1221. Predicate pred, bidirectional_graph_helper_with_property< Config >& g_)
  1222. {
  1223. typedef typename Config::global_edgelist_selector EdgeListS;
  1224. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1225. typedef typename Config::graph_type graph_type;
  1226. typedef typename Config::OutEdgeList::value_type::property_type PropT;
  1227. graph_type& g = static_cast< graph_type& >(g_);
  1228. typedef typename Config::EdgeIter EdgeIter;
  1229. typedef std::vector< EdgeIter > Garbage;
  1230. Garbage garbage;
  1231. // First remove the edges from the sources' out-edge lists and
  1232. // from the graph's edge set list.
  1233. typename Config::in_edge_iterator in_i, in_end;
  1234. for (boost::tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
  1235. if (pred(*in_i))
  1236. {
  1237. typename Config::vertex_descriptor u = source(*in_i, g);
  1238. detail::remove_directed_edge_dispatch(
  1239. *in_i, g.out_edge_list(u), *(PropT*)(*in_i).get_property());
  1240. // Put in garbage to delete later. Will need the properties
  1241. // for the remove_if of the out-edges.
  1242. garbage.push_back((*in_i.base()).get_iter());
  1243. }
  1244. // Now remove the edges from this in-edge list.
  1245. typename Config::in_edge_iterator first, last;
  1246. boost::tie(first, last) = in_edges(v, g);
  1247. typedef typename Config::edge_parallel_category Cat;
  1248. detail::remove_directed_edge_if_dispatch(
  1249. first, last, in_edge_list(g, v), pred, Cat());
  1250. // Now delete the edge properties from the g.m_edges list
  1251. for (typename Garbage::iterator i = garbage.begin(); i != garbage.end();
  1252. ++i)
  1253. g.m_edges.erase(*i);
  1254. }
  1255. // O(1)
  1256. template < class Config >
  1257. inline typename Config::edges_size_type num_edges(
  1258. const bidirectional_graph_helper_with_property< Config >& g_)
  1259. {
  1260. typedef typename Config::graph_type graph_type;
  1261. const graph_type& g = static_cast< const graph_type& >(g_);
  1262. return g.m_edges.size();
  1263. }
  1264. // O(E/V * E/V) for allow_parallel_edge_tag
  1265. // O(E/V * log(E/V)) for disallow_parallel_edge_tag
  1266. template < class Config >
  1267. inline void clear_vertex(typename Config::vertex_descriptor u,
  1268. bidirectional_graph_helper_with_property< Config >& g_)
  1269. {
  1270. typedef typename Config::global_edgelist_selector EdgeListS;
  1271. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1272. typedef typename Config::graph_type graph_type;
  1273. typedef typename Config::edge_parallel_category Cat;
  1274. graph_type& g = static_cast< graph_type& >(g_);
  1275. typename Config::OutEdgeList& el = g.out_edge_list(u);
  1276. typename Config::OutEdgeList::iterator ei = el.begin(), ei_end = el.end();
  1277. for (; ei != ei_end; ++ei)
  1278. {
  1279. detail::erase_from_incidence_list(
  1280. in_edge_list(g, (*ei).get_target()), u, Cat());
  1281. g.m_edges.erase((*ei).get_iter());
  1282. }
  1283. typename Config::InEdgeList& in_el = in_edge_list(g, u);
  1284. typename Config::InEdgeList::iterator in_ei = in_el.begin(),
  1285. in_ei_end = in_el.end();
  1286. for (; in_ei != in_ei_end; ++in_ei)
  1287. {
  1288. detail::erase_from_incidence_list(
  1289. g.out_edge_list((*in_ei).get_target()), u, Cat());
  1290. g.m_edges.erase((*in_ei).get_iter());
  1291. }
  1292. g.out_edge_list(u).clear();
  1293. in_edge_list(g, u).clear();
  1294. }
  1295. template < class Config >
  1296. inline void clear_out_edges(typename Config::vertex_descriptor u,
  1297. bidirectional_graph_helper_with_property< Config >& g_)
  1298. {
  1299. typedef typename Config::global_edgelist_selector EdgeListS;
  1300. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1301. typedef typename Config::graph_type graph_type;
  1302. typedef typename Config::edge_parallel_category Cat;
  1303. graph_type& g = static_cast< graph_type& >(g_);
  1304. typename Config::OutEdgeList& el = g.out_edge_list(u);
  1305. typename Config::OutEdgeList::iterator ei = el.begin(), ei_end = el.end();
  1306. for (; ei != ei_end; ++ei)
  1307. {
  1308. detail::erase_from_incidence_list(
  1309. in_edge_list(g, (*ei).get_target()), u, Cat());
  1310. g.m_edges.erase((*ei).get_iter());
  1311. }
  1312. g.out_edge_list(u).clear();
  1313. }
  1314. template < class Config >
  1315. inline void clear_in_edges(typename Config::vertex_descriptor u,
  1316. bidirectional_graph_helper_with_property< Config >& g_)
  1317. {
  1318. typedef typename Config::global_edgelist_selector EdgeListS;
  1319. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1320. typedef typename Config::graph_type graph_type;
  1321. typedef typename Config::edge_parallel_category Cat;
  1322. graph_type& g = static_cast< graph_type& >(g_);
  1323. typename Config::InEdgeList& in_el = in_edge_list(g, u);
  1324. typename Config::InEdgeList::iterator in_ei = in_el.begin(),
  1325. in_ei_end = in_el.end();
  1326. for (; in_ei != in_ei_end; ++in_ei)
  1327. {
  1328. detail::erase_from_incidence_list(
  1329. g.out_edge_list((*in_ei).get_target()), u, Cat());
  1330. g.m_edges.erase((*in_ei).get_iter());
  1331. }
  1332. in_edge_list(g, u).clear();
  1333. }
  1334. // O(1) for allow_parallel_edge_tag
  1335. // O(log(E/V)) for disallow_parallel_edge_tag
  1336. template < class Config >
  1337. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  1338. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  1339. const typename Config::edge_property_type& p,
  1340. bidirectional_graph_helper_with_property< Config >& g_)
  1341. {
  1342. typedef typename Config::graph_type graph_type;
  1343. graph_type& g = static_cast< graph_type& >(g_);
  1344. typedef typename Config::edge_descriptor edge_descriptor;
  1345. typedef typename Config::StoredEdge StoredEdge;
  1346. bool inserted;
  1347. typename Config::EdgeContainer::value_type e(u, v, p);
  1348. typename Config::EdgeContainer::iterator p_iter
  1349. = graph_detail::push(g.m_edges, e).first;
  1350. typename Config::OutEdgeList::iterator i;
  1351. boost::tie(i, inserted) = boost::graph_detail::push(
  1352. g.out_edge_list(u), StoredEdge(v, p_iter, &g.m_edges));
  1353. if (inserted)
  1354. {
  1355. boost::graph_detail::push(
  1356. in_edge_list(g, v), StoredEdge(u, p_iter, &g.m_edges));
  1357. return std::make_pair(edge_descriptor(u, v, &p_iter->m_property), true);
  1358. }
  1359. else
  1360. {
  1361. g.m_edges.erase(p_iter);
  1362. return std::make_pair(
  1363. edge_descriptor(u, v, &i->get_iter()->get_property()), false);
  1364. }
  1365. }
  1366. template < class Config >
  1367. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  1368. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  1369. bidirectional_graph_helper_with_property< Config >& g_)
  1370. {
  1371. typename Config::edge_property_type p;
  1372. return add_edge(u, v, p, g_);
  1373. }
  1374. // O(1)
  1375. template < class Config >
  1376. inline typename Config::degree_size_type degree(
  1377. typename Config::vertex_descriptor u,
  1378. const bidirectional_graph_helper_with_property< Config >& g_)
  1379. {
  1380. typedef typename Config::graph_type graph_type;
  1381. const graph_type& g = static_cast< const graph_type& >(g_);
  1382. return in_degree(u, g) + out_degree(u, g);
  1383. }
  1384. //=========================================================================
  1385. // Adjacency List Helper Class
  1386. template < class Config, class Base > struct adj_list_helper : public Base
  1387. {
  1388. typedef typename Config::graph_type AdjList;
  1389. typedef typename Config::vertex_descriptor vertex_descriptor;
  1390. typedef typename Config::edge_descriptor edge_descriptor;
  1391. typedef typename Config::out_edge_iterator out_edge_iterator;
  1392. typedef typename Config::in_edge_iterator in_edge_iterator;
  1393. typedef typename Config::adjacency_iterator adjacency_iterator;
  1394. typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
  1395. typedef typename Config::vertex_iterator vertex_iterator;
  1396. typedef typename Config::edge_iterator edge_iterator;
  1397. typedef typename Config::directed_category directed_category;
  1398. typedef typename Config::edge_parallel_category edge_parallel_category;
  1399. typedef typename Config::vertices_size_type vertices_size_type;
  1400. typedef typename Config::edges_size_type edges_size_type;
  1401. typedef typename Config::degree_size_type degree_size_type;
  1402. typedef typename Config::StoredEdge StoredEdge;
  1403. typedef typename Config::vertex_property_type vertex_property_type;
  1404. typedef typename Config::edge_property_type edge_property_type;
  1405. typedef typename Config::graph_property_type graph_property_type;
  1406. typedef typename Config::global_edgelist_selector global_edgelist_selector;
  1407. typedef typename lookup_one_property< vertex_property_type,
  1408. vertex_bundle_t >::type vertex_bundled;
  1409. typedef
  1410. typename lookup_one_property< edge_property_type, edge_bundle_t >::type
  1411. edge_bundled;
  1412. typedef typename lookup_one_property< graph_property_type,
  1413. graph_bundle_t >::type graph_bundled;
  1414. };
  1415. template < class Config, class Base >
  1416. inline std::pair< typename Config::adjacency_iterator,
  1417. typename Config::adjacency_iterator >
  1418. adjacent_vertices(typename Config::vertex_descriptor u,
  1419. const adj_list_helper< Config, Base >& g_)
  1420. {
  1421. typedef typename Config::graph_type AdjList;
  1422. const AdjList& cg = static_cast< const AdjList& >(g_);
  1423. AdjList& g = const_cast< AdjList& >(cg);
  1424. typedef typename Config::adjacency_iterator adjacency_iterator;
  1425. typename Config::out_edge_iterator first, last;
  1426. boost::tie(first, last) = out_edges(u, g);
  1427. return std::make_pair(
  1428. adjacency_iterator(first, &g), adjacency_iterator(last, &g));
  1429. }
  1430. template < class Config, class Base >
  1431. inline std::pair< typename Config::inv_adjacency_iterator,
  1432. typename Config::inv_adjacency_iterator >
  1433. inv_adjacent_vertices(typename Config::vertex_descriptor u,
  1434. const adj_list_helper< Config, Base >& g_)
  1435. {
  1436. typedef typename Config::graph_type AdjList;
  1437. const AdjList& cg = static_cast< const AdjList& >(g_);
  1438. AdjList& g = const_cast< AdjList& >(cg);
  1439. typedef typename Config::inv_adjacency_iterator inv_adjacency_iterator;
  1440. typename Config::in_edge_iterator first, last;
  1441. boost::tie(first, last) = in_edges(u, g);
  1442. return std::make_pair(
  1443. inv_adjacency_iterator(first, &g), inv_adjacency_iterator(last, &g));
  1444. }
  1445. template < class Config, class Base >
  1446. inline std::pair< typename Config::out_edge_iterator,
  1447. typename Config::out_edge_iterator >
  1448. out_edges(typename Config::vertex_descriptor u,
  1449. const adj_list_helper< Config, Base >& g_)
  1450. {
  1451. typedef typename Config::graph_type AdjList;
  1452. typedef typename Config::out_edge_iterator out_edge_iterator;
  1453. const AdjList& cg = static_cast< const AdjList& >(g_);
  1454. AdjList& g = const_cast< AdjList& >(cg);
  1455. return std::make_pair(out_edge_iterator(g.out_edge_list(u).begin(), u),
  1456. out_edge_iterator(g.out_edge_list(u).end(), u));
  1457. }
  1458. template < class Config, class Base >
  1459. inline std::pair< typename Config::vertex_iterator,
  1460. typename Config::vertex_iterator >
  1461. vertices(const adj_list_helper< Config, Base >& g_)
  1462. {
  1463. typedef typename Config::graph_type AdjList;
  1464. const AdjList& cg = static_cast< const AdjList& >(g_);
  1465. AdjList& g = const_cast< AdjList& >(cg);
  1466. return std::make_pair(g.vertex_set().begin(), g.vertex_set().end());
  1467. }
  1468. template < class Config, class Base >
  1469. inline typename Config::vertices_size_type num_vertices(
  1470. const adj_list_helper< Config, Base >& g_)
  1471. {
  1472. typedef typename Config::graph_type AdjList;
  1473. const AdjList& g = static_cast< const AdjList& >(g_);
  1474. return g.vertex_set().size();
  1475. }
  1476. template < class Config, class Base >
  1477. inline typename Config::degree_size_type out_degree(
  1478. typename Config::vertex_descriptor u,
  1479. const adj_list_helper< Config, Base >& g_)
  1480. {
  1481. typedef typename Config::graph_type AdjList;
  1482. const AdjList& g = static_cast< const AdjList& >(g_);
  1483. return g.out_edge_list(u).size();
  1484. }
  1485. template < class Config, class Base >
  1486. inline std::pair< typename Config::edge_descriptor, bool > edge(
  1487. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  1488. const adj_list_helper< Config, Base >& g_)
  1489. {
  1490. typedef typename Config::graph_type Graph;
  1491. typedef typename Config::StoredEdge StoredEdge;
  1492. const Graph& cg = static_cast< const Graph& >(g_);
  1493. const typename Config::OutEdgeList& el = cg.out_edge_list(u);
  1494. typename Config::OutEdgeList::const_iterator it
  1495. = graph_detail::find(el, StoredEdge(v));
  1496. return std::make_pair(typename Config::edge_descriptor(u, v,
  1497. (it == el.end() ? 0 : &(*it).get_property())),
  1498. (it != el.end()));
  1499. }
  1500. template < class Config, class Base >
  1501. inline std::pair< typename Config::out_edge_iterator,
  1502. typename Config::out_edge_iterator >
  1503. edge_range(typename Config::vertex_descriptor u,
  1504. typename Config::vertex_descriptor v,
  1505. const adj_list_helper< Config, Base >& g_)
  1506. {
  1507. typedef typename Config::graph_type Graph;
  1508. typedef typename Config::StoredEdge StoredEdge;
  1509. const Graph& cg = static_cast< const Graph& >(g_);
  1510. Graph& g = const_cast< Graph& >(cg);
  1511. typedef typename Config::out_edge_iterator out_edge_iterator;
  1512. typename Config::OutEdgeList& el = g.out_edge_list(u);
  1513. typename Config::OutEdgeList::iterator first, last;
  1514. typename Config::EdgeContainer fake_edge_container;
  1515. boost::tie(first, last) = graph_detail::equal_range(el, StoredEdge(v));
  1516. return std::make_pair(
  1517. out_edge_iterator(first, u), out_edge_iterator(last, u));
  1518. }
  1519. template < class Config >
  1520. inline typename Config::degree_size_type in_degree(
  1521. typename Config::vertex_descriptor u,
  1522. const directed_edges_helper< Config >& g_)
  1523. {
  1524. typedef typename Config::graph_type Graph;
  1525. const Graph& cg = static_cast< const Graph& >(g_);
  1526. Graph& g = const_cast< Graph& >(cg);
  1527. return in_edge_list(g, u).size();
  1528. }
  1529. namespace detail
  1530. {
  1531. template < class Config, class Base, class Property >
  1532. inline typename boost::property_map< typename Config::graph_type,
  1533. Property >::type
  1534. get_dispatch(
  1535. adj_list_helper< Config, Base >&, Property p, boost::edge_property_tag)
  1536. {
  1537. typedef typename Config::graph_type Graph;
  1538. typedef typename boost::property_map< Graph, Property >::type PA;
  1539. return PA(p);
  1540. }
  1541. template < class Config, class Base, class Property >
  1542. inline typename boost::property_map< typename Config::graph_type,
  1543. Property >::const_type
  1544. get_dispatch(const adj_list_helper< Config, Base >&, Property p,
  1545. boost::edge_property_tag)
  1546. {
  1547. typedef typename Config::graph_type Graph;
  1548. typedef typename boost::property_map< Graph, Property >::const_type PA;
  1549. return PA(p);
  1550. }
  1551. template < class Config, class Base, class Property >
  1552. inline typename boost::property_map< typename Config::graph_type,
  1553. Property >::type
  1554. get_dispatch(adj_list_helper< Config, Base >& g, Property p,
  1555. boost::vertex_property_tag)
  1556. {
  1557. typedef typename Config::graph_type Graph;
  1558. typedef typename boost::property_map< Graph, Property >::type PA;
  1559. return PA(&static_cast< Graph& >(g), p);
  1560. }
  1561. template < class Config, class Base, class Property >
  1562. inline typename boost::property_map< typename Config::graph_type,
  1563. Property >::const_type
  1564. get_dispatch(const adj_list_helper< Config, Base >& g, Property p,
  1565. boost::vertex_property_tag)
  1566. {
  1567. typedef typename Config::graph_type Graph;
  1568. typedef typename boost::property_map< Graph, Property >::const_type PA;
  1569. const Graph& cg = static_cast< const Graph& >(g);
  1570. return PA(&cg, p);
  1571. }
  1572. } // namespace detail
  1573. // Implementation of the PropertyGraph interface
  1574. template < class Config, class Base, class Property >
  1575. inline
  1576. typename boost::property_map< typename Config::graph_type, Property >::type
  1577. get(Property p, adj_list_helper< Config, Base >& g)
  1578. {
  1579. typedef typename detail::property_kind_from_graph<
  1580. adj_list_helper< Config, Base >, Property >::type Kind;
  1581. return detail::get_dispatch(g, p, Kind());
  1582. }
  1583. template < class Config, class Base, class Property >
  1584. inline typename boost::property_map< typename Config::graph_type,
  1585. Property >::const_type
  1586. get(Property p, const adj_list_helper< Config, Base >& g)
  1587. {
  1588. typedef typename detail::property_kind_from_graph<
  1589. adj_list_helper< Config, Base >, Property >::type Kind;
  1590. return detail::get_dispatch(g, p, Kind());
  1591. }
  1592. template < class Config, class Base, class Property, class Key >
  1593. inline typename boost::property_traits< typename boost::property_map<
  1594. typename Config::graph_type, Property >::type >::reference
  1595. get(Property p, adj_list_helper< Config, Base >& g, const Key& key)
  1596. {
  1597. return get(get(p, g), key);
  1598. }
  1599. template < class Config, class Base, class Property, class Key >
  1600. inline typename boost::property_traits< typename boost::property_map<
  1601. typename Config::graph_type, Property >::const_type >::reference
  1602. get(Property p, const adj_list_helper< Config, Base >& g, const Key& key)
  1603. {
  1604. return get(get(p, g), key);
  1605. }
  1606. template < class Config, class Base, class Property, class Key, class Value >
  1607. inline void put(Property p, adj_list_helper< Config, Base >& g, const Key& key,
  1608. const Value& value)
  1609. {
  1610. typedef typename Config::graph_type Graph;
  1611. typedef typename boost::property_map< Graph, Property >::type Map;
  1612. Map pmap = get(p, static_cast< Graph& >(g));
  1613. put(pmap, key, value);
  1614. }
  1615. //=========================================================================
  1616. // Generalize Adjacency List Implementation
  1617. struct adj_list_tag
  1618. {
  1619. };
  1620. template < class Derived, class Config, class Base >
  1621. class adj_list_impl : public adj_list_helper< Config, Base >
  1622. {
  1623. typedef typename Config::OutEdgeList OutEdgeList;
  1624. typedef typename Config::InEdgeList InEdgeList;
  1625. typedef typename Config::StoredVertexList StoredVertexList;
  1626. public:
  1627. typedef typename Config::stored_vertex stored_vertex;
  1628. typedef typename Config::EdgeContainer EdgeContainer;
  1629. typedef typename Config::vertex_descriptor vertex_descriptor;
  1630. typedef typename Config::edge_descriptor edge_descriptor;
  1631. typedef typename Config::vertex_iterator vertex_iterator;
  1632. typedef typename Config::edge_iterator edge_iterator;
  1633. typedef typename Config::edge_parallel_category edge_parallel_category;
  1634. typedef typename Config::vertices_size_type vertices_size_type;
  1635. typedef typename Config::edges_size_type edges_size_type;
  1636. typedef typename Config::degree_size_type degree_size_type;
  1637. typedef typename Config::edge_property_type edge_property_type;
  1638. typedef adj_list_tag graph_tag;
  1639. static vertex_descriptor null_vertex() { return 0; }
  1640. inline adj_list_impl() {}
  1641. inline adj_list_impl(const adj_list_impl& x) { copy_impl(x); }
  1642. inline adj_list_impl& operator=(const adj_list_impl& x)
  1643. {
  1644. this->clear();
  1645. copy_impl(x);
  1646. return *this;
  1647. }
  1648. inline void clear()
  1649. {
  1650. for (typename StoredVertexList::iterator i = m_vertices.begin();
  1651. i != m_vertices.end(); ++i)
  1652. delete (stored_vertex*)*i;
  1653. m_vertices.clear();
  1654. m_edges.clear();
  1655. }
  1656. inline adj_list_impl(vertices_size_type num_vertices)
  1657. {
  1658. for (vertices_size_type i = 0; i < num_vertices; ++i)
  1659. add_vertex(static_cast< Derived& >(*this));
  1660. }
  1661. template < class EdgeIterator >
  1662. inline adj_list_impl(
  1663. vertices_size_type num_vertices, EdgeIterator first, EdgeIterator last)
  1664. {
  1665. vertex_descriptor* v = new vertex_descriptor[num_vertices];
  1666. for (vertices_size_type i = 0; i < num_vertices; ++i)
  1667. v[i] = add_vertex(static_cast< Derived& >(*this));
  1668. while (first != last)
  1669. {
  1670. add_edge(v[(*first).first], v[(*first).second], *this);
  1671. ++first;
  1672. }
  1673. delete[] v;
  1674. }
  1675. template < class EdgeIterator, class EdgePropertyIterator >
  1676. inline adj_list_impl(vertices_size_type num_vertices, EdgeIterator first,
  1677. EdgeIterator last, EdgePropertyIterator ep_iter)
  1678. {
  1679. vertex_descriptor* v = new vertex_descriptor[num_vertices];
  1680. for (vertices_size_type i = 0; i < num_vertices; ++i)
  1681. v[i] = add_vertex(static_cast< Derived& >(*this));
  1682. while (first != last)
  1683. {
  1684. add_edge(v[(*first).first], v[(*first).second], *ep_iter, *this);
  1685. ++first;
  1686. ++ep_iter;
  1687. }
  1688. delete[] v;
  1689. }
  1690. ~adj_list_impl()
  1691. {
  1692. for (typename StoredVertexList::iterator i = m_vertices.begin();
  1693. i != m_vertices.end(); ++i)
  1694. delete (stored_vertex*)*i;
  1695. }
  1696. // protected:
  1697. inline OutEdgeList& out_edge_list(vertex_descriptor v)
  1698. {
  1699. stored_vertex* sv = (stored_vertex*)v;
  1700. return sv->m_out_edges;
  1701. }
  1702. inline const OutEdgeList& out_edge_list(vertex_descriptor v) const
  1703. {
  1704. stored_vertex* sv = (stored_vertex*)v;
  1705. return sv->m_out_edges;
  1706. }
  1707. inline StoredVertexList& vertex_set() { return m_vertices; }
  1708. inline const StoredVertexList& vertex_set() const { return m_vertices; }
  1709. inline void copy_impl(const adj_list_impl& x_)
  1710. {
  1711. const Derived& x = static_cast< const Derived& >(x_);
  1712. // Would be better to have a constant time way to get from
  1713. // vertices in x to the corresponding vertices in *this.
  1714. std::map< stored_vertex*, stored_vertex* > vertex_map;
  1715. // Copy the stored vertex objects by adding each vertex
  1716. // and copying its property object.
  1717. vertex_iterator vi, vi_end;
  1718. for (boost::tie(vi, vi_end) = vertices(x); vi != vi_end; ++vi)
  1719. {
  1720. stored_vertex* v = (stored_vertex*)add_vertex(*this);
  1721. v->m_property = ((stored_vertex*)*vi)->m_property;
  1722. vertex_map[(stored_vertex*)*vi] = v;
  1723. }
  1724. // Copy the edges by adding each edge and copying its
  1725. // property object.
  1726. edge_iterator ei, ei_end;
  1727. for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei)
  1728. {
  1729. edge_descriptor e;
  1730. bool inserted;
  1731. vertex_descriptor s = source(*ei, x), t = target(*ei, x);
  1732. boost::tie(e, inserted) = add_edge(vertex_map[(stored_vertex*)s],
  1733. vertex_map[(stored_vertex*)t], *this);
  1734. *((edge_property_type*)e.m_eproperty)
  1735. = *((edge_property_type*)(*ei).m_eproperty);
  1736. }
  1737. }
  1738. typename Config::EdgeContainer m_edges;
  1739. StoredVertexList m_vertices;
  1740. };
  1741. // O(1)
  1742. template < class Derived, class Config, class Base >
  1743. inline typename Config::vertex_descriptor add_vertex(
  1744. adj_list_impl< Derived, Config, Base >& g_)
  1745. {
  1746. Derived& g = static_cast< Derived& >(g_);
  1747. typedef typename Config::stored_vertex stored_vertex;
  1748. stored_vertex* v = new stored_vertex;
  1749. typename Config::StoredVertexList::iterator pos;
  1750. bool inserted;
  1751. boost::tie(pos, inserted) = boost::graph_detail::push(g.m_vertices, v);
  1752. v->m_position = pos;
  1753. g.added_vertex(v);
  1754. return v;
  1755. }
  1756. // O(1)
  1757. template < class Derived, class Config, class Base >
  1758. inline typename Config::vertex_descriptor add_vertex(
  1759. const typename Config::vertex_property_type& p,
  1760. adj_list_impl< Derived, Config, Base >& g_)
  1761. {
  1762. typedef typename Config::vertex_descriptor vertex_descriptor;
  1763. Derived& g = static_cast< Derived& >(g_);
  1764. if (optional< vertex_descriptor > v
  1765. = g.vertex_by_property(get_property_value(p, vertex_bundle)))
  1766. return *v;
  1767. typedef typename Config::stored_vertex stored_vertex;
  1768. stored_vertex* v = new stored_vertex(p);
  1769. typename Config::StoredVertexList::iterator pos;
  1770. bool inserted;
  1771. boost::tie(pos, inserted) = boost::graph_detail::push(g.m_vertices, v);
  1772. v->m_position = pos;
  1773. g.added_vertex(v);
  1774. return v;
  1775. }
  1776. // O(1)
  1777. template < class Derived, class Config, class Base >
  1778. inline void remove_vertex(typename Config::vertex_descriptor u,
  1779. adj_list_impl< Derived, Config, Base >& g_)
  1780. {
  1781. typedef typename Config::stored_vertex stored_vertex;
  1782. Derived& g = static_cast< Derived& >(g_);
  1783. g.removing_vertex(
  1784. u, boost::graph_detail::iterator_stability(g_.m_vertices));
  1785. stored_vertex* su = (stored_vertex*)u;
  1786. g.m_vertices.erase(su->m_position);
  1787. delete su;
  1788. }
  1789. // O(V)
  1790. template < class Derived, class Config, class Base >
  1791. inline typename Config::vertex_descriptor vertex(
  1792. typename Config::vertices_size_type n,
  1793. const adj_list_impl< Derived, Config, Base >& g_)
  1794. {
  1795. const Derived& g = static_cast< const Derived& >(g_);
  1796. typename Config::vertex_iterator i = vertices(g).first;
  1797. while (n--)
  1798. ++i; // std::advance(i, n); (not VC++ portable)
  1799. return *i;
  1800. }
  1801. //=========================================================================
  1802. // Vector-Backbone Adjacency List Implementation
  1803. namespace detail
  1804. {
  1805. template < class Graph, class vertex_descriptor >
  1806. inline void remove_vertex_dispatch(
  1807. Graph& g, vertex_descriptor u, boost::directed_tag)
  1808. {
  1809. typedef typename Graph::edge_parallel_category edge_parallel_category;
  1810. g.m_vertices.erase(g.m_vertices.begin() + u);
  1811. vertex_descriptor V = num_vertices(g);
  1812. if (u != V)
  1813. {
  1814. for (vertex_descriptor v = 0; v < V; ++v)
  1815. reindex_edge_list(
  1816. g.out_edge_list(v), u, edge_parallel_category());
  1817. }
  1818. }
  1819. template < class Graph, class vertex_descriptor >
  1820. inline void remove_vertex_dispatch(
  1821. Graph& g, vertex_descriptor u, boost::undirected_tag)
  1822. {
  1823. typedef typename Graph::global_edgelist_selector EdgeListS;
  1824. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1825. typedef typename Graph::edge_parallel_category edge_parallel_category;
  1826. g.m_vertices.erase(g.m_vertices.begin() + u);
  1827. vertex_descriptor V = num_vertices(g);
  1828. for (vertex_descriptor v = 0; v < V; ++v)
  1829. reindex_edge_list(g.out_edge_list(v), u, edge_parallel_category());
  1830. typedef typename Graph::EdgeContainer Container;
  1831. typedef typename Container::iterator Iter;
  1832. Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
  1833. for (; ei != ei_end; ++ei)
  1834. {
  1835. if (ei->m_source > u)
  1836. --ei->m_source;
  1837. if (ei->m_target > u)
  1838. --ei->m_target;
  1839. }
  1840. }
  1841. template < class Graph, class vertex_descriptor >
  1842. inline void remove_vertex_dispatch(
  1843. Graph& g, vertex_descriptor u, boost::bidirectional_tag)
  1844. {
  1845. typedef typename Graph::global_edgelist_selector EdgeListS;
  1846. BOOST_STATIC_ASSERT((!is_same< EdgeListS, vecS >::value));
  1847. typedef typename Graph::edge_parallel_category edge_parallel_category;
  1848. g.m_vertices.erase(g.m_vertices.begin() + u);
  1849. vertex_descriptor V = num_vertices(g);
  1850. vertex_descriptor v;
  1851. if (u != V)
  1852. {
  1853. for (v = 0; v < V; ++v)
  1854. reindex_edge_list(
  1855. g.out_edge_list(v), u, edge_parallel_category());
  1856. for (v = 0; v < V; ++v)
  1857. reindex_edge_list(
  1858. in_edge_list(g, v), u, edge_parallel_category());
  1859. typedef typename Graph::EdgeContainer Container;
  1860. typedef typename Container::iterator Iter;
  1861. Iter ei = g.m_edges.begin(), ei_end = g.m_edges.end();
  1862. for (; ei != ei_end; ++ei)
  1863. {
  1864. if (ei->m_source > u)
  1865. --ei->m_source;
  1866. if (ei->m_target > u)
  1867. --ei->m_target;
  1868. }
  1869. }
  1870. }
  1871. template < class EdgeList, class vertex_descriptor >
  1872. inline void reindex_edge_list(
  1873. EdgeList& el, vertex_descriptor u, boost::allow_parallel_edge_tag)
  1874. {
  1875. typename EdgeList::iterator ei = el.begin(), e_end = el.end();
  1876. for (; ei != e_end; ++ei)
  1877. if ((*ei).get_target() > u)
  1878. --(*ei).get_target();
  1879. }
  1880. template < class EdgeList, class vertex_descriptor >
  1881. inline void reindex_edge_list(
  1882. EdgeList& el, vertex_descriptor u, boost::disallow_parallel_edge_tag)
  1883. {
  1884. typename EdgeList::iterator ei = el.begin(), e_end = el.end();
  1885. while (ei != e_end)
  1886. {
  1887. if (ei->get_target() > u)
  1888. {
  1889. typename EdgeList::value_type ce = *ei;
  1890. ++ei;
  1891. el.erase(ce);
  1892. --ce.get_target();
  1893. el.insert(ce);
  1894. }
  1895. else {
  1896. ++ei;
  1897. }
  1898. }
  1899. }
  1900. } // namespace detail
  1901. struct vec_adj_list_tag
  1902. {
  1903. };
  1904. template < class Graph, class Config, class Base >
  1905. class vec_adj_list_impl : public adj_list_helper< Config, Base >
  1906. {
  1907. typedef typename Config::OutEdgeList OutEdgeList;
  1908. typedef typename Config::InEdgeList InEdgeList;
  1909. typedef typename Config::StoredVertexList StoredVertexList;
  1910. public:
  1911. typedef typename Config::vertex_descriptor vertex_descriptor;
  1912. typedef typename Config::edge_descriptor edge_descriptor;
  1913. typedef typename Config::out_edge_iterator out_edge_iterator;
  1914. typedef typename Config::edge_iterator edge_iterator;
  1915. typedef typename Config::directed_category directed_category;
  1916. typedef typename Config::vertices_size_type vertices_size_type;
  1917. typedef typename Config::edges_size_type edges_size_type;
  1918. typedef typename Config::degree_size_type degree_size_type;
  1919. typedef typename Config::StoredEdge StoredEdge;
  1920. typedef typename Config::stored_vertex stored_vertex;
  1921. typedef typename Config::EdgeContainer EdgeContainer;
  1922. typedef typename Config::edge_property_type edge_property_type;
  1923. typedef vec_adj_list_tag graph_tag;
  1924. static vertex_descriptor null_vertex()
  1925. {
  1926. return (std::numeric_limits< vertex_descriptor >::max)();
  1927. }
  1928. inline vec_adj_list_impl() {}
  1929. inline vec_adj_list_impl(const vec_adj_list_impl& x) { copy_impl(x); }
  1930. inline vec_adj_list_impl& operator=(const vec_adj_list_impl& x)
  1931. {
  1932. this->clear();
  1933. copy_impl(x);
  1934. return *this;
  1935. }
  1936. inline void clear()
  1937. {
  1938. m_vertices.clear();
  1939. m_edges.clear();
  1940. }
  1941. inline vec_adj_list_impl(vertices_size_type _num_vertices)
  1942. : m_vertices(_num_vertices)
  1943. {
  1944. }
  1945. template < class EdgeIterator >
  1946. inline vec_adj_list_impl(
  1947. vertices_size_type num_vertices, EdgeIterator first, EdgeIterator last)
  1948. : m_vertices(num_vertices)
  1949. {
  1950. while (first != last)
  1951. {
  1952. add_edge(
  1953. (*first).first, (*first).second, static_cast< Graph& >(*this));
  1954. ++first;
  1955. }
  1956. }
  1957. template < class EdgeIterator, class EdgePropertyIterator >
  1958. inline vec_adj_list_impl(vertices_size_type num_vertices,
  1959. EdgeIterator first, EdgeIterator last, EdgePropertyIterator ep_iter)
  1960. : m_vertices(num_vertices)
  1961. {
  1962. while (first != last)
  1963. {
  1964. add_edge((*first).first, (*first).second, *ep_iter,
  1965. static_cast< Graph& >(*this));
  1966. ++first;
  1967. ++ep_iter;
  1968. }
  1969. }
  1970. // protected:
  1971. inline boost::integer_range< vertex_descriptor > vertex_set() const
  1972. {
  1973. return boost::integer_range< vertex_descriptor >(0, m_vertices.size());
  1974. }
  1975. inline OutEdgeList& out_edge_list(vertex_descriptor v)
  1976. {
  1977. return m_vertices[v].m_out_edges;
  1978. }
  1979. inline const OutEdgeList& out_edge_list(vertex_descriptor v) const
  1980. {
  1981. return m_vertices[v].m_out_edges;
  1982. }
  1983. inline void copy_impl(const vec_adj_list_impl& x_)
  1984. {
  1985. const Graph& x = static_cast< const Graph& >(x_);
  1986. // Copy the stored vertex objects by adding each vertex
  1987. // and copying its property object.
  1988. for (vertices_size_type i = 0; i < num_vertices(x); ++i)
  1989. {
  1990. vertex_descriptor v = add_vertex(*this);
  1991. m_vertices[v].m_property = x.m_vertices[i].m_property;
  1992. }
  1993. // Copy the edges by adding each edge and copying its
  1994. // property object.
  1995. #ifdef BOOST_NO_CXX17_STRUCTURED_BINDINGS
  1996. edge_iterator ei, ei_end;
  1997. for (boost::tie(ei, ei_end) = edges(x); ei != ei_end; ++ei)
  1998. #else // Silences -Wmaybe-uninitialized in adj_list_edge_iterator::operator++().
  1999. for (auto [ei, ei_end] = edges(x); ei != ei_end; ++ei)
  2000. #endif
  2001. {
  2002. edge_descriptor e;
  2003. bool inserted;
  2004. boost::tie(e, inserted)
  2005. = add_edge(source(*ei, x), target(*ei, x), *this);
  2006. *((edge_property_type*)e.m_eproperty)
  2007. = *((edge_property_type*)(*ei).m_eproperty);
  2008. }
  2009. }
  2010. typename Config::EdgeContainer m_edges;
  2011. StoredVertexList m_vertices;
  2012. };
  2013. // Had to make these non-members to avoid accidental instantiation
  2014. // on SGI MIPSpro C++
  2015. template < class G, class C, class B >
  2016. inline typename C::InEdgeList& in_edge_list(
  2017. vec_adj_list_impl< G, C, B >& g, typename C::vertex_descriptor v)
  2018. {
  2019. return g.m_vertices[v].m_in_edges;
  2020. }
  2021. template < class G, class C, class B >
  2022. inline const typename C::InEdgeList& in_edge_list(
  2023. const vec_adj_list_impl< G, C, B >& g, typename C::vertex_descriptor v)
  2024. {
  2025. return g.m_vertices[v].m_in_edges;
  2026. }
  2027. // O(1)
  2028. template < class Graph, class Config, class Base >
  2029. inline typename Config::vertex_descriptor add_vertex(
  2030. vec_adj_list_impl< Graph, Config, Base >& g_)
  2031. {
  2032. Graph& g = static_cast< Graph& >(g_);
  2033. g.m_vertices.resize(g.m_vertices.size() + 1);
  2034. g.added_vertex(g.m_vertices.size() - 1);
  2035. return g.m_vertices.size() - 1;
  2036. }
  2037. template < class Graph, class Config, class Base >
  2038. inline typename Config::vertex_descriptor add_vertex(
  2039. const typename Config::vertex_property_type& p,
  2040. vec_adj_list_impl< Graph, Config, Base >& g_)
  2041. {
  2042. typedef typename Config::vertex_descriptor vertex_descriptor;
  2043. Graph& g = static_cast< Graph& >(g_);
  2044. if (optional< vertex_descriptor > v
  2045. = g.vertex_by_property(get_property_value(p, vertex_bundle)))
  2046. return *v;
  2047. typedef typename Config::stored_vertex stored_vertex;
  2048. g.m_vertices.push_back(stored_vertex(p));
  2049. g.added_vertex(g.m_vertices.size() - 1);
  2050. return g.m_vertices.size() - 1;
  2051. }
  2052. // Here we override the directed_graph_helper add_edge() function
  2053. // so that the number of vertices is automatically changed if
  2054. // either u or v is greater than the number of vertices.
  2055. template < class Graph, class Config, class Base >
  2056. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  2057. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  2058. const typename Config::edge_property_type& p,
  2059. vec_adj_list_impl< Graph, Config, Base >& g_)
  2060. {
  2061. BOOST_USING_STD_MAX();
  2062. typename Config::vertex_descriptor x
  2063. = max BOOST_PREVENT_MACRO_SUBSTITUTION(u, v);
  2064. if (x >= num_vertices(g_))
  2065. g_.m_vertices.resize(x + 1);
  2066. adj_list_helper< Config, Base >& g = g_;
  2067. return add_edge(u, v, p, g);
  2068. }
  2069. template < class Graph, class Config, class Base >
  2070. inline std::pair< typename Config::edge_descriptor, bool > add_edge(
  2071. typename Config::vertex_descriptor u, typename Config::vertex_descriptor v,
  2072. vec_adj_list_impl< Graph, Config, Base >& g_)
  2073. {
  2074. typename Config::edge_property_type p;
  2075. return add_edge(u, v, p, g_);
  2076. }
  2077. // O(V + E)
  2078. template < class Graph, class Config, class Base >
  2079. inline void remove_vertex(typename Config::vertex_descriptor v,
  2080. vec_adj_list_impl< Graph, Config, Base >& g_)
  2081. {
  2082. typedef typename Config::directed_category Cat;
  2083. Graph& g = static_cast< Graph& >(g_);
  2084. g.removing_vertex(
  2085. v, boost::graph_detail::iterator_stability(g_.m_vertices));
  2086. detail::remove_vertex_dispatch(g, v, Cat());
  2087. }
  2088. // O(1)
  2089. template < class Graph, class Config, class Base >
  2090. inline typename Config::vertex_descriptor vertex(
  2091. typename Config::vertices_size_type n,
  2092. const vec_adj_list_impl< Graph, Config, Base >&)
  2093. {
  2094. return n;
  2095. }
  2096. namespace detail
  2097. {
  2098. //=========================================================================
  2099. // Adjacency List Generator
  2100. template < class Graph, class VertexListS, class OutEdgeListS,
  2101. class DirectedS, class VertexProperty, class EdgeProperty,
  2102. class GraphProperty, class EdgeListS >
  2103. struct adj_list_gen
  2104. {
  2105. typedef typename detail::is_random_access< VertexListS >::type
  2106. is_rand_access;
  2107. typedef typename has_property< EdgeProperty >::type has_edge_property;
  2108. typedef typename DirectedS::is_directed_t DirectedT;
  2109. typedef typename DirectedS::is_bidir_t BidirectionalT;
  2110. struct config
  2111. {
  2112. typedef OutEdgeListS edgelist_selector;
  2113. typedef EdgeListS global_edgelist_selector;
  2114. typedef Graph graph_type;
  2115. typedef EdgeProperty edge_property_type;
  2116. typedef VertexProperty vertex_property_type;
  2117. typedef GraphProperty graph_property_type;
  2118. typedef std::size_t vertices_size_type;
  2119. typedef adjacency_list_traits< OutEdgeListS, VertexListS,
  2120. DirectedS >
  2121. Traits;
  2122. typedef typename Traits::directed_category directed_category;
  2123. typedef
  2124. typename Traits::edge_parallel_category edge_parallel_category;
  2125. typedef typename Traits::vertex_descriptor vertex_descriptor;
  2126. typedef typename Traits::edge_descriptor edge_descriptor;
  2127. typedef void* vertex_ptr;
  2128. // need to reorganize this to avoid instantiating stuff
  2129. // that doesn't get used -JGS
  2130. // VertexList and vertex_iterator
  2131. typedef typename container_gen< VertexListS, vertex_ptr >::type
  2132. SeqVertexList;
  2133. typedef boost::integer_range< vertex_descriptor > RandVertexList;
  2134. typedef typename mpl::if_< is_rand_access, RandVertexList,
  2135. SeqVertexList >::type VertexList;
  2136. typedef typename VertexList::iterator vertex_iterator;
  2137. // EdgeContainer and StoredEdge
  2138. typedef typename container_gen< EdgeListS,
  2139. list_edge< vertex_descriptor, EdgeProperty > >::type
  2140. EdgeContainer;
  2141. typedef typename mpl::and_< DirectedT,
  2142. typename mpl::not_< BidirectionalT >::type >::type
  2143. on_edge_storage;
  2144. typedef typename mpl::if_< on_edge_storage, std::size_t,
  2145. typename EdgeContainer::size_type >::type edges_size_type;
  2146. typedef typename EdgeContainer::iterator EdgeIter;
  2147. typedef
  2148. typename detail::is_random_access< EdgeListS >::type is_edge_ra;
  2149. typedef typename mpl::if_< on_edge_storage,
  2150. stored_edge_property< vertex_descriptor, EdgeProperty >,
  2151. typename mpl::if_< is_edge_ra,
  2152. stored_ra_edge_iter< vertex_descriptor, EdgeContainer,
  2153. EdgeProperty >,
  2154. stored_edge_iter< vertex_descriptor, EdgeIter,
  2155. EdgeProperty > >::type >::type StoredEdge;
  2156. // Adjacency Types
  2157. typedef typename container_gen< OutEdgeListS, StoredEdge >::type
  2158. OutEdgeList;
  2159. typedef typename OutEdgeList::size_type degree_size_type;
  2160. typedef typename OutEdgeList::iterator OutEdgeIter;
  2161. typedef std::iterator_traits< OutEdgeIter >
  2162. OutEdgeIterTraits;
  2163. typedef
  2164. typename OutEdgeIterTraits::iterator_category OutEdgeIterCat;
  2165. typedef typename OutEdgeIterTraits::difference_type OutEdgeIterDiff;
  2166. typedef out_edge_iter< OutEdgeIter, vertex_descriptor,
  2167. edge_descriptor, OutEdgeIterDiff >
  2168. out_edge_iterator;
  2169. typedef typename adjacency_iterator_generator< graph_type,
  2170. vertex_descriptor, out_edge_iterator >::type adjacency_iterator;
  2171. typedef OutEdgeList InEdgeList;
  2172. typedef OutEdgeIter InEdgeIter;
  2173. typedef OutEdgeIterCat InEdgeIterCat;
  2174. typedef OutEdgeIterDiff InEdgeIterDiff;
  2175. typedef in_edge_iter< InEdgeIter, vertex_descriptor,
  2176. edge_descriptor, InEdgeIterDiff >
  2177. in_edge_iterator;
  2178. typedef typename inv_adjacency_iterator_generator< graph_type,
  2179. vertex_descriptor, in_edge_iterator >::type
  2180. inv_adjacency_iterator;
  2181. // Edge Iterator
  2182. typedef std::iterator_traits< EdgeIter > EdgeIterTraits;
  2183. typedef typename EdgeIterTraits::iterator_category EdgeIterCat;
  2184. typedef typename EdgeIterTraits::difference_type EdgeIterDiff;
  2185. typedef undirected_edge_iter< EdgeIter, edge_descriptor,
  2186. EdgeIterDiff >
  2187. UndirectedEdgeIter; // also used for bidirectional
  2188. typedef adj_list_edge_iterator< vertex_iterator, out_edge_iterator,
  2189. graph_type >
  2190. DirectedEdgeIter;
  2191. typedef typename mpl::if_< on_edge_storage, DirectedEdgeIter,
  2192. UndirectedEdgeIter >::type edge_iterator;
  2193. // stored_vertex and StoredVertexList
  2194. typedef typename container_gen< VertexListS, vertex_ptr >::type
  2195. SeqStoredVertexList;
  2196. struct seq_stored_vertex
  2197. {
  2198. seq_stored_vertex() {}
  2199. seq_stored_vertex(const VertexProperty& p) : m_property(p) {}
  2200. OutEdgeList m_out_edges;
  2201. VertexProperty m_property;
  2202. typename SeqStoredVertexList::iterator m_position;
  2203. };
  2204. struct bidir_seq_stored_vertex
  2205. {
  2206. bidir_seq_stored_vertex() {}
  2207. bidir_seq_stored_vertex(const VertexProperty& p) : m_property(p)
  2208. {
  2209. }
  2210. OutEdgeList m_out_edges;
  2211. InEdgeList m_in_edges;
  2212. VertexProperty m_property;
  2213. typename SeqStoredVertexList::iterator m_position;
  2214. };
  2215. struct rand_stored_vertex
  2216. {
  2217. rand_stored_vertex() {}
  2218. rand_stored_vertex(const VertexProperty& p) : m_property(p) {}
  2219. OutEdgeList m_out_edges;
  2220. VertexProperty m_property;
  2221. };
  2222. struct bidir_rand_stored_vertex
  2223. {
  2224. bidir_rand_stored_vertex() {}
  2225. bidir_rand_stored_vertex(const VertexProperty& p)
  2226. : m_property(p)
  2227. {
  2228. }
  2229. OutEdgeList m_out_edges;
  2230. InEdgeList m_in_edges;
  2231. VertexProperty m_property;
  2232. };
  2233. typedef typename mpl::if_< is_rand_access,
  2234. typename mpl::if_< BidirectionalT, bidir_rand_stored_vertex,
  2235. rand_stored_vertex >::type,
  2236. typename mpl::if_< BidirectionalT, bidir_seq_stored_vertex,
  2237. seq_stored_vertex >::type >::type StoredVertex;
  2238. struct stored_vertex : public StoredVertex
  2239. {
  2240. stored_vertex() {}
  2241. stored_vertex(const VertexProperty& p) : StoredVertex(p) {}
  2242. };
  2243. typedef typename container_gen< VertexListS, stored_vertex >::type
  2244. RandStoredVertexList;
  2245. typedef typename mpl::if_< is_rand_access, RandStoredVertexList,
  2246. SeqStoredVertexList >::type StoredVertexList;
  2247. }; // end of config
  2248. typedef typename mpl::if_< BidirectionalT,
  2249. bidirectional_graph_helper_with_property< config >,
  2250. typename mpl::if_< DirectedT, directed_graph_helper< config >,
  2251. undirected_graph_helper< config > >::type >::type
  2252. DirectedHelper;
  2253. typedef typename mpl::if_< is_rand_access,
  2254. vec_adj_list_impl< Graph, config, DirectedHelper >,
  2255. adj_list_impl< Graph, config, DirectedHelper > >::type type;
  2256. };
  2257. } // namespace detail
  2258. //=========================================================================
  2259. // Vertex Property Maps
  2260. template < class Graph, class ValueType, class Reference, class Tag >
  2261. struct adj_list_vertex_property_map
  2262. : public boost::put_get_helper< Reference,
  2263. adj_list_vertex_property_map< Graph, ValueType, Reference, Tag > >
  2264. {
  2265. typedef typename Graph::stored_vertex StoredVertex;
  2266. typedef ValueType value_type;
  2267. typedef Reference reference;
  2268. typedef typename Graph::vertex_descriptor key_type;
  2269. typedef boost::lvalue_property_map_tag category;
  2270. inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag())
  2271. : m_tag(tag)
  2272. {
  2273. }
  2274. inline Reference operator[](key_type v) const
  2275. {
  2276. StoredVertex* sv = (StoredVertex*)v;
  2277. return get_property_value(sv->m_property, m_tag);
  2278. }
  2279. inline Reference operator()(key_type v) const
  2280. {
  2281. return this->operator[](v);
  2282. }
  2283. Tag m_tag;
  2284. };
  2285. template < class Graph, class Property, class PropRef >
  2286. struct adj_list_vertex_all_properties_map
  2287. : public boost::put_get_helper< PropRef,
  2288. adj_list_vertex_all_properties_map< Graph, Property, PropRef > >
  2289. {
  2290. typedef typename Graph::stored_vertex StoredVertex;
  2291. typedef Property value_type;
  2292. typedef PropRef reference;
  2293. typedef typename Graph::vertex_descriptor key_type;
  2294. typedef boost::lvalue_property_map_tag category;
  2295. inline adj_list_vertex_all_properties_map(
  2296. const Graph* = 0, vertex_all_t = vertex_all_t())
  2297. {
  2298. }
  2299. inline PropRef operator[](key_type v) const
  2300. {
  2301. StoredVertex* sv = (StoredVertex*)v;
  2302. return sv->m_property;
  2303. }
  2304. inline PropRef operator()(key_type v) const { return this->operator[](v); }
  2305. };
  2306. template < class Graph, class GraphPtr, class ValueType, class Reference,
  2307. class Tag >
  2308. struct vec_adj_list_vertex_property_map
  2309. : public boost::put_get_helper< Reference,
  2310. vec_adj_list_vertex_property_map< Graph, GraphPtr, ValueType, Reference,
  2311. Tag > >
  2312. {
  2313. typedef ValueType value_type;
  2314. typedef Reference reference;
  2315. typedef typename boost::graph_traits< Graph >::vertex_descriptor key_type;
  2316. typedef boost::lvalue_property_map_tag category;
  2317. vec_adj_list_vertex_property_map(GraphPtr g = 0, Tag tag = Tag())
  2318. : m_g(g), m_tag(tag)
  2319. {
  2320. }
  2321. inline Reference operator[](key_type v) const
  2322. {
  2323. return get_property_value(m_g->m_vertices[v].m_property, m_tag);
  2324. }
  2325. inline Reference operator()(key_type v) const
  2326. {
  2327. return this->operator[](v);
  2328. }
  2329. GraphPtr m_g;
  2330. Tag m_tag;
  2331. };
  2332. template < class Graph, class GraphPtr, class Property, class PropertyRef >
  2333. struct vec_adj_list_vertex_all_properties_map
  2334. : public boost::put_get_helper< PropertyRef,
  2335. vec_adj_list_vertex_all_properties_map< Graph, GraphPtr, Property,
  2336. PropertyRef > >
  2337. {
  2338. typedef Property value_type;
  2339. typedef PropertyRef reference;
  2340. typedef typename boost::graph_traits< Graph >::vertex_descriptor key_type;
  2341. typedef boost::lvalue_property_map_tag category;
  2342. vec_adj_list_vertex_all_properties_map(
  2343. GraphPtr g = 0, vertex_all_t = vertex_all_t())
  2344. : m_g(g)
  2345. {
  2346. }
  2347. inline PropertyRef operator[](key_type v) const
  2348. {
  2349. return m_g->m_vertices[v].m_property;
  2350. }
  2351. inline PropertyRef operator()(key_type v) const
  2352. {
  2353. return this->operator[](v);
  2354. }
  2355. GraphPtr m_g;
  2356. };
  2357. struct adj_list_any_vertex_pa
  2358. {
  2359. template < class Tag, class Graph, class Property > struct bind_
  2360. {
  2361. typedef typename property_value< Property, Tag >::type value_type;
  2362. typedef value_type& reference;
  2363. typedef const value_type& const_reference;
  2364. typedef adj_list_vertex_property_map< Graph, value_type, reference,
  2365. Tag >
  2366. type;
  2367. typedef adj_list_vertex_property_map< Graph, value_type,
  2368. const_reference, Tag >
  2369. const_type;
  2370. };
  2371. };
  2372. struct adj_list_all_vertex_pa
  2373. {
  2374. template < class Tag, class Graph, class Property > struct bind_
  2375. {
  2376. typedef typename Graph::vertex_descriptor Vertex;
  2377. typedef adj_list_vertex_all_properties_map< Graph, Property, Property& >
  2378. type;
  2379. typedef adj_list_vertex_all_properties_map< Graph, Property,
  2380. const Property& >
  2381. const_type;
  2382. };
  2383. };
  2384. template < class Property, class Vertex >
  2385. struct vec_adj_list_vertex_id_map
  2386. : public boost::put_get_helper< Vertex,
  2387. vec_adj_list_vertex_id_map< Property, Vertex > >
  2388. {
  2389. typedef Vertex value_type;
  2390. typedef Vertex key_type;
  2391. typedef Vertex reference;
  2392. typedef boost::readable_property_map_tag category;
  2393. inline vec_adj_list_vertex_id_map() {}
  2394. template < class Graph >
  2395. inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t)
  2396. {
  2397. }
  2398. inline value_type operator[](key_type v) const { return v; }
  2399. inline value_type operator()(key_type v) const { return v; }
  2400. };
  2401. struct vec_adj_list_any_vertex_pa
  2402. {
  2403. template < class Tag, class Graph, class Property > struct bind_
  2404. {
  2405. typedef typename property_value< Property, Tag >::type value_type;
  2406. typedef value_type& reference;
  2407. typedef const value_type& const_reference;
  2408. typedef vec_adj_list_vertex_property_map< Graph, Graph*, value_type,
  2409. reference, Tag >
  2410. type;
  2411. typedef vec_adj_list_vertex_property_map< Graph, const Graph*,
  2412. value_type, const_reference, Tag >
  2413. const_type;
  2414. };
  2415. };
  2416. struct vec_adj_list_id_vertex_pa
  2417. {
  2418. template < class Tag, class Graph, class Property > struct bind_
  2419. {
  2420. typedef typename Graph::vertex_descriptor Vertex;
  2421. typedef vec_adj_list_vertex_id_map< Property, Vertex > type;
  2422. typedef vec_adj_list_vertex_id_map< Property, Vertex > const_type;
  2423. };
  2424. };
  2425. struct vec_adj_list_all_vertex_pa
  2426. {
  2427. template < class Tag, class Graph, class Property > struct bind_
  2428. {
  2429. typedef typename Graph::vertex_descriptor Vertex;
  2430. typedef vec_adj_list_vertex_all_properties_map< Graph, Graph*, Property,
  2431. Property& >
  2432. type;
  2433. typedef vec_adj_list_vertex_all_properties_map< Graph, const Graph*,
  2434. Property, const Property& >
  2435. const_type;
  2436. };
  2437. };
  2438. namespace detail
  2439. {
  2440. template < class Tag, class Graph, class Property >
  2441. struct adj_list_choose_vertex_pa
  2442. : boost::mpl::if_< boost::is_same< Tag, vertex_all_t >,
  2443. adj_list_all_vertex_pa, adj_list_any_vertex_pa >::type ::
  2444. template bind_< Tag, Graph, Property >
  2445. {
  2446. };
  2447. template < class Tag > struct vec_adj_list_choose_vertex_pa_helper
  2448. {
  2449. typedef vec_adj_list_any_vertex_pa type;
  2450. };
  2451. template <> struct vec_adj_list_choose_vertex_pa_helper< vertex_index_t >
  2452. {
  2453. typedef vec_adj_list_id_vertex_pa type;
  2454. };
  2455. template <> struct vec_adj_list_choose_vertex_pa_helper< vertex_all_t >
  2456. {
  2457. typedef vec_adj_list_all_vertex_pa type;
  2458. };
  2459. template < class Tag, class Graph, class Property >
  2460. struct vec_adj_list_choose_vertex_pa
  2461. : vec_adj_list_choose_vertex_pa_helper< Tag >::type::template bind_< Tag,
  2462. Graph, Property >
  2463. {
  2464. };
  2465. } // namespace detail
  2466. //=========================================================================
  2467. // Edge Property Map
  2468. template < class Directed, class Value, class Ref, class Vertex, class Property,
  2469. class Tag >
  2470. struct adj_list_edge_property_map
  2471. : public put_get_helper< Ref,
  2472. adj_list_edge_property_map< Directed, Value, Ref, Vertex, Property,
  2473. Tag > >
  2474. {
  2475. Tag tag;
  2476. explicit adj_list_edge_property_map(Tag tag = Tag()) : tag(tag) {}
  2477. typedef Value value_type;
  2478. typedef Ref reference;
  2479. typedef detail::edge_desc_impl< Directed, Vertex > key_type;
  2480. typedef boost::lvalue_property_map_tag category;
  2481. inline Ref operator[](key_type e) const
  2482. {
  2483. Property& p = *(Property*)e.get_property();
  2484. return get_property_value(p, tag);
  2485. }
  2486. inline Ref operator()(key_type e) const { return this->operator[](e); }
  2487. };
  2488. template < class Directed, class Property, class PropRef, class PropPtr,
  2489. class Vertex >
  2490. struct adj_list_edge_all_properties_map
  2491. : public put_get_helper< PropRef,
  2492. adj_list_edge_all_properties_map< Directed, Property, PropRef, PropPtr,
  2493. Vertex > >
  2494. {
  2495. explicit adj_list_edge_all_properties_map(edge_all_t = edge_all_t()) {}
  2496. typedef Property value_type;
  2497. typedef PropRef reference;
  2498. typedef detail::edge_desc_impl< Directed, Vertex > key_type;
  2499. typedef boost::lvalue_property_map_tag category;
  2500. inline PropRef operator[](key_type e) const
  2501. {
  2502. return *(PropPtr)e.get_property();
  2503. }
  2504. inline PropRef operator()(key_type e) const { return this->operator[](e); }
  2505. };
  2506. // Edge Property Maps
  2507. namespace detail
  2508. {
  2509. struct adj_list_any_edge_pmap
  2510. {
  2511. template < class Graph, class Property, class Tag > struct bind_
  2512. {
  2513. typedef typename property_value< Property, Tag >::type value_type;
  2514. typedef value_type& reference;
  2515. typedef const value_type& const_reference;
  2516. typedef adj_list_edge_property_map<
  2517. typename Graph::directed_category, value_type, reference,
  2518. typename Graph::vertex_descriptor, Property, Tag >
  2519. type;
  2520. typedef adj_list_edge_property_map<
  2521. typename Graph::directed_category, value_type, const_reference,
  2522. typename Graph::vertex_descriptor, const Property, Tag >
  2523. const_type;
  2524. };
  2525. };
  2526. struct adj_list_all_edge_pmap
  2527. {
  2528. template < class Graph, class Property, class Tag > struct bind_
  2529. {
  2530. typedef adj_list_edge_all_properties_map<
  2531. typename Graph::directed_category, Property, Property&,
  2532. Property*, typename Graph::vertex_descriptor >
  2533. type;
  2534. typedef adj_list_edge_all_properties_map<
  2535. typename Graph::directed_category, Property, const Property&,
  2536. const Property*, typename Graph::vertex_descriptor >
  2537. const_type;
  2538. };
  2539. };
  2540. template < class Tag > struct adj_list_choose_edge_pmap_helper
  2541. {
  2542. typedef adj_list_any_edge_pmap type;
  2543. };
  2544. template <> struct adj_list_choose_edge_pmap_helper< edge_all_t >
  2545. {
  2546. typedef adj_list_all_edge_pmap type;
  2547. };
  2548. template < class Tag, class Graph, class Property >
  2549. struct adj_list_choose_edge_pmap
  2550. : adj_list_choose_edge_pmap_helper< Tag >::type::template bind_< Graph,
  2551. Property, Tag >
  2552. {
  2553. };
  2554. struct adj_list_edge_property_selector
  2555. {
  2556. template < class Graph, class Property, class Tag >
  2557. struct bind_ : adj_list_choose_edge_pmap< Tag, Graph, Property >
  2558. {
  2559. };
  2560. };
  2561. } // namespace detail
  2562. template <> struct edge_property_selector< adj_list_tag >
  2563. {
  2564. typedef detail::adj_list_edge_property_selector type;
  2565. };
  2566. template <> struct edge_property_selector< vec_adj_list_tag >
  2567. {
  2568. typedef detail::adj_list_edge_property_selector type;
  2569. };
  2570. // Vertex Property Maps
  2571. struct adj_list_vertex_property_selector
  2572. {
  2573. template < class Graph, class Property, class Tag >
  2574. struct bind_ : detail::adj_list_choose_vertex_pa< Tag, Graph, Property >
  2575. {
  2576. };
  2577. };
  2578. template <> struct vertex_property_selector< adj_list_tag >
  2579. {
  2580. typedef adj_list_vertex_property_selector type;
  2581. };
  2582. struct vec_adj_list_vertex_property_selector
  2583. {
  2584. template < class Graph, class Property, class Tag >
  2585. struct bind_ : detail::vec_adj_list_choose_vertex_pa< Tag, Graph, Property >
  2586. {
  2587. };
  2588. };
  2589. template <> struct vertex_property_selector< vec_adj_list_tag >
  2590. {
  2591. typedef vec_adj_list_vertex_property_selector type;
  2592. };
  2593. } // namespace boost
  2594. namespace boost
  2595. {
  2596. template < typename V > struct hash< boost::detail::stored_edge< V > >
  2597. {
  2598. std::size_t operator()(const boost::detail::stored_edge< V >& e) const
  2599. {
  2600. return hash< V >()(e.m_target);
  2601. }
  2602. };
  2603. template < typename V, typename P >
  2604. struct hash< boost::detail::stored_edge_property< V, P > >
  2605. {
  2606. std::size_t operator()(
  2607. const boost::detail::stored_edge_property< V, P >& e) const
  2608. {
  2609. return hash< V >()(e.m_target);
  2610. }
  2611. };
  2612. template < typename V, typename I, typename P >
  2613. struct hash< boost::detail::stored_edge_iter< V, I, P > >
  2614. {
  2615. std::size_t operator()(
  2616. const boost::detail::stored_edge_iter< V, I, P >& e) const
  2617. {
  2618. return hash< V >()(e.m_target);
  2619. }
  2620. };
  2621. }
  2622. #endif // BOOST_GRAPH_DETAIL_DETAIL_ADJACENCY_LIST_CCT
  2623. /*
  2624. Implementation Notes:
  2625. Many of the public interface functions in this file would have been
  2626. more conveniently implemented as inline friend functions.
  2627. However there are a few compiler bugs that make that approach
  2628. non-portable.
  2629. 1. g++ inline friend in namespace bug
  2630. 2. g++ using clause doesn't work with inline friends
  2631. 3. VC++ doesn't have Koenig lookup
  2632. For these reasons, the functions were all written as non-inline free
  2633. functions, and static cast was used to convert from the helper
  2634. class to the adjacency_list derived class.
  2635. Looking back, it might have been better to write out all functions
  2636. in terms of the adjacency_list, and then use a tag to dispatch
  2637. to the various helpers instead of using inheritance.
  2638. */