dump.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // Ah... The joys graph data structures :)
  2. // A hole into which many a good computer scientist has fallen, never to be heard from again.
  3. // - Andrew Sutton
  4. /*
  5. Basic idea: provide concepts that define the interface(s) to different kinds of graphs so that you can do
  6. basic graph operations and algoriths without knowing exactly which kind of graph it is and keep ignorant
  7. about implementation details.
  8. Basic design idea: do like the STL
  9. */
  10. /*
  11. // Graph concepts (like STL containers):
  12. // Do we need them (STL doesn't make containers explicit)
  13. template<class G> concept bool Graph = false; // general graph operations
  14. template<class G> concept bool DAG = false; // operations simplified for DAGs (any extra operations?)
  15. template<class G> concept bool Tree = false; // operations simplified for trees (any extra operations?)
  16. // accessor concepts (like STL Iterators):
  17. template<class G> concept bool Edge_ref = false; // most general and slowest
  18. template<class G> concept bool DAG_edge_ref = false; // operations simplified for DAGs (any extra operations?)
  19. template<class G> concept bool Tree_edge_ref = false; // operations simplified for trees (any extra operations?)
  20. template<class G> concept bool Vertex_ref = false; // most general and slowest
  21. template<class G> concept bool DAG_vertex_ref = false; // operations simplified for DAGs (any extra operations?)
  22. template<class G> concept bool Tree_vertex_ref = false; // operations simplified for DAGs (any extra operations?)
  23. // the value type (in a more general design, this would be a template parmeter):
  24. struct Val {};
  25. // specific directed graphs:
  26. struct Tree {};
  27. struct Dag { };
  28. struct Dgraph {};
  29. struct Node_ref {};
  30. struct Edge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  31. struct DAG_vertex_ref {};
  32. struct DAG_edge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  33. struct Gnode_ref {};
  34. struct Gedge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  35. // another Graph representation:
  36. struct DGN_ref {};
  37. struct DGE_ref {}; // Is an Edge an object? (if not, refer to parent node)
  38. // use:
  39. template<Graph G>
  40. void traverse(G& g)
  41. {
  42. vector<???> found; // there is a way (look up traits), lets try g::value_type
  43. }
  44. */
  45. /*
  46. Basic idea: provide concepts that define the interface(s) to different kinds of graphs so that you can do
  47. basic graph operations and algoriths without knowing exactly which kind of graph it is and keep ignorant
  48. about implementation details.
  49. Basic design idea: do like the STL
  50. */
  51. /*
  52. // Graph concepts (like STL containers):
  53. // Do we need them (STL doesn't make containers explicit)
  54. template<class G> concept bool Graph = // general graph operations
  55. requires { typename G::value_type; };
  56. template<class G> concept bool DAG = Graph<G> && requires(G g) { tops(g); }; // operations simplified for DAGs
  57. template<class G> concept bool Tree = DAG<G> && requires(G g) { top(g); }; // operations simplified for trees
  58. // accessor concepts (like STL Iterators):
  59. template<class E> concept bool Edge_ref = // most general and slowest
  60. requires { typename E::value_type; };
  61. template<class E> concept bool DAG_edge_ref = // operations simplified for DAGs (any extra operations?)
  62. Edge_ref<E> && false;
  63. template<class E> concept bool Tree_edge_ref = // operations simplified for trees (any extra operations?)
  64. DAG_edge_ref<E> && false;
  65. template<class G> concept bool Vertex_ref = true; // most general and slowest
  66. template<class G> concept bool DAG_vertex_ref = false; // operations simplified for DAGs (any extra operations?)
  67. template<class G> concept bool Tree_vertex_ref = false; // operations simplified for DAGs (any extra operations?)
  68. // the value type (in a more general design, this would be a template parmeter):
  69. struct Val {};
  70. // specific directed graphs (note: we can't assume common structure or common naming from implementation):
  71. struct Tree {
  72. using value_type = Val;
  73. };
  74. struct Node_ref {};
  75. struct Edge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  76. void tops(Tree&); // return vector Tree_vertex_refs
  77. Node_ref top(Tree&);
  78. struct Dag {
  79. using value_type = Val;
  80. };
  81. struct DAG_vertex_ref {};
  82. struct DAG_edge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  83. void tops(Dag&);
  84. struct Dgraph {
  85. using value_type = Val;
  86. };
  87. struct Gnode_ref {};
  88. struct Gedge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  89. // another Graph representation:
  90. struct DGN_ref {};
  91. struct DGE_ref {}; // Is an Edge an object? (if not, refer to parent node)
  92. // use:
  93. #include <vector>
  94. using namespace std;
  95. template<Graph G, Vertex_ref R>
  96. void traverse(G& g, R r)
  97. {
  98. vector<typename G::value_type> found; // member g::value_type (old habit: could just have used Val)
  99. // ...
  100. }
  101. void use1(Tree& t, Dag& d, Dgraph& dg, Node_ref& tr, DAG_vertex_ref& dr, Gnode_ref& gr)
  102. {
  103. traverse(t,tr);
  104. traverse(d,dr);
  105. traverse(dg,gr);
  106. }
  107. */
  108. /*
  109. Basic idea: provide concepts that define the interface(s) to different kinds of graphs so that you can do
  110. basic graph operations and algoriths without knowing exactly which kind of graph it is and keep ignorant
  111. about implementation details.
  112. Basic design idea: do like the STL
  113. */
  114. /*
  115. // Graph concepts (like STL containers):
  116. // Do we need them (STL doesn't make containers explicit)
  117. template<class G> concept bool Graph = // general graph operations
  118. requires { typename G::value_type; };
  119. template<class G> concept bool DAG = Graph<G> && requires(G g) { tops(g); }; // operations simplified for DAGs
  120. template<class G> concept bool Tree = DAG<G> && requires(G g) { top(g); }; // operations simplified for trees
  121. // accessor concepts (like STL Iterators):
  122. template<class E> concept bool Edge_ref = // most general and slowest
  123. requires(E e) {
  124. typename E::value_type;
  125. { *e } -> typename E::value_type;
  126. { e.vertex } -> Vertex_ref;
  127. };
  128. template<class E> concept bool DAG_edge_ref = // operations simplified for DAGs (any extra operations?)
  129. Edge_ref<E> && false;
  130. template<class E> concept bool Tree_edge_ref = // operations simplified for trees (any extra operations?)
  131. DAG_edge_ref<E> && false;
  132. template<class V> concept bool Vertex_ref = // most general and slowest
  133. requires(V v, int i) {
  134. typename V::value_type;
  135. { *v } -> typename V::value_type;
  136. { v.edge[i] } -> Edge_ref;
  137. };
  138. template<class V> concept bool DAG_vertex_ref = false; // operations simplified for DAGs (any extra operations?)
  139. template<class V> concept bool Tree_vertex_ref = false; // operations simplified for DAGs (any extra operations?)
  140. // the value type (in a more general design, this would be a template parmeter):
  141. struct Val {};
  142. // specific directed graphs (note: we can't assume common structure or common naming from implementation):
  143. struct Tree {
  144. using value_type = Val;
  145. };
  146. struct Node_ref {};
  147. struct Edge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  148. void tops(Tree&); // return vector Tree_vertex_refs
  149. Node_ref top(Tree&);
  150. struct Dag {
  151. using value_type = Val;
  152. };
  153. struct DAG_vertex_ref {};
  154. struct DAG_edge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  155. void tops(Dag&);
  156. struct Dgraph {
  157. using value_type = Val;
  158. };
  159. struct Gnode_ref {};
  160. struct Gedge_ref {}; // Is an Edge an object? (if not, refer to parent node)
  161. // another Graph representation:
  162. struct DGN_ref {};
  163. struct DGE_ref {}; // Is an Edge an object? (if not, refer to parent node)
  164. // use:
  165. #include <vector>
  166. using namespace std;
  167. template<Graph G, Vertex_ref R>
  168. void traverse(G& g, R r)
  169. {
  170. vector<typename G::value_type> found; // member g::value_type (old habit: could just have used Val)
  171. // ...
  172. }
  173. void use1(Tree& t, Dag& d, Dgraph& dg, Node_ref& tr, DAG_vertex_ref& dr, Gnode_ref& gr)
  174. {
  175. traverse(t,tr);
  176. traverse(d,dr);
  177. traverse(dg,gr);
  178. }