src/work/klao/iter_map.h
author klao
Sat, 17 Apr 2004 01:57:48 +0000
changeset 347 e4ab32225f1c
child 361 ab0899df30d2
permissions -rw-r--r--
A generic map with value type [0, N) where N is a small integer.
Can enumerate keys with a given value.
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
klao@347
    13
klao@347
    14
namespace hugo {
klao@347
    15
klao@347
    16
klao@347
    17
  /// \todo Decide whether we need all the range checkings!!!
klao@347
    18
klao@347
    19
  template<typename KeyIntMap, uint8_t N>
klao@347
    20
  class IterableMap {
klao@347
    21
  public:
klao@347
    22
klao@347
    23
    typedef typename KeyIntMap::KeyType KeyType;
klao@347
    24
    typedef uint8_t ValueType;
klao@347
    25
klao@347
    26
    typedef typename std::vector<KeyType>::const_iterator iterator;
klao@347
    27
klao@347
    28
  protected:
klao@347
    29
    KeyIntMap &base;
klao@347
    30
    std::vector<KeyType> data;
klao@347
    31
    size_t bounds[N];
klao@347
    32
klao@347
    33
    uint8_t find(size_t a) const {
klao@347
    34
      uint8_t n=0;
klao@347
    35
      for(; n<N && bounds[n]<=a; ++n);
klao@347
    36
      return n;
klao@347
    37
    }
klao@347
    38
klao@347
    39
    void half_swap(size_t &a, size_t b) {
klao@347
    40
      if(a != b) {
klao@347
    41
	base.set(data[b],a);
klao@347
    42
	data[a] = data[b];
klao@347
    43
	a = b;
klao@347
    44
      }
klao@347
    45
    }
klao@347
    46
klao@347
    47
    size_t move(size_t a, uint8_t m, uint8_t n) {
klao@347
    48
      if(m != n) {
klao@347
    49
	size_t orig_a = a;
klao@347
    50
	KeyType orig_key = data[a];
klao@347
    51
	while(m > n) {
klao@347
    52
	  --m;
klao@347
    53
	  half_swap(a, bounds[m]++);
klao@347
    54
	}
klao@347
    55
	while(m < n) {
klao@347
    56
	  half_swap(a, --bounds[m]);
klao@347
    57
	  ++m;
klao@347
    58
	}
klao@347
    59
	if(a != orig_a) {
klao@347
    60
	  base.set(orig_key, a);
klao@347
    61
	  data[a]=orig_key;
klao@347
    62
	}
klao@347
    63
      }
klao@347
    64
      return a;
klao@347
    65
    }
klao@347
    66
klao@347
    67
  public:
klao@347
    68
    
klao@347
    69
    IterableMap(KeyIntMap &_base) : base(_base) {
klao@347
    70
      memset(bounds, 0, sizeof(bounds));
klao@347
    71
      //    for(int i=0; i<N; ++i) { bounds[i]=0; }
klao@347
    72
    }
klao@347
    73
klao@347
    74
    uint8_t operator[](const KeyType& k) const {
klao@347
    75
      return find(base[k]);
klao@347
    76
    }
klao@347
    77
klao@347
    78
    void set(const KeyType& k, uint8_t n) {
klao@347
    79
      size_t a = base[k];
klao@347
    80
      if(a < bounds[N-1]) {
klao@347
    81
	base.set(k, move(a, find(a), n));
klao@347
    82
      }
klao@347
    83
    }
klao@347
    84
klao@347
    85
    void insert(const KeyType& k, uint8_t n) {
klao@347
    86
      if(n<N) {
klao@347
    87
	data.push_back(k);
klao@347
    88
	base.set(k, move(bounds[N-1]++, N-1, n));
klao@347
    89
      }
klao@347
    90
    }
klao@347
    91
klao@347
    92
    iterator begin(uint8_t n) const {
klao@347
    93
      if(n < N)
klao@347
    94
	return data.begin() + (n ? bounds[n-1] : 0);
klao@347
    95
      else
klao@347
    96
	return data.end();
klao@347
    97
    }
klao@347
    98
klao@347
    99
    iterator end(uint8_t n) const {
klao@347
   100
      if(n < N)
klao@347
   101
	return data.begin() + bounds[n];
klao@347
   102
      else
klao@347
   103
	return data.end();
klao@347
   104
    }
klao@347
   105
klao@347
   106
    size_t size(uint8_t n) const {
klao@347
   107
      if(n < N)
klao@347
   108
	return bounds[n] - (n ? bounds[n-1] : 0);
klao@347
   109
      else
klao@347
   110
	return 0;
klao@347
   111
    }
klao@347
   112
    
klao@347
   113
    size_t size() const {
klao@347
   114
      // assert(bounds[N-1] == data.size());
klao@347
   115
      return bounds[N-1];
klao@347
   116
    }
klao@347
   117
klao@347
   118
  };
klao@347
   119
klao@347
   120
}
klao@347
   121
#endif