gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improvements for graph maps (#302) - Add a count() function to CrossRefMap. - Add tests for IdMap and RangeIdMap. - Extend tests for CrossRefMap. - Improve the doc.
0 2 0
default
2 files changed with 123 insertions and 5 deletions:
↑ Collapse diff ↑
Ignore white space 24 line context
... ...
@@ -1817,25 +1817,25 @@
1817 1817

	
1818 1818
  /// \brief Provides an immutable and unique id for each item in a graph.
1819 1819
  ///
1820 1820
  /// IdMap provides a unique and immutable id for each item of the
1821 1821
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
1822 1822
  ///  - \b unique: different items get different ids,
1823 1823
  ///  - \b immutable: the id of an item does not change (even if you
1824 1824
  ///    delete other nodes).
1825 1825
  ///
1826 1826
  /// Using this map you get access (i.e. can read) the inner id values of
1827 1827
  /// the items stored in the graph, which is returned by the \c id()
1828 1828
  /// function of the graph. This map can be inverted with its member
1829
  /// class \c InverseMap or with the \c operator() member.
1829
  /// class \c InverseMap or with the \c operator()() member.
1830 1830
  ///
1831 1831
  /// \tparam GR The graph type.
1832 1832
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1833 1833
  /// \c GR::Edge).
1834 1834
  ///
1835 1835
  /// \see RangeIdMap
1836 1836
  template <typename GR, typename K>
1837 1837
  class IdMap : public MapBase<K, int> {
1838 1838
  public:
1839 1839
    /// The graph type of IdMap.
1840 1840
    typedef GR Graph;
1841 1841
    typedef GR Digraph;
... ...
@@ -2024,24 +2024,32 @@
2024 2024
    }
2025 2025

	
2026 2026
    /// \brief Gives back an item by its value.
2027 2027
    ///
2028 2028
    /// This function gives back an item that is assigned to
2029 2029
    /// the given value or \c INVALID if no such item exists.
2030 2030
    /// If there are more items with the same associated value,
2031 2031
    /// only one of them is returned.
2032 2032
    Key operator()(const Value& val) const {
2033 2033
      typename Container::const_iterator it = _inv_map.find(val);
2034 2034
      return it != _inv_map.end() ? it->second : INVALID;
2035 2035
    }
2036
    
2037
    /// \brief Returns the number of items with the given value.
2038
    ///
2039
    /// This function returns the number of items with the given value
2040
    /// associated with it.
2041
    int count(const Value &val) const {
2042
      return _inv_map.count(val);
2043
    }
2036 2044

	
2037 2045
  protected:
2038 2046

	
2039 2047
    /// \brief Erase the key from the map and the inverse map.
2040 2048
    ///
2041 2049
    /// Erase the key from the map and the inverse map. It is called by the
2042 2050
    /// \c AlterationNotifier.
2043 2051
    virtual void erase(const Key& key) {
2044 2052
      Value val = Map::operator[](key);
2045 2053
      typename Container::iterator it;
2046 2054
      for (it = _inv_map.equal_range(val).first;
2047 2055
           it != _inv_map.equal_range(val).second; ++it) {
... ...
@@ -2113,40 +2121,40 @@
2113 2121
      const CrossRefMap& _inverted;
2114 2122
    };
2115 2123

	
2116 2124
    /// \brief It gives back the read-only inverse map.
2117 2125
    ///
2118 2126
    /// It gives back the read-only inverse map.
2119 2127
    InverseMap inverse() const {
2120 2128
      return InverseMap(*this);
2121 2129
    }
2122 2130

	
2123 2131
  };
2124 2132

	
2125
  /// \brief Provides continuous and unique ID for the
2133
  /// \brief Provides continuous and unique id for the
2126 2134
  /// items of a graph.
2127 2135
  ///
2128 2136
  /// RangeIdMap provides a unique and continuous
2129
  /// ID for each item of a given type (\c Node, \c Arc or
2137
  /// id for each item of a given type (\c Node, \c Arc or
2130 2138
  /// \c Edge) in a graph. This id is
2131 2139
  ///  - \b unique: different items get different ids,
2132 2140
  ///  - \b continuous: the range of the ids is the set of integers
2133 2141
  ///    between 0 and \c n-1, where \c n is the number of the items of
2134 2142
  ///    this type (\c Node, \c Arc or \c Edge).
2135 2143
  ///  - So, the ids can change when deleting an item of the same type.
2136 2144
  ///
2137 2145
  /// Thus this id is not (necessarily) the same as what can get using
2138 2146
  /// the \c id() function of the graph or \ref IdMap.
2139 2147
  /// This map can be inverted with its member class \c InverseMap,
2140
  /// or with the \c operator() member.
2148
  /// or with the \c operator()() member.
2141 2149
  ///
2142 2150
  /// \tparam GR The graph type.
2143 2151
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2144 2152
  /// \c GR::Edge).
2145 2153
  ///
2146 2154
  /// \see IdMap
2147 2155
  template <typename GR, typename K>
2148 2156
  class RangeIdMap
2149 2157
    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
2150 2158

	
2151 2159
    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
2152 2160

	
Ignore white space 24 line context
... ...
@@ -320,69 +320,179 @@
320 320
    ConstMap<int, double> cm(2.0);
321 321
    IdentityMap<int> im;
322 322
    ConvertMap<IdentityMap<int>, double> id(im);
323 323
    check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
324 324
          "Something is wrong with LessMap");
325 325
    check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
326 326
          "Something is wrong with EqualMap");
327 327
  }
328 328

	
329 329
  // LoggerBoolMap
330 330
  {
331 331
    typedef std::vector<int> vec;
332
    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
333
    checkConcept<WriteMap<int, bool>,
334
                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
335

	
332 336
    vec v1;
333 337
    vec v2(10);
334 338
    LoggerBoolMap<std::back_insert_iterator<vec> >
335 339
      map1(std::back_inserter(v1));
336 340
    LoggerBoolMap<vec::iterator> map2(v2.begin());
337 341
    map1.set(10, false);
338 342
    map1.set(20, true);   map2.set(20, true);
339 343
    map1.set(30, false);  map2.set(40, false);
340 344
    map1.set(50, true);   map2.set(50, true);
341 345
    map1.set(60, true);   map2.set(60, true);
342 346
    check(v1.size() == 3 && v2.size() == 10 &&
343 347
          v1[0]==20 && v1[1]==50 && v1[2]==60 &&
344 348
          v2[0]==20 && v2[1]==50 && v2[2]==60,
345 349
          "Something is wrong with LoggerBoolMap");
346 350

	
347 351
    int i = 0;
348 352
    for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
349 353
          it != map2.end(); ++it )
350 354
      check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
351 355
  }
352 356
  
357
  // IdMap, RangeIdMap
358
  {
359
    typedef ListDigraph Graph;
360
    DIGRAPH_TYPEDEFS(Graph);
361

	
362
    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
363
    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
364
    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
365
    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
366
    
367
    Graph gr;
368
    IdMap<Graph, Node> nmap(gr);
369
    IdMap<Graph, Arc> amap(gr);
370
    RangeIdMap<Graph, Node> nrmap(gr);
371
    RangeIdMap<Graph, Arc> armap(gr);
372
    
373
    Node n0 = gr.addNode();
374
    Node n1 = gr.addNode();
375
    Node n2 = gr.addNode();
376
    
377
    Arc a0 = gr.addArc(n0, n1);
378
    Arc a1 = gr.addArc(n0, n2);
379
    Arc a2 = gr.addArc(n2, n1);
380
    Arc a3 = gr.addArc(n2, n0);
381
    
382
    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
383
    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
384
    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
385

	
386
    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
387
    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
388
    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
389
    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
390

	
391
    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
392
    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
393
    
394
    check(nrmap.size() == 3 && armap.size() == 4,
395
          "Wrong RangeIdMap::size()");
396

	
397
    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
398
    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
399
    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
400
    
401
    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
402
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
403
    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
404
    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
405

	
406
    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
407
    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
408
    
409
    gr.erase(n1);
410
    
411
    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
412
    nrmap.swap(n2, n0);
413
    if (armap[a1] == 1) armap.swap(a1, a3);
414
    armap.swap(a3, a1);
415
    
416
    check(nrmap.size() == 2 && armap.size() == 2,
417
          "Wrong RangeIdMap::size()");
418

	
419
    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
420
    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
421
    
422
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
423
    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
424

	
425
    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
426
    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
427
  }
428
  
353 429
  // CrossRefMap
354 430
  {
355 431
    typedef ListDigraph Graph;
356 432
    DIGRAPH_TYPEDEFS(Graph);
357 433

	
358 434
    checkConcept<ReadWriteMap<Node, int>,
359 435
                 CrossRefMap<Graph, Node, int> >();
436
    checkConcept<ReadWriteMap<Node, bool>,
437
                 CrossRefMap<Graph, Node, bool> >();
438
    checkConcept<ReadWriteMap<Node, double>,
439
                 CrossRefMap<Graph, Node, double> >();
360 440
    
361 441
    Graph gr;
362 442
    typedef CrossRefMap<Graph, Node, char> CRMap;
363 443
    typedef CRMap::ValueIterator ValueIt;
364 444
    CRMap map(gr);
365 445
    
366 446
    Node n0 = gr.addNode();
367 447
    Node n1 = gr.addNode();
368 448
    Node n2 = gr.addNode();
369 449
    
370 450
    map.set(n0, 'A');
371 451
    map.set(n1, 'B');
372 452
    map.set(n2, 'C');
453
    
454
    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
455
          "Wrong CrossRefMap");
456
    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
457
          "Wrong CrossRefMap");
458
    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
459
          "Wrong CrossRefMap");
460
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
461
          "Wrong CrossRefMap::count()");
462
    
463
    ValueIt it = map.beginValue();
464
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
465
          it == map.endValue(), "Wrong value iterator");
466
    
373 467
    map.set(n2, 'A');
468

	
469
    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
470
          "Wrong CrossRefMap");
471
    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
472
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
473
    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
474
          "Wrong CrossRefMap");
475
    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
476
          "Wrong CrossRefMap::count()");
477

	
478
    it = map.beginValue();
479
    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
480
          it == map.endValue(), "Wrong value iterator");
481

	
374 482
    map.set(n0, 'C');
375 483

	
376 484
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
377 485
          "Wrong CrossRefMap");
378 486
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
379 487
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
380 488
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
489
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
490
          "Wrong CrossRefMap::count()");
381 491

	
382
    ValueIt it = map.beginValue();
492
    it = map.beginValue();
383 493
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
384 494
          it == map.endValue(), "Wrong value iterator");
385 495
  }
386 496

	
387 497
  return 0;
388 498
}
0 comments (0 inline)