array_map.h

Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * src/lemon/array_map.h - Part of LEMON, a generic C++ optimization library 00003 * 00004 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 00005 * (Egervary Combinatorial Optimization Research Group, EGRES). 00006 * 00007 * Permission to use, modify and distribute this software is granted 00008 * provided that this copyright notice appears in all copies. For 00009 * precise terms see the accompanying LICENSE file. 00010 * 00011 * This software is provided "AS IS" with no warranty of any kind, 00012 * express or implied, and with no claim as to its suitability for any 00013 * purpose. 00014 * 00015 */ 00016 00017 #ifndef LEMON_ARRAY_MAP_H 00018 #define LEMON_ARRAY_MAP_H 00019 00020 #include <memory> 00021 00022 #include <lemon/map_iterator.h> 00023 #include <lemon/map_bits.h> 00024 00029 00030 namespace lemon { 00031 00032 00035 00045 template <typename MapRegistry, typename Value> 00046 class ArrayMap : public MapRegistry::MapBase { 00047 00048 template <typename MR, typename V> friend class ArrayMap; 00049 00050 public: 00051 00053 typedef typename MapRegistry::Graph Graph; 00055 typedef typename MapRegistry::KeyType KeyType; 00057 typedef typename MapRegistry::KeyIt KeyIt; 00058 00060 typedef typename MapRegistry::MapBase MapBase; 00061 00062 00063 public: 00064 00066 typedef Value ValueType; 00068 typedef Value& ReferenceType; 00070 typedef Value* PointerType; 00071 00073 typedef const Value ConstValueType; 00075 typedef const Value& ConstReferenceType; 00077 typedef const Value* ConstPointerType; 00078 00079 00080 typedef std::allocator<Value> Allocator; 00081 00082 00085 ArrayMap(const Graph& g, MapRegistry& r) : MapBase(g, r) { 00086 allocate_memory(); 00087 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00088 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00089 allocator.construct(&(values[id]), Value()); 00090 } 00091 } 00092 00095 ArrayMap(const Graph& g, MapRegistry& r, const Value& v) 00096 : MapBase(g, r) { 00097 allocate_memory(); 00098 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00099 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00100 allocator.construct(&(values[id]), v); 00101 } 00102 } 00103 00106 ArrayMap(const ArrayMap& copy) : MapBase(copy) { 00107 capacity = copy.capacity; 00108 if (capacity == 0) return; 00109 values = allocator.allocate(capacity); 00110 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00111 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00112 allocator.construct(&(values[id]), copy.values[id]); 00113 } 00114 } 00115 00118 template <typename TT> 00119 ArrayMap(const ArrayMap<MapRegistry, TT>& copy) 00120 : MapBase(copy) { 00121 capacity = copy.capacity; 00122 if (capacity == 0) return; 00123 values = allocator.allocate(capacity); 00124 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00125 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00126 allocator.construct(&(values[id]), copy.values[id]); 00127 } 00128 } 00129 00132 ArrayMap& operator=(const ArrayMap& copy) { 00133 if (&copy == this) return *this; 00134 00135 if (MapBase::getGraph() != copy.getGraph()) { 00136 if (capacity != 0) { 00137 MapBase::destroy(); 00138 allocator.deallocate(values, capacity); 00139 } 00140 00141 MapBase::operator=(copy); 00142 capacity = copy.capacity; 00143 if (capacity == 0) return *this; 00144 values = allocator.allocate(capacity); 00145 } 00146 00147 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00148 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00149 allocator.construct(&(values[id]), copy.values[id]); 00150 } 00151 00152 return *this; 00153 } 00154 00157 template <typename TT> 00158 ArrayMap& operator=(const ArrayMap<MapRegistry, TT>& copy) { 00159 00160 if (MapBase::getGraph() != copy.getGraph()) { 00161 if (capacity != 0) { 00162 MapBase::destroy(); 00163 allocator.deallocate(values, capacity); 00164 } 00165 00166 MapBase::operator=(copy); 00167 00168 capacity = copy.capacity; 00169 if (capacity == 0) return *this; 00170 values = allocator.allocate(capacity); 00171 } 00172 00173 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00174 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00175 allocator.construct(&(values[id]), copy.values[id]); 00176 } 00177 00178 return *this; 00179 } 00180 00183 virtual ~ArrayMap() { 00184 if (capacity != 0) { 00185 MapBase::destroy(); 00186 allocator.deallocate(values, capacity); 00187 } 00188 } 00189 00190 00195 ReferenceType operator[](const KeyType& key) { 00196 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key); 00197 return values[id]; 00198 } 00199 00204 ConstReferenceType operator[](const KeyType& key) const { 00205 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key); 00206 return values[id]; 00207 } 00208 00212 void set(const KeyType& key, const ValueType& val) { 00213 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key); 00214 values[id] = val; 00215 } 00216 00219 void add(const KeyType& key) { 00220 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key); 00221 if (id >= capacity) { 00222 int new_capacity = (capacity == 0 ? 1 : capacity); 00223 while (new_capacity <= id) { 00224 new_capacity <<= 1; 00225 } 00226 Value* new_values = allocator.allocate(new_capacity);; 00227 for (KeyIt it(*MapBase::getGraph()); it != INVALID; ++it) { 00228 int jd = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), it); 00229 if (id != jd) { 00230 allocator.construct(&(new_values[jd]), values[jd]); 00231 allocator.destroy(&(values[jd])); 00232 } 00233 } 00234 if (capacity != 0) allocator.deallocate(values, capacity); 00235 values = new_values; 00236 capacity = new_capacity; 00237 } 00238 allocator.construct(&(values[id]), Value()); 00239 } 00240 00243 void erase(const KeyType& key) { 00244 int id = KeyInfo<Graph, KeyIt>::id(*MapBase::getGraph(), key); 00245 allocator.destroy(&(values[id])); 00246 } 00247 00250 void clear() { 00251 if (capacity != 0) { 00252 MapBase::destroy(); 00253 allocator.deallocate(values, capacity); 00254 capacity = 0; 00255 } 00256 } 00257 00259 typedef MapIterator<ArrayMap> Iterator; 00261 typedef MapConstIterator<ArrayMap> ConstIterator; 00262 00265 Iterator begin() { 00266 return Iterator(*this, KeyIt(*MapBase::getGraph())); 00267 } 00268 00271 Iterator end() { 00272 return Iterator(*this, INVALID); 00273 } 00274 00277 ConstIterator begin() const { 00278 return ConstIterator(*this, KeyIt(*MapBase::getGraph())); 00279 } 00280 00283 ConstIterator end() const { 00284 return ConstIterator(*this, INVALID); 00285 } 00286 00288 typedef MapConstKeySet<ArrayMap> ConstKeySet; 00289 00291 ConstKeySet keySet() const { 00292 return ConstKeySet(*this); 00293 } 00294 00296 typedef MapConstValueSet<ArrayMap> ConstValueSet; 00297 00299 ConstValueSet valueSet() const { 00300 return ConstValueSet(*this); 00301 } 00302 00304 typedef MapValueSet<ArrayMap> ValueSet; 00305 00307 ValueSet valueSet() { 00308 return ValueSet(*this); 00309 } 00310 00311 private: 00312 00313 void allocate_memory() { 00314 int max_id = KeyInfo<Graph, KeyIt>::maxId(*MapBase::getGraph()); 00315 if (max_id == -1) { 00316 capacity = 0; 00317 values = 0; 00318 return; 00319 } 00320 capacity = 1; 00321 while (capacity <= max_id) { 00322 capacity <<= 1; 00323 } 00324 values = allocator.allocate(capacity); 00325 } 00326 00327 int capacity; 00328 Value* values; 00329 Allocator allocator; 00330 00331 public: 00332 // STL compatibility typedefs. 00333 typedef Iterator iterator; 00334 typedef ConstIterator const_iterator; 00335 typedef typename Iterator::PairValueType value_type; 00336 typedef typename Iterator::KeyType key_type; 00337 typedef typename Iterator::ValueType data_type; 00338 typedef typename Iterator::PairReferenceType reference; 00339 typedef typename Iterator::PairPointerType pointer; 00340 typedef typename ConstIterator::PairReferenceType const_reference; 00341 typedef typename ConstIterator::PairPointerType const_pointer; 00342 typedef int difference_type; 00343 }; 00344 00346 00347 } 00348 00349 #endif //LEMON_ARRAY_MAP_H

Generated on Thu Sep 30 12:18:33 2004 for LEMON by doxygen 1.3.8