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