adjacency_list_graph.ipp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2008-2010 Gordon Woodhull
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_MSM_MPL_GRAPH_DETAIL_ADJACENCY_LIST_GRAPH_IPP_INCLUDED
  5. #define BOOST_MSM_MPL_GRAPH_DETAIL_ADJACENCY_LIST_GRAPH_IPP_INCLUDED
  6. // implementation of a graph declared in adjacency list format
  7. // sequence< pair< source_vertex, sequence< pair<edge, target_vertex> > > >
  8. #include <boost/msm/mpl_graph/mpl_utils.hpp>
  9. #include <boost/msm/mpl_graph/detail/incidence_list_graph.ipp>
  10. #include <boost/mpl/copy.hpp>
  11. #include <boost/mpl/inserter.hpp>
  12. #include <boost/mpl/map.hpp>
  13. #include <boost/mpl/insert.hpp>
  14. #include <boost/mpl/fold.hpp>
  15. #include <boost/mpl/pair.hpp>
  16. #include <boost/mpl/at.hpp>
  17. #include <boost/mpl/push_back.hpp>
  18. namespace boost {
  19. namespace msm {
  20. namespace mpl_graph {
  21. namespace detail {
  22. // tag identifying graph implementation as adjacency list (not defined)
  23. struct adjacency_list_tag;
  24. // outs map is really just the same data with the sequences turned into maps
  25. // it might make sense to make another adjacency_map implementation for that case
  26. template<typename AdjacencyList>
  27. struct produce_al_outs_map :
  28. mpl::reverse_fold<AdjacencyList,
  29. mpl::map<>,
  30. mpl::insert<mpl::_1,
  31. mpl::pair<mpl::first<mpl::_2>, mpl_utils::as_map<mpl::second<mpl::_2> > > > >
  32. {};
  33. // Edge->Target map for a Source for out_*, degree
  34. template<typename Source, typename GraphData>
  35. struct produce_out_map<adjacency_list_tag, Source, GraphData> :
  36. mpl::at<typename produce_al_outs_map<GraphData>::type, Source>
  37. {};
  38. template<typename InsMap, typename Source, typename Adjacencies>
  39. struct produce_in_adjacencies :
  40. mpl::reverse_fold<Adjacencies,
  41. InsMap,
  42. mpl::insert<mpl::_1,
  43. mpl::pair<mpl::second<mpl::_2>,
  44. mpl::insert<mpl_utils::at_or_default<mpl::_1, mpl::second<mpl::_2>, mpl::map<> >,
  45. mpl::pair<mpl::first<mpl::_2>, Source> > > > >
  46. {};
  47. template<typename AdjacencyList>
  48. struct produce_al_ins_map :
  49. mpl::reverse_fold<AdjacencyList,
  50. mpl::map<>,
  51. produce_in_adjacencies<mpl::_1, mpl::first<mpl::_2>, mpl::second<mpl::_2> > >
  52. {};
  53. // Edge->Source map for a Target for in_*, degree
  54. template<typename Target, typename GraphData>
  55. struct produce_in_map<adjacency_list_tag, Target, GraphData> :
  56. mpl::at<typename produce_al_ins_map<GraphData>::type, Target>
  57. {};
  58. // for everything else to do with edges,
  59. // just produce an incidence list and forward to that graph implementation
  60. // (produce_out_map could, and produce_in_map probably should, be implemented this way too)
  61. template<typename Incidences, typename Source, typename Adjacencies>
  62. struct produce_adjacencies_incidences : // adjacencies'
  63. mpl::reverse_fold<Adjacencies,
  64. Incidences,
  65. mpl::push_back<mpl::_1,
  66. mpl::vector3<mpl::first<mpl::_2>, Source, mpl::second<mpl::_2> > > >
  67. {};
  68. template<typename AdjacencyList>
  69. struct produce_incidence_list_from_adjacency_list :
  70. mpl::reverse_fold<AdjacencyList,
  71. mpl::vector<>,
  72. produce_adjacencies_incidences<mpl::_1, mpl::first<mpl::_2>, mpl::second<mpl::_2> > >
  73. {};
  74. // Edge->pair<Source,Target> map for source, target
  75. template<typename GraphData>
  76. struct produce_edge_st_map<adjacency_list_tag, GraphData> :
  77. produce_edge_st_map<incidence_list_tag,
  78. typename produce_incidence_list_from_adjacency_list<GraphData>::type>
  79. {};
  80. // adjacency list supports zero-degree vertices, which incidence list does not
  81. template<typename VertexSet, typename Adjacencies>
  82. struct insert_adjacencies_targets : // adjacencies'
  83. mpl::reverse_fold<Adjacencies,
  84. VertexSet,
  85. mpl::insert<mpl::_1, mpl::second<mpl::_2> > >
  86. {};
  87. template<typename GraphData>
  88. struct produce_vertex_set<adjacency_list_tag, GraphData> :
  89. mpl::reverse_fold<GraphData,
  90. mpl::set<>,
  91. insert_adjacencies_targets<mpl::insert<mpl::_1, mpl::first<mpl::_2> >,
  92. mpl::second<mpl::_2> > >
  93. {};
  94. // Edge set for EdgeListGraph
  95. template<typename GraphData>
  96. struct produce_edge_set<adjacency_list_tag, GraphData> :
  97. produce_edge_set<incidence_list_tag,
  98. typename produce_incidence_list_from_adjacency_list<GraphData>::type>
  99. {};
  100. } // namespaces
  101. }
  102. }
  103. }
  104. #endif // BOOST_MSM_MPL_GRAPH_DETAIL_ADJACENCY_LIST_GRAPH_IPP_INCLUDED