Improvements for graph maps (#302)
authorPeter Kovacs <kpeter@inf.elte.hu>
Thu, 23 Jul 2009 18:13:59 +0200
changeset 7206e8c27ee9079
parent 684 7b1a6e963018
child 721 99124ea4f048
Improvements for graph maps (#302)

- Add a count() function to CrossRefMap.
- Add tests for IdMap and RangeIdMap.
- Extend tests for CrossRefMap.
- Improve the doc.
lemon/maps.h
test/maps_test.cc
     1.1 --- a/lemon/maps.h	Thu Jul 23 18:09:41 2009 +0200
     1.2 +++ b/lemon/maps.h	Thu Jul 23 18:13:59 2009 +0200
     1.3 @@ -1826,7 +1826,7 @@
     1.4    /// Using this map you get access (i.e. can read) the inner id values of
     1.5    /// the items stored in the graph, which is returned by the \c id()
     1.6    /// function of the graph. This map can be inverted with its member
     1.7 -  /// class \c InverseMap or with the \c operator() member.
     1.8 +  /// class \c InverseMap or with the \c operator()() member.
     1.9    ///
    1.10    /// \tparam GR The graph type.
    1.11    /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
    1.12 @@ -2033,6 +2033,14 @@
    1.13        typename Container::const_iterator it = _inv_map.find(val);
    1.14        return it != _inv_map.end() ? it->second : INVALID;
    1.15      }
    1.16 +    
    1.17 +    /// \brief Returns the number of items with the given value.
    1.18 +    ///
    1.19 +    /// This function returns the number of items with the given value
    1.20 +    /// associated with it.
    1.21 +    int count(const Value &val) const {
    1.22 +      return _inv_map.count(val);
    1.23 +    }
    1.24  
    1.25    protected:
    1.26  
    1.27 @@ -2122,11 +2130,11 @@
    1.28  
    1.29    };
    1.30  
    1.31 -  /// \brief Provides continuous and unique ID for the
    1.32 +  /// \brief Provides continuous and unique id for the
    1.33    /// items of a graph.
    1.34    ///
    1.35    /// RangeIdMap provides a unique and continuous
    1.36 -  /// ID for each item of a given type (\c Node, \c Arc or
    1.37 +  /// id for each item of a given type (\c Node, \c Arc or
    1.38    /// \c Edge) in a graph. This id is
    1.39    ///  - \b unique: different items get different ids,
    1.40    ///  - \b continuous: the range of the ids is the set of integers
    1.41 @@ -2137,7 +2145,7 @@
    1.42    /// Thus this id is not (necessarily) the same as what can get using
    1.43    /// the \c id() function of the graph or \ref IdMap.
    1.44    /// This map can be inverted with its member class \c InverseMap,
    1.45 -  /// or with the \c operator() member.
    1.46 +  /// or with the \c operator()() member.
    1.47    ///
    1.48    /// \tparam GR The graph type.
    1.49    /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
     2.1 --- a/test/maps_test.cc	Thu Jul 23 18:09:41 2009 +0200
     2.2 +++ b/test/maps_test.cc	Thu Jul 23 18:13:59 2009 +0200
     2.3 @@ -329,6 +329,10 @@
     2.4    // LoggerBoolMap
     2.5    {
     2.6      typedef std::vector<int> vec;
     2.7 +    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
     2.8 +    checkConcept<WriteMap<int, bool>,
     2.9 +                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
    2.10 +
    2.11      vec v1;
    2.12      vec v2(10);
    2.13      LoggerBoolMap<std::back_insert_iterator<vec> >
    2.14 @@ -350,6 +354,78 @@
    2.15        check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
    2.16    }
    2.17    
    2.18 +  // IdMap, RangeIdMap
    2.19 +  {
    2.20 +    typedef ListDigraph Graph;
    2.21 +    DIGRAPH_TYPEDEFS(Graph);
    2.22 +
    2.23 +    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
    2.24 +    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
    2.25 +    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
    2.26 +    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
    2.27 +    
    2.28 +    Graph gr;
    2.29 +    IdMap<Graph, Node> nmap(gr);
    2.30 +    IdMap<Graph, Arc> amap(gr);
    2.31 +    RangeIdMap<Graph, Node> nrmap(gr);
    2.32 +    RangeIdMap<Graph, Arc> armap(gr);
    2.33 +    
    2.34 +    Node n0 = gr.addNode();
    2.35 +    Node n1 = gr.addNode();
    2.36 +    Node n2 = gr.addNode();
    2.37 +    
    2.38 +    Arc a0 = gr.addArc(n0, n1);
    2.39 +    Arc a1 = gr.addArc(n0, n2);
    2.40 +    Arc a2 = gr.addArc(n2, n1);
    2.41 +    Arc a3 = gr.addArc(n2, n0);
    2.42 +    
    2.43 +    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
    2.44 +    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
    2.45 +    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
    2.46 +
    2.47 +    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
    2.48 +    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
    2.49 +    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
    2.50 +    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
    2.51 +
    2.52 +    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
    2.53 +    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
    2.54 +    
    2.55 +    check(nrmap.size() == 3 && armap.size() == 4,
    2.56 +          "Wrong RangeIdMap::size()");
    2.57 +
    2.58 +    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
    2.59 +    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
    2.60 +    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
    2.61 +    
    2.62 +    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
    2.63 +    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
    2.64 +    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
    2.65 +    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
    2.66 +
    2.67 +    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
    2.68 +    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
    2.69 +    
    2.70 +    gr.erase(n1);
    2.71 +    
    2.72 +    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
    2.73 +    nrmap.swap(n2, n0);
    2.74 +    if (armap[a1] == 1) armap.swap(a1, a3);
    2.75 +    armap.swap(a3, a1);
    2.76 +    
    2.77 +    check(nrmap.size() == 2 && armap.size() == 2,
    2.78 +          "Wrong RangeIdMap::size()");
    2.79 +
    2.80 +    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
    2.81 +    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
    2.82 +    
    2.83 +    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
    2.84 +    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
    2.85 +
    2.86 +    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
    2.87 +    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
    2.88 +  }
    2.89 +  
    2.90    // CrossRefMap
    2.91    {
    2.92      typedef ListDigraph Graph;
    2.93 @@ -357,6 +433,10 @@
    2.94  
    2.95      checkConcept<ReadWriteMap<Node, int>,
    2.96                   CrossRefMap<Graph, Node, int> >();
    2.97 +    checkConcept<ReadWriteMap<Node, bool>,
    2.98 +                 CrossRefMap<Graph, Node, bool> >();
    2.99 +    checkConcept<ReadWriteMap<Node, double>,
   2.100 +                 CrossRefMap<Graph, Node, double> >();
   2.101      
   2.102      Graph gr;
   2.103      typedef CrossRefMap<Graph, Node, char> CRMap;
   2.104 @@ -370,7 +450,35 @@
   2.105      map.set(n0, 'A');
   2.106      map.set(n1, 'B');
   2.107      map.set(n2, 'C');
   2.108 +    
   2.109 +    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
   2.110 +          "Wrong CrossRefMap");
   2.111 +    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
   2.112 +          "Wrong CrossRefMap");
   2.113 +    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
   2.114 +          "Wrong CrossRefMap");
   2.115 +    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
   2.116 +          "Wrong CrossRefMap::count()");
   2.117 +    
   2.118 +    ValueIt it = map.beginValue();
   2.119 +    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
   2.120 +          it == map.endValue(), "Wrong value iterator");
   2.121 +    
   2.122      map.set(n2, 'A');
   2.123 +
   2.124 +    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
   2.125 +          "Wrong CrossRefMap");
   2.126 +    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
   2.127 +    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
   2.128 +    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
   2.129 +          "Wrong CrossRefMap");
   2.130 +    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
   2.131 +          "Wrong CrossRefMap::count()");
   2.132 +
   2.133 +    it = map.beginValue();
   2.134 +    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
   2.135 +          it == map.endValue(), "Wrong value iterator");
   2.136 +
   2.137      map.set(n0, 'C');
   2.138  
   2.139      check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
   2.140 @@ -378,8 +486,10 @@
   2.141      check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
   2.142      check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
   2.143      check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
   2.144 +    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
   2.145 +          "Wrong CrossRefMap::count()");
   2.146  
   2.147 -    ValueIt it = map.beginValue();
   2.148 +    it = map.beginValue();
   2.149      check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
   2.150            it == map.endValue(), "Wrong value iterator");
   2.151    }