src/work/klao/iter_map.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000 (2004-09-08)
changeset 822 88226d9fe821
parent 367 825647d4eca7
child 921 818510fa3d99
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

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