src/hugo/array_map.h
changeset 872 c010b38ea35b
parent 830 89dfa3bece81
child 891 74589d20dbc3
equal deleted inserted replaced
1:9eab62d796b2 2:ebec0894ab1d
     3 #define ARRAY_MAP_H
     3 #define ARRAY_MAP_H
     4 
     4 
     5 #include <memory>
     5 #include <memory>
     6 
     6 
     7 #include <hugo/map_iterator.h>
     7 #include <hugo/map_iterator.h>
       
     8 #include <hugo/map_bits.h>
     8 
     9 
     9 ///\ingroup graphmaps
    10 ///\ingroup graphmaps
    10 ///\file
    11 ///\file
    11 ///\brief Graph maps that construates and destruates
    12 ///\brief Graph maps that construates and destruates
    12 ///their elements dynamically.
    13 ///their elements dynamically.
    69     /** Graph and Registry initialized map constructor.
    70     /** Graph and Registry initialized map constructor.
    70      */
    71      */
    71     ArrayMap(const Graph& g, MapRegistry& r) : MapBase(g, r) {
    72     ArrayMap(const Graph& g, MapRegistry& r) : MapBase(g, r) {
    72       allocate_memory();
    73       allocate_memory();
    73       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
    74       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
    74 	int id = MapBase::getGraph()->id(it);
    75 	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
    75 	allocator.construct(&(values[id]), Value());
    76 	allocator.construct(&(values[id]), Value());
    76       }								
    77       }								
    77     }
    78     }
    78 
    79 
    79     /** Constructor to use default value to initialize the map. 
    80     /** Constructor to use default value to initialize the map. 
    80      */
    81      */
    81     ArrayMap(const Graph& g, MapRegistry& r, const Value& v) 
    82     ArrayMap(const Graph& g, MapRegistry& r, const Value& v) 
    82       : MapBase(g, r) {
    83       : MapBase(g, r) {
    83       allocate_memory();
    84       allocate_memory();
    84       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
    85       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
    85 	int id = MapBase::getGraph()->id(it);
    86 	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
    86 	allocator.construct(&(values[id]), v);
    87 	allocator.construct(&(values[id]), v);
    87       }								
    88       }								
    88     }
    89     }
    89 
    90 
    90     /** Constructor to copy a map of the same map type.
    91     /** Constructor to copy a map of the same map type.
    92     ArrayMap(const ArrayMap& copy) : MapBase(*copy.graph, *copy.registry) {
    93     ArrayMap(const ArrayMap& copy) : MapBase(*copy.graph, *copy.registry) {
    93       capacity = copy.capacity;
    94       capacity = copy.capacity;
    94       if (capacity == 0) return;
    95       if (capacity == 0) return;
    95       values = allocator.allocate(capacity);
    96       values = allocator.allocate(capacity);
    96       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
    97       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
    97 	int id = MapBase::getGraph()->id(it);
    98 	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
    98 	allocator.construct(&(values[id]), copy.values[id]);
    99 	allocator.construct(&(values[id]), copy.values[id]);
    99       }
   100       }
   100     }
   101     }
   101 
   102 
   102     /** Constructor to copy a map of an other map type.
   103     /** Constructor to copy a map of an other map type.
   121       }
   122       }
   122       capacity = copy.capacity;
   123       capacity = copy.capacity;
   123       if (capacity == 0) return *this;
   124       if (capacity == 0) return *this;
   124       values = allocator.allocate(capacity);
   125       values = allocator.allocate(capacity);
   125       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
   126       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
   126 	int id = MapBase::getGraph()->id(it);
   127 	int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
   127 	allocator.construct(&(values[id]), copy.values[id]);
   128 	allocator.construct(&(values[id]), copy.values[id]);
   128       }
   129       }
   129       return *this;
   130       return *this;
   130     }
   131     }
   131 
   132 
   132     /** Assign operator to copy a map an other map type.
   133     /** Assign operator to copy a map an other map type.
   133      */
   134      */
   134     template <typename CMap> ArrayMap& operator=(const CMap& copy) {
   135     template <typename CMap> ArrayMap& operator=(const CMap& copy) {
   135       if (MapBase::getGraph()) {
   136       if (capacity != 0) {
   136 	MapBase::destroy();
   137 	MapBase::destroy();
   137       } 
   138 	allocator.deallocate(values, capacity);
       
   139       }
   138       MapBase::operator=(copy);
   140       MapBase::operator=(copy);
   139       if (MapBase::getGraph()) {
   141       if (MapBase::getGraph()) {
   140 	allocate_memory();
   142 	allocate_memory();
   141 	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
   143 	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
   142 	  set(it, copy[it]);
   144 	  set(it, copy[it]);
   158     /**
   160     /**
   159      * The subscript operator. The map can be subscripted by the
   161      * The subscript operator. The map can be subscripted by the
   160      * actual keys of the graph. 
   162      * actual keys of the graph. 
   161      */
   163      */
   162     ReferenceType operator[](const KeyType& key) {
   164     ReferenceType operator[](const KeyType& key) {
   163       int id = MapBase::getGraph()->id(key);
   165       int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
   164       return values[id];
   166       return values[id];
   165     } 
   167     } 
   166 		
   168 		
   167     /**
   169     /**
   168      * The const subscript operator. The map can be subscripted by the
   170      * The const subscript operator. The map can be subscripted by the
   169      * actual keys of the graph. 
   171      * actual keys of the graph. 
   170      */
   172      */
   171     ConstReferenceType operator[](const KeyType& key) const {
   173     ConstReferenceType operator[](const KeyType& key) const {
   172       int id = MapBase::getGraph()->id(key);
   174       int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
   173       return values[id];
   175       return values[id];
   174     }
   176     }
   175 	
   177 	
   176     /** Setter function of the map. Equivalent with map[key] = val.
   178     /** Setter function of the map. Equivalent with map[key] = val.
   177      *  This is a compatibility feature with the not dereferable maps.
   179      *  This is a compatibility feature with the not dereferable maps.
   178      */
   180      */
   179     void set(const KeyType& key, const ValueType& val) {
   181     void set(const KeyType& key, const ValueType& val) {
   180       int id = MapBase::getGraph()->id(key);
   182       int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
   181       values[id] = val;
   183       values[id] = val;
   182     }
   184     }
   183 		
   185 		
   184     /** Add a new key to the map. It called by the map registry.
   186     /** Add a new key to the map. It called by the map registry.
   185      */
   187      */
   186     void add(const KeyType& key) {
   188     void add(const KeyType& key) {
   187       int id = MapBase::getGraph()->id(key);
   189       int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
   188       if (id >= capacity) {
   190       if (id >= capacity) {
   189 	int new_capacity = (capacity == 0 ? 1 : capacity);
   191 	int new_capacity = (capacity == 0 ? 1 : capacity);
   190 	while (new_capacity <= id) {
   192 	while (new_capacity <= id) {
   191 	  new_capacity <<= 1;
   193 	  new_capacity <<= 1;
   192 	}
   194 	}
   193 	Value* new_values = allocator.allocate(new_capacity);;
   195 	Value* new_values = allocator.allocate(new_capacity);;
   194 	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
   196 	for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
   195 	  int jd = MapBase::getGraph()->id(it);
   197 	  int jd = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it);
   196 	  if (id != jd) {
   198 	  if (id != jd) {
   197 	    allocator.construct(&(new_values[jd]), values[jd]);
   199 	    allocator.construct(&(new_values[jd]), values[jd]);
   198 	    allocator.destroy(&(values[jd]));
   200 	    allocator.destroy(&(values[jd]));
   199 	  }
   201 	  }
   200 	}
   202 	}
   206     }
   208     }
   207 		
   209 		
   208     /** Erase a key from the map. It called by the map registry.
   210     /** Erase a key from the map. It called by the map registry.
   209      */
   211      */
   210     void erase(const KeyType& key) {
   212     void erase(const KeyType& key) {
   211       int id = MapBase::getGraph()->id(key);
   213       int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key);
   212       allocator.destroy(&(values[id]));
   214       allocator.destroy(&(values[id]));
   213     }
   215     }
   214 
   216 
   215     /** Clear the data structure.
   217     /** Clear the data structure.
   216      */
   218      */
   276     }
   278     }
   277 
   279 
   278   private:
   280   private:
   279       
   281       
   280     void allocate_memory() {
   282     void allocate_memory() {
   281       int max_id = -1;
   283       int max_id = KeyInfo<Graph, KeyIt>::maxId(*MapBase::getGraph());
   282       for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) {
       
   283 	int id = MapBase::getGraph()->id(it);
       
   284 	if (id > max_id) {
       
   285 	  max_id = id;
       
   286 	}			
       
   287       }
       
   288       if (max_id == -1) {
   284       if (max_id == -1) {
   289 	capacity = 0;
   285 	capacity = 0;
   290 	values = 0;
   286 	values = 0;
   291 	return;
   287 	return;
   292       }
   288       }
   298     }      
   294     }      
   299 
   295 
   300     int capacity;
   296     int capacity;
   301     Value* values;
   297     Value* values;
   302     Allocator allocator;
   298     Allocator allocator;
       
   299 
       
   300   public:
       
   301     // STL  compatibility typedefs.
       
   302     typedef Iterator iterator;
       
   303     typedef ConstIterator const_iterator;
       
   304     typedef typename Iterator::PairValueType value_type;
       
   305     typedef typename Iterator::KeyType key_type;
       
   306     typedef typename Iterator::ValueType data_type;
       
   307     typedef typename Iterator::PairReferenceType reference;
       
   308     typedef typename Iterator::PairPointerType pointer;
       
   309     typedef typename ConstIterator::PairReferenceType const_reference;
       
   310     typedef typename ConstIterator::PairPointerType const_pointer;
       
   311     typedef int difference_type;		
   303   };		
   312   };		
   304 
   313 
   305 /// @}
   314 /// @}
   306 
   315 
   307 }
   316 }