src/work/deba/array_map_factory.h
author alpar
Tue, 06 Jul 2004 11:28:20 +0000
changeset 696 48aa9ace1d7d
parent 627 6cc21a9c9fda
child 702 4207f82a1778
permissions -rw-r--r--
Example in the doc is corrected.
deba@627
     1
#ifndef ARRAY_MAP_H
deba@627
     2
#define ARRAY_MAP_H
deba@627
     3
deba@627
     4
#include <memory>
deba@627
     5
deba@627
     6
deba@627
     7
#include <iostream>
deba@627
     8
using namespace std;
deba@627
     9
deba@627
    10
namespace hugo {
deba@627
    11
	
deba@674
    12
  template <typename MapRegistry> class ArrayMapFactory {
deba@674
    13
		
deba@674
    14
  public:
deba@674
    15
		
deba@674
    16
    typedef typename MapRegistry::Graph Graph;
deba@674
    17
    typedef typename MapRegistry::Key Key;
deba@674
    18
    typedef typename MapRegistry::KeyIt KeyIt;
deba@674
    19
deba@674
    20
    typedef typename MapRegistry::MapBase MapBase;
deba@674
    21
		
deba@674
    22
    template <typename V, typename A = std::allocator<V> > 
deba@674
    23
      class Map : public MapBase {
deba@674
    24
    
deba@627
    25
	public:
deba@674
    26
deba@674
    27
	typedef V Value;
deba@674
    28
	typedef A Allocator;
deba@627
    29
deba@627
    30
	
deba@674
    31
	Map() : values(0), capacity(0) {}
deba@627
    32
			
deba@674
    33
	Map(Graph& g, MapRegistry& r) : MapBase(g, r) {
deba@674
    34
	  int max_id = -1;
deba@674
    35
	  for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@674
    36
	    int id = graph->id(it);
deba@674
    37
	    if (id > max_id) {
deba@674
    38
	      max_id = id;
deba@674
    39
	    }			
deba@674
    40
	  }
deba@674
    41
	  if (max_id == -1) {
deba@674
    42
	    capacity = 0;
deba@674
    43
	    values = 0;
deba@674
    44
	    return;
deba@674
    45
	  }
deba@674
    46
	  capacity = 1;
deba@674
    47
	  while (capacity <= max_id) {
deba@674
    48
	    capacity <<= 1;
deba@674
    49
	  }
deba@674
    50
	  values = allocator.allocate(capacity);
deba@674
    51
	  for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@674
    52
	    int id = graph->id(it);
deba@674
    53
	    allocator.construct(&(values[id]), Value());
deba@674
    54
	  }								
deba@674
    55
	}
deba@674
    56
deba@674
    57
	Map(const Map& copy) : MapBase(*copy.graph, *copy.registry) {
deba@674
    58
	  capacity = copy.capacity;
deba@674
    59
	  values = allocator.allocate(capacity);
deba@674
    60
	  for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@674
    61
	    int id = graph->id(it);
deba@674
    62
	    allocator.construct(&(values[id]), copy.values[id]);
deba@674
    63
	  }
deba@674
    64
	}
deba@627
    65
				
deba@674
    66
	virtual ~Map() {
deba@674
    67
	  destroy();
deba@674
    68
	  allocator.deallocate(values, capacity);
deba@674
    69
	}
deba@627
    70
	
deba@627
    71
	
deba@674
    72
	Value& operator[](const Key& key) {
deba@674
    73
	  int id = graph->id(key);
deba@674
    74
	  return values[id];
deba@674
    75
	} 
deba@627
    76
		
deba@674
    77
	const Value& operator[](const Key& key) const {
deba@674
    78
	  int id = graph->id(key);
deba@674
    79
	  return values[id];
deba@674
    80
	}
deba@627
    81
	
deba@674
    82
	const Value& get(const Key& key) const {
deba@674
    83
	  int id = graph->id(key);
deba@674
    84
	  return values[id];
deba@674
    85
	} 
deba@627
    86
		
deba@674
    87
	void set(const Key& key, const Value& val) {
deba@674
    88
	  int id = graph->id(key);
deba@674
    89
	  values[id] = val;
deba@674
    90
	}
deba@627
    91
		
deba@674
    92
	void add(const Key& key) {
deba@674
    93
	  int id = graph->id(key);
deba@674
    94
	  if (id >= capacity) {
deba@674
    95
	    int new_capacity = (capacity == 0 ? 1 : capacity);
deba@674
    96
	    while (new_capacity <= id) {
deba@674
    97
	      new_capacity <<= 1;
deba@674
    98
	    }
deba@674
    99
	    Value* new_values = allocator.allocate(new_capacity);;
deba@674
   100
	    for (KeyIt it(*graph); graph->valid(it); graph->next(it)) {
deba@674
   101
	      int jd = graph->id(it);
deba@674
   102
	      if (id != jd) {
deba@674
   103
		allocator.construct(&(new_values[jd]), values[jd]);
deba@674
   104
		allocator.destroy(&(values[jd]));
deba@674
   105
	      }
deba@674
   106
	    }
deba@674
   107
	    if (capacity != 0) allocator.deallocate(values, capacity);
deba@674
   108
	    values = new_values;
deba@674
   109
	    capacity = new_capacity;
deba@674
   110
	  }
deba@674
   111
	  allocator.construct(&(values[id]), Value());
deba@674
   112
	}
deba@627
   113
		
deba@674
   114
	void erase(const Key& key) {
deba@674
   115
	  int id = graph->id(key);
deba@674
   116
	  allocator.destroy(&(values[id]));
deba@674
   117
	}
deba@627
   118
	
deba@674
   119
	private:
deba@674
   120
	int capacity;
deba@674
   121
	Value* values;
deba@674
   122
	Allocator allocator;
deba@674
   123
      };		
deba@674
   124
  };
deba@627
   125
}
deba@627
   126
deba@627
   127
#endif