ordered_out_edges.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. /*
  10. IMPORTANT:
  11. ~~~~~~~~~~
  12. This example appears to be broken and crashes at runtime, see https://github.com/boostorg/graph/issues/149
  13. */
  14. #include <boost/config.hpp>
  15. #include <iostream>
  16. #include <functional>
  17. #include <string>
  18. #include <boost/graph/adjacency_list.hpp>
  19. #include <boost/graph/properties.hpp>
  20. /*
  21. Sample output:
  22. 0 --chandler--> 1 --joe--> 1
  23. 1 --chandler--> 0 --joe--> 0 --curly--> 2 --dick--> 3 --dick--> 3
  24. 2 --curly--> 1 --tom--> 4
  25. 3 --dick--> 1 --dick--> 1 --harry--> 4
  26. 4 --tom--> 2 --harry--> 3
  27. name(0,1) = chandler
  28. name(0,1) = chandler
  29. name(0,1) = joe
  30. */
  31. template <class StoredEdge>
  32. struct order_by_name
  33. {
  34. typedef StoredEdge first_argument_type;
  35. typedef StoredEdge second_argument_type;
  36. typedef bool result_type;
  37. bool operator()(const StoredEdge& e1, const StoredEdge& e2) const {
  38. // Order by target vertex, then by name.
  39. // std::pair's operator< does a nice job of implementing
  40. // lexicographical compare on tuples.
  41. return std::make_pair(e1.get_target(), boost::get(boost::edge_name, e1))
  42. < std::make_pair(e2.get_target(), boost::get(boost::edge_name, e2));
  43. }
  44. };
  45. #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  46. struct ordered_set_by_nameS { };
  47. namespace boost {
  48. template <class ValueType>
  49. struct container_gen<ordered_set_by_nameS, ValueType> {
  50. typedef std::multiset<ValueType, order_by_name<ValueType> > type;
  51. };
  52. }
  53. #else
  54. struct ordered_set_by_nameS {
  55. template <class T>
  56. struct bind_ { typedef std::multiset<T, order_by_name<T> > type; };
  57. };
  58. namespace boost {
  59. template <> struct container_selector<ordered_set_by_nameS> {
  60. typedef ordered_set_by_nameS type;
  61. };
  62. }
  63. #endif
  64. namespace boost {
  65. template <>
  66. struct parallel_edge_traits<ordered_set_by_nameS> {
  67. typedef allow_parallel_edge_tag type;
  68. };
  69. }
  70. int
  71. main()
  72. {
  73. #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  74. std::cout << "This program requires partial specialization" << std::endl;
  75. #else
  76. using namespace boost;
  77. typedef property<edge_name_t, std::string> EdgeProperty;
  78. typedef adjacency_list<ordered_set_by_nameS, vecS, undirectedS,
  79. no_property, EdgeProperty> graph_type;
  80. graph_type g;
  81. add_edge(0, 1, EdgeProperty("joe"), g);
  82. add_edge(1, 2, EdgeProperty("curly"), g);
  83. add_edge(1, 3, EdgeProperty("dick"), g);
  84. add_edge(1, 3, EdgeProperty("dick"), g);
  85. add_edge(2, 4, EdgeProperty("tom"), g);
  86. add_edge(3, 4, EdgeProperty("harry"), g);
  87. add_edge(0, 1, EdgeProperty("chandler"), g);
  88. property_map<graph_type, vertex_index_t>::type id = get(vertex_index, g);
  89. property_map<graph_type, edge_name_t>::type name = get(edge_name, g);
  90. graph_traits<graph_type>::vertex_iterator i, end;
  91. graph_traits<graph_type>::out_edge_iterator ei, edge_end;
  92. for (boost::tie(i, end) = vertices(g); i != end; ++i) {
  93. std::cout << id[*i] << " ";
  94. for (boost::tie(ei, edge_end) = out_edges(*i, g); ei != edge_end; ++ei)
  95. std::cout << " --" << name[*ei] << "--> " << id[target(*ei, g)] << " ";
  96. std::cout << std::endl;
  97. }
  98. std::cout << std::endl;
  99. bool found;
  100. typedef graph_traits<graph_type> Traits;
  101. Traits::edge_descriptor e;
  102. Traits::out_edge_iterator e_first, e_last;
  103. boost::tie(e, found) = edge(0, 1, g);
  104. if (found)
  105. std::cout << "name(0,1) = " << name[e] << std::endl;
  106. else
  107. std::cout << "not found" << std::endl;
  108. std::cout << std::endl;
  109. boost::tie(e_first, e_last) = edge_range(0, 1, g);
  110. while (e_first != e_last)
  111. std::cout << "name(0,1) = " << name[*e_first++] << std::endl;
  112. #endif
  113. return 0;
  114. }