gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Small improvements + add tests for StaticDigraph (#68)
0 2 0
default
2 files changed with 118 insertions and 8 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -23,31 +23,31 @@
23 23
///\file
24 24
///\brief StaticDigraph class.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/bits/graph_extender.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  class StaticDigraphBase {
32 32
  public:
33 33

	
34 34
    StaticDigraphBase() 
35
      : node_num(-1), arc_num(0), 
35
      : built(false), node_num(0), arc_num(0), 
36 36
        node_first_out(NULL), node_first_in(NULL),
37 37
        arc_source(NULL), arc_target(NULL), 
38 38
        arc_next_in(NULL), arc_next_out(NULL) {}
39 39
    
40 40
    ~StaticDigraphBase() {
41
      if (node_num != -1) {
41
      if (built) {
42 42
        delete[] node_first_out;
43 43
        delete[] node_first_in;
44 44
        delete[] arc_source;
45 45
        delete[] arc_target;
46 46
        delete[] arc_next_out;
47 47
        delete[] arc_next_in;
48 48
      }
49 49
    }
50 50

	
51 51
    class Node {
52 52
      friend class StaticDigraphBase;
53 53
    protected:
... ...
@@ -119,39 +119,45 @@
119 119
      bool operator()(const Arc& left, const Arc& right) const {
120 120
	return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
121 121
      }
122 122
    private:
123 123
      const Digraph& digraph;
124 124
      const NodeRefMap& nodeRef;
125 125
    };
126 126
    
127 127
  public:
128 128

	
129 129
    typedef True BuildTag;
130 130
    
131
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
132
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
133

	
134
      if (node_num != -1) {
131
    void clear() {
132
      if (built) {
135 133
        delete[] node_first_out;
136 134
        delete[] node_first_in;
137 135
        delete[] arc_source;
138 136
        delete[] arc_target;
139 137
        delete[] arc_next_out;
140 138
        delete[] arc_next_in;
141 139
      }
142

	
140
      built = false;
141
      node_num = 0;
142
      arc_num = 0;
143
    }
144
    
145
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
146
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
143 147
      typedef typename Digraph::Node GNode;
144 148
      typedef typename Digraph::Arc GArc;
145 149

	
150
      built = true;
151

	
146 152
      node_num = countNodes(digraph);
147 153
      arc_num = countArcs(digraph);
148 154

	
149 155
      node_first_out = new int[node_num + 1];
150 156
      node_first_in = new int[node_num];
151 157

	
152 158
      arc_source = new int[arc_num];
153 159
      arc_target = new int[arc_num];
154 160
      arc_next_out = new int[arc_num];
155 161
      arc_next_in = new int[arc_num];
156 162

	
157 163
      int node_index = 0;
... ...
@@ -196,42 +202,52 @@
196 202

	
197 203
    void fastFirstOut(Arc& e, const Node& n) const {
198 204
      e.id = node_first_out[n.id];
199 205
    }
200 206

	
201 207
    static void fastNextOut(Arc& e) {
202 208
      ++e.id;
203 209
    }
204 210
    void fastLastOut(Arc& e, const Node& n) const {
205 211
      e.id = node_first_out[n.id + 1];
206 212
    }
207 213

	
208
  private:
214
  protected:
215
    bool built;
209 216
    int node_num;
210 217
    int arc_num;
211 218
    int *node_first_out;
212 219
    int *node_first_in;
213 220
    int *arc_source;
214 221
    int *arc_target;
215 222
    int *arc_next_in;
216 223
    int *arc_next_out;
217 224
  };
218 225

	
219 226
  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
220 227

	
221 228

	
222 229
  class StaticDigraph : public ExtendedStaticDigraphBase {
223 230
  public:
224 231

	
225 232
    typedef ExtendedStaticDigraphBase Parent;
233
  
234
  public:
235
  
236
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
237
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
238
      if (built) Parent::clear();
239
      Parent::build(digraph, nodeRef, arcRef);
240
    }
241
  
226 242

	
227 243
  protected:
228 244

	
229 245
    using Parent::fastFirstOut;
230 246
    using Parent::fastNextOut;
231 247
    using Parent::fastLastOut;
232 248
    
233 249
  public:
234 250

	
235 251
    class OutArcIt : public Arc {
236 252
    public:
237 253

	
... ...
@@ -252,17 +268,33 @@
252 268
      }
253 269

	
254 270
      OutArcIt& operator++() { 
255 271
        StaticDigraph::fastNextOut(*this);
256 272
        if (last == *this) *this = INVALID;
257 273
        return *this; 
258 274
      }
259 275

	
260 276
    private:
261 277
      Arc last;
262 278
    };
263 279

	
280
    Node baseNode(const OutArcIt &arc) const {
281
      return Parent::source(static_cast<const Arc&>(arc));
282
    }
283

	
284
    Node runningNode(const OutArcIt &arc) const {
285
      return Parent::target(static_cast<const Arc&>(arc));
286
    }
287

	
288
    Node baseNode(const InArcIt &arc) const {
289
      return Parent::target(static_cast<const Arc&>(arc));
290
    }
291

	
292
    Node runningNode(const InArcIt &arc) const {
293
      return Parent::source(static_cast<const Arc&>(arc));
294
    }
295

	
264 296
  };
265 297

	
266 298
}
267 299

	
268 300
#endif
Ignore white space 24 line context
... ...
@@ -10,24 +10,25 @@
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22
#include <lemon/static_graph.h>
22 23
#include <lemon/full_graph.h>
23 24

	
24 25
#include "test_tools.h"
25 26
#include "graph_test.h"
26 27

	
27 28
using namespace lemon;
28 29
using namespace lemon::concepts;
29 30

	
30 31
template <class Digraph>
31 32
void checkDigraphBuild() {
32 33
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
33 34
  Digraph G;
... ...
@@ -308,24 +309,28 @@
308 309
    checkConcept<Digraph, ListDigraph>();
309 310
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
310 311
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
311 312
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
312 313
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
313 314
  }
314 315
  { // Checking SmartDigraph
315 316
    checkConcept<Digraph, SmartDigraph>();
316 317
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
317 318
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
318 319
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
319 320
  }
321
  { // Checking StaticDigraph
322
    checkConcept<Digraph, StaticDigraph>();
323
    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
324
  }
320 325
  { // Checking FullDigraph
321 326
    checkConcept<Digraph, FullDigraph>();
322 327
  }
323 328
}
324 329

	
325 330
template <typename Digraph>
326 331
void checkDigraphValidity() {
327 332
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
328 333
  Digraph g;
329 334

	
330 335
  Node
331 336
    n1 = g.addNode(),
... ...
@@ -363,24 +368,94 @@
363 368
  g.erase(n1);
364 369

	
365 370
  check(!g.valid(n1), "Wrong validity check");
366 371
  check(g.valid(n2), "Wrong validity check");
367 372
  check(g.valid(n3), "Wrong validity check");
368 373
  check(!g.valid(e1), "Wrong validity check");
369 374
  check(g.valid(e2), "Wrong validity check");
370 375

	
371 376
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
372 377
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 378
}
374 379

	
380
void checkStaticDigraph() {
381
  SmartDigraph g;
382
  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
383
  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
384
  
385
  StaticDigraph G;
386
  
387
  checkGraphNodeList(G, 0);
388
  checkGraphArcList(G, 0);
389

	
390
  G.build(g, nref, aref);
391

	
392
  checkGraphNodeList(G, 0);
393
  checkGraphArcList(G, 0);
394

	
395
  SmartDigraph::Node
396
    n1 = g.addNode(),
397
    n2 = g.addNode(),
398
    n3 = g.addNode();
399

	
400
  G.build(g, nref, aref);
401

	
402
  checkGraphNodeList(G, 3);
403
  checkGraphArcList(G, 0);
404

	
405
  SmartDigraph::Arc a1 = g.addArc(n1, n2);
406

	
407
  G.build(g, nref, aref);
408

	
409
  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
410
        "Wrong arc or wrong references");
411
  checkGraphNodeList(G, 3);
412
  checkGraphArcList(G, 1);
413

	
414
  checkGraphOutArcList(G, nref[n1], 1);
415
  checkGraphOutArcList(G, nref[n2], 0);
416
  checkGraphOutArcList(G, nref[n3], 0);
417

	
418
  checkGraphInArcList(G, nref[n1], 0);
419
  checkGraphInArcList(G, nref[n2], 1);
420
  checkGraphInArcList(G, nref[n3], 0);
421

	
422
  checkGraphConArcList(G, 1);
423

	
424
  SmartDigraph::Arc
425
    a2 = g.addArc(n2, n1),
426
    a3 = g.addArc(n2, n3),
427
    a4 = g.addArc(n2, n3);
428

	
429
  digraphCopy(g, G).nodeRef(nref).run();
430

	
431
  checkGraphNodeList(G, 3);
432
  checkGraphArcList(G, 4);
433

	
434
  checkGraphOutArcList(G, nref[n1], 1);
435
  checkGraphOutArcList(G, nref[n2], 3);
436
  checkGraphOutArcList(G, nref[n3], 0);
437

	
438
  checkGraphInArcList(G, nref[n1], 1);
439
  checkGraphInArcList(G, nref[n2], 1);
440
  checkGraphInArcList(G, nref[n3], 2);
441

	
442
  checkGraphConArcList(G, 4);
443

	
444
  checkNodeIds(G);
445
  checkArcIds(G);
446
  checkGraphNodeMap(G);
447
  checkGraphArcMap(G);
448
}
449

	
375 450
void checkFullDigraph(int num) {
376 451
  typedef FullDigraph Digraph;
377 452
  DIGRAPH_TYPEDEFS(Digraph);
378 453
  Digraph G(num);
379 454

	
380 455
  checkGraphNodeList(G, num);
381 456
  checkGraphArcList(G, num * num);
382 457

	
383 458
  for (NodeIt n(G); n != INVALID; ++n) {
384 459
    checkGraphOutArcList(G, n, num);
385 460
    checkGraphInArcList(G, n, num);
386 461
  }
... ...
@@ -410,22 +485,25 @@
410 485
    checkDigraphSplit<ListDigraph>();
411 486
    checkDigraphAlter<ListDigraph>();
412 487
    checkDigraphErase<ListDigraph>();
413 488
    checkDigraphSnapshot<ListDigraph>();
414 489
    checkDigraphValidityErase<ListDigraph>();
415 490
  }
416 491
  { // Checking SmartDigraph
417 492
    checkDigraphBuild<SmartDigraph>();
418 493
    checkDigraphSplit<SmartDigraph>();
419 494
    checkDigraphSnapshot<SmartDigraph>();
420 495
    checkDigraphValidity<SmartDigraph>();
421 496
  }
497
  { // Checking StaticDigraph
498
    checkStaticDigraph();
499
  }
422 500
  { // Checking FullDigraph
423 501
    checkFullDigraph(8);
424 502
  }
425 503
}
426 504

	
427 505
int main() {
428 506
  checkDigraphs();
429 507
  checkConcepts();
430 508
  return 0;
431 509
}
0 comments (0 inline)