src/work/klao/iter_map.h
author klao
Wed, 21 Apr 2004 16:09:42 +0000
changeset 362 6c2e8a1f380a
parent 361 ab0899df30d2
child 365 9ca84022df34
permissions -rw-r--r--
IterableMap: no range checking, no warning :)
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@361
    19
  template<typename KeyIntMap, uint8_t N, typename Val = uint8_t>
klao@347
    20
  class IterableMap {
klao@347
    21
  public:
klao@347
    22
klao@347
    23
    typedef typename KeyIntMap::KeyType KeyType;
klao@361
    24
    typedef Val 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@361
    32
    Val def_val;
klao@347
    33
klao@361
    34
    Val find(size_t a) const {
klao@361
    35
      for(uint8_t n=0; n<N; ++n) {
klao@361
    36
	if(bounds[n] > a)
klao@361
    37
	  return n;
klao@361
    38
      }
klao@361
    39
      return def_val;
klao@347
    40
    }
klao@347
    41
klao@347
    42
    void half_swap(size_t &a, size_t b) {
klao@347
    43
      if(a != b) {
klao@347
    44
	base.set(data[b],a);
klao@347
    45
	data[a] = data[b];
klao@347
    46
	a = b;
klao@347
    47
      }
klao@347
    48
    }
klao@347
    49
klao@347
    50
    size_t move(size_t a, uint8_t m, uint8_t n) {
klao@347
    51
      if(m != n) {
klao@347
    52
	size_t orig_a = a;
klao@347
    53
	KeyType orig_key = data[a];
klao@347
    54
	while(m > n) {
klao@347
    55
	  --m;
klao@347
    56
	  half_swap(a, bounds[m]++);
klao@347
    57
	}
klao@362
    58
	// FIXME: range check ide?
klao@347
    59
	while(m < n) {
klao@347
    60
	  half_swap(a, --bounds[m]);
klao@347
    61
	  ++m;
klao@347
    62
	}
klao@347
    63
	if(a != orig_a) {
klao@347
    64
	  base.set(orig_key, a);
klao@347
    65
	  data[a]=orig_key;
klao@347
    66
	}
klao@347
    67
      }
klao@347
    68
      return a;
klao@347
    69
    }
klao@347
    70
klao@347
    71
  public:
klao@347
    72
    
klao@361
    73
    IterableMap(KeyIntMap &_base, Val d = N+1) : base(_base), def_val(d) {
klao@347
    74
      memset(bounds, 0, sizeof(bounds));
klao@347
    75
      //    for(int i=0; i<N; ++i) { bounds[i]=0; }
klao@347
    76
    }
klao@347
    77
klao@361
    78
    Val operator[](const KeyType& k) const {
klao@347
    79
      return find(base[k]);
klao@347
    80
    }
klao@347
    81
klao@361
    82
    void set(const KeyType& k, Val n) {
klao@362
    83
      // FIXME: range check?
klao@347
    84
      size_t a = base[k];
klao@362
    85
      if(a < bounds[N-1]) {
klao@347
    86
	base.set(k, move(a, find(a), n));
klao@347
    87
      }
klao@362
    88
      else {
klao@362
    89
	insert(k, n);
klao@362
    90
      }
klao@347
    91
    }
klao@347
    92
klao@361
    93
    void insert(const KeyType& k, Val n) {
klao@362
    94
      data.push_back(k);
klao@362
    95
      base.set(k, move(bounds[N-1]++, N-1, n));
klao@347
    96
    }
klao@347
    97
klao@361
    98
    iterator begin(Val n) const {
klao@362
    99
      return data.begin() + (n ? bounds[n-1] : 0);
klao@347
   100
    }
klao@347
   101
klao@361
   102
    iterator end(Val n) const {
klao@362
   103
      return data.begin() + bounds[n];
klao@347
   104
    }
klao@347
   105
klao@361
   106
    size_t size(Val n) const {
klao@362
   107
      return bounds[n] - (n ? bounds[n-1] : 0);
klao@347
   108
    }
klao@347
   109
    
klao@347
   110
    size_t size() const {
klao@347
   111
      // assert(bounds[N-1] == data.size());
klao@347
   112
      return bounds[N-1];
klao@347
   113
    }
klao@347
   114
klao@347
   115
  };
klao@347
   116
klao@361
   117
klao@361
   118
klao@361
   119
klao@361
   120
  template<typename KeyIntMap>
klao@361
   121
  class IterableBoolMap : public IterableMap<KeyIntMap, 2, bool> {
klao@361
   122
    typedef IterableMap<KeyIntMap, 2, bool> Parent;
klao@361
   123
klao@361
   124
  public:
klao@361
   125
    IterableBoolMap(KeyIntMap &_base, bool d = false) : Parent(_base, d) {}
klao@361
   126
  };
klao@361
   127
klao@347
   128
}
klao@347
   129
#endif