COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/klao/iter_map.h @ 987:87f7c54892df

Last change on this file since 987:87f7c54892df was 987:87f7c54892df, checked in by Alpar Juttner, 20 years ago

Naming changes:

File size: 3.2 KB
RevLine 
[347]1// -*- c++ -*- //
2
[921]3#ifndef LEMON_ITER_MAP
4#define LEMON_ITER_MAP
[347]5
6#include <vector>
7#include <algorithm>
8// for uint8_t
9#include <stdint.h>
10// for memset
11#include <cstring>
12
[921]13#include <lemon/invalid.h>
[347]14
[921]15namespace lemon {
[347]16
[367]17  /// \brief A map with "small integers" as value set which can enumarate it
18  /// value classes
[347]19
20  /// \todo Decide whether we need all the range checkings!!!
21
[367]22  /// \todo Implement dynamic map behaviour. Is it necessary? Yes it is.
23
[361]24  template<typename KeyIntMap, uint8_t N, typename Val = uint8_t>
[347]25  class IterableMap {
26  public:
27
[987]28    typedef typename KeyIntMap::Key Key;
29    typedef Val Value;
[347]30
[987]31    typedef typename std::vector<Key>::const_iterator iterator;
[347]32
33  protected:
34    KeyIntMap &base;
[987]35    std::vector<Key> data;
[347]36    size_t bounds[N];
[361]37    Val def_val;
[347]38
[361]39    Val find(size_t a) const {
40      for(uint8_t n=0; n<N; ++n) {
41        if(bounds[n] > a)
42          return n;
43      }
44      return def_val;
[347]45    }
46
47    void half_swap(size_t &a, size_t b) {
48      if(a != b) {
49        base.set(data[b],a);
50        data[a] = data[b];
51        a = b;
52      }
53    }
54
55    size_t move(size_t a, uint8_t m, uint8_t n) {
56      if(m != n) {
57        size_t orig_a = a;
[987]58        Key orig_key = data[a];
[347]59        while(m > n) {
60          --m;
61          half_swap(a, bounds[m]++);
62        }
[362]63        // FIXME: range check ide?
[347]64        while(m < n) {
65          half_swap(a, --bounds[m]);
66          ++m;
67        }
68        if(a != orig_a) {
69          base.set(orig_key, a);
70          data[a]=orig_key;
71        }
72      }
73      return a;
74    }
75
76  public:
77   
[361]78    IterableMap(KeyIntMap &_base, Val d = N+1) : base(_base), def_val(d) {
[347]79      memset(bounds, 0, sizeof(bounds));
80      //    for(int i=0; i<N; ++i) { bounds[i]=0; }
81    }
82
[987]83    Val operator[](const Key& k) const {
[347]84      return find(base[k]);
85    }
86
[987]87    void set(const Key& k, Val n) {
[362]88      // FIXME: range check?
[347]89      size_t a = base[k];
[362]90      if(a < bounds[N-1]) {
[367]91        move(a, find(a), n);
[347]92      }
[362]93      else {
94        insert(k, n);
95      }
[347]96    }
97
[987]98    void insert(const Key& k, Val n) {
[362]99      data.push_back(k);
100      base.set(k, move(bounds[N-1]++, N-1, n));
[347]101    }
102
[367]103    /// This func is not very usable, but necessary to implement
104    /// dynamic map behaviour.
[987]105    void remove(const Key& k) {
[367]106      size_t a = base[k];
107      if(a < bounds[N-1]) {
108        move(a, find(a), N);
109        data.pop_back();
110        base.set(k, -1);
111      }
112    }
113
[361]114    iterator begin(Val n) const {
[362]115      return data.begin() + (n ? bounds[n-1] : 0);
[347]116    }
117
[361]118    iterator end(Val n) const {
[362]119      return data.begin() + bounds[n];
[347]120    }
121
[361]122    size_t size(Val n) const {
[362]123      return bounds[n] - (n ? bounds[n-1] : 0);
[347]124    }
125   
126    size_t size() const {
127      // assert(bounds[N-1] == data.size());
128      return bounds[N-1];
129    }
130
[365]131
132    /// For use as an iterator...
[987]133    Key& first(Key &k, Val n) {
[365]134      size_t i = (n ? bounds[n-1] : 0);
135      if( i < bounds[n] ) {
136        k = data[i];
137      }
138      else {
139        k = INVALID;
140      }
141      return k;
142    }
143
144    /// For use as an iterator...
[987]145    Key& next(Key &k) {
[365]146      size_t i = base[k];
147      uint8_t n = find(i);
148      ++i;
149      if( i < bounds[n] ) {
150        k = data[i];
151      }
152      else {
153        k = INVALID;
154      }
155      return k;
156    }
157
[347]158  };
159
[361]160
161
162
163  template<typename KeyIntMap>
164  class IterableBoolMap : public IterableMap<KeyIntMap, 2, bool> {
165    typedef IterableMap<KeyIntMap, 2, bool> Parent;
166
167  public:
168    IterableBoolMap(KeyIntMap &_base, bool d = false) : Parent(_base, d) {}
169  };
170
[347]171}
172#endif
Note: See TracBrowser for help on using the repository browser.