diff -r d8475431bbbb -r 8e85e6bbefdf src/lemon/bits/array_map.h --- a/src/lemon/bits/array_map.h Sat May 21 21:04:57 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,369 +0,0 @@ -/* -*- C++ -*- - * src/lemon/bits/array_map.h - Part of LEMON, a generic C++ optimization library - * - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport - * (Egervary Research Group on Combinatorial Optimization, EGRES). - * - * Permission to use, modify and distribute this software is granted - * provided that this copyright notice appears in all copies. For - * precise terms see the accompanying LICENSE file. - * - * This software is provided "AS IS" with no warranty of any kind, - * express or implied, and with no claim as to its suitability for any - * purpose. - * - */ - -#ifndef LEMON_ARRAY_MAP_H -#define LEMON_ARRAY_MAP_H - -#include -#include - -///\ingroup graphmaps -///\file -///\brief Graph maps that construates and destruates -///their elements dynamically. - -namespace lemon { - - - /// \addtogroup graphmaps - /// @{ - - /// The ArrayMap template class is graph map structure what - /// automatically updates the map when a key is added to or erased from - /// the map. This map factory uses the allocators to implement - /// the container functionality. - /// - /// The template parameter is the AlterationNotifier that the maps - /// will belong to and the Value. - - - template - class ArrayMap : public AlterationNotifier<_Item>::ObserverBase { - - typedef _Item Item; - public: - - /// The graph type of the maps. - typedef _Graph Graph; - /// The key type of the maps. - typedef _Item Key; - - typedef AlterationNotifier<_Item> Registry; - - /// The MapBase of the Map which imlements the core regisitry function. - typedef typename Registry::ObserverBase Parent; - - /// The value type of the map. - typedef _Value Value; - - - private: - typedef std::allocator Allocator; - - - public: - - /// Graph and Registry initialized map constructor. - - ArrayMap(const Graph& _g) : graph(&_g) { - Item it; - attach(_g.getNotifier(Item())); - allocate_memory(); - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; - allocator.construct(&(values[id]), Value()); - } - } - - /// Constructor to use default value to initialize the map. - - /// It constrates a map and initialize all of the the map. - - ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) { - Item it; - attach(_g.getNotifier(_Item())); - allocate_memory(); - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; - allocator.construct(&(values[id]), _v); - } - } - - /// Constructor to copy a map of the same map type. - - ArrayMap(const ArrayMap& copy) : Parent() { - if (copy.attached()) { - attach(*copy.getRegistry()); - } - capacity = copy.capacity; - if (capacity == 0) return; - values = allocator.allocate(capacity); - Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; - allocator.construct(&(values[id]), copy.values[id]); - } - } - - using Parent::attach; - using Parent::detach; - using Parent::attached; - - /// Assign operator to copy a map of the same map type. - - ArrayMap& operator=(const ArrayMap& copy) { - if (© == this) return *this; - - if (graph != copy.graph) { - if (attached()) { - clear(); - detach(); - } - if (copy.attached()) { - attach(*copy.getRegistry()); - } - capacity = copy.capacity; - if (capacity == 0) return *this; - values = allocator.allocate(capacity); - } - - Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; - allocator.construct(&(values[id]), copy.values[id]); - } - - return *this; - } - - /// The destructor of the map. - - virtual ~ArrayMap() { - if (attached()) { - clear(); - detach(); - } - } - - - ///The subscript operator. The map can be subscripted by the - ///actual keys of the graph. - - Value& operator[](const Key& key) { - int id = graph->id(key); - return values[id]; - } - - - ///The const subscript operator. The map can be subscripted by the - ///actual keys of the graph. - - const Value& operator[](const Key& key) const { - int id = graph->id(key); - return values[id]; - } - - /// Setter function of the map. Equivalent with map[key] = val. - /// This is a compatibility feature with the not dereferable maps. - - void set(const Key& key, const Value& val) { - (*this)[key] = val; - } - - /// Add a new key to the map. It called by the map registry. - - void add(const Key& key) { - int id = graph->id(key); - if (id >= capacity) { - int new_capacity = (capacity == 0 ? 1 : capacity); - while (new_capacity <= id) { - new_capacity <<= 1; - } - Value* new_values = allocator.allocate(new_capacity); - Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int jd = graph->id(it);; - if (id != jd) { - allocator.construct(&(new_values[jd]), values[jd]); - allocator.destroy(&(values[jd])); - } - } - if (capacity != 0) allocator.deallocate(values, capacity); - values = new_values; - capacity = new_capacity; - } - allocator.construct(&(values[id]), Value()); - } - - void add(const std::vector& keys) { - int max_id = -1; - for (int i = 0; i < (int)keys.size(); ++i) { - int id = graph->id(keys[i]); - if (id > max_id) { - max_id = id; - } - } - if (max_id >= capacity) { - int new_capacity = (capacity == 0 ? 1 : capacity); - while (new_capacity <= max_id) { - new_capacity <<= 1; - } - Value* new_values = allocator.allocate(new_capacity); - Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it); - bool found = false; - for (int i = 0; i < (int)keys.size(); ++i) { - int jd = graph->id(keys[i]); - if (id == jd) { - found = true; - break; - } - } - if (found) continue; - allocator.construct(&(new_values[id]), values[id]); - allocator.destroy(&(values[id])); - } - if (capacity != 0) allocator.deallocate(values, capacity); - values = new_values; - capacity = new_capacity; - } - for (int i = 0; i < (int)keys.size(); ++i) { - int id = graph->id(keys[i]); - allocator.construct(&(values[id]), Value()); - } - } - - /// Erase a key from the map. It called by the map registry. - - void erase(const Key& key) { - int id = graph->id(key); - allocator.destroy(&(values[id])); - } - - void erase(const std::vector& keys) { - for (int i = 0; i < (int)keys.size(); ++i) { - int id = graph->id(keys[i]); - allocator.destroy(&(values[id])); - } - } - - void build() { - allocate_memory(); - Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it);; - allocator.construct(&(values[id]), Value()); - } - } - - void clear() { - if (capacity != 0) { - Item it; - for (graph->first(it); it != INVALID; graph->next(it)) { - int id = graph->id(it); - allocator.destroy(&(values[id])); - } - allocator.deallocate(values, capacity); - capacity = 0; - } - } - - const Graph* getGraph() { - return graph; - } - - private: - - void allocate_memory() { - int max_id = graph->maxId(_Item()); - if (max_id == -1) { - capacity = 0; - values = 0; - return; - } - capacity = 1; - while (capacity <= max_id) { - capacity <<= 1; - } - values = allocator.allocate(capacity); - } - - const Graph* graph; - int capacity; - Value* values; - Allocator allocator; - - }; - - template - class ArrayMappableGraphExtender : public _Base { - public: - - typedef ArrayMappableGraphExtender<_Base> Graph; - typedef _Base Parent; - - typedef typename Parent::Node Node; - typedef typename Parent::NodeIt NodeIt; - typedef typename Parent::NodeNotifier NodeObserverRegistry; - - typedef typename Parent::Edge Edge; - typedef typename Parent::EdgeIt EdgeIt; - typedef typename Parent::EdgeNotifier EdgeObserverRegistry; - - - - template - class NodeMap - : public IterableMapExtender > { - public: - typedef ArrayMappableGraphExtender<_Base> Graph; - - typedef typename Graph::Node Node; - typedef typename Graph::NodeIt NodeIt; - - typedef IterableMapExtender > Parent; - - //typedef typename Parent::Graph Graph; - typedef typename Parent::Value Value; - - NodeMap(const Graph& g) - : Parent(g) {} - NodeMap(const Graph& g, const Value& v) - : Parent(g, v) {} - - }; - - template - class EdgeMap - : public IterableMapExtender > { - public: - typedef ArrayMappableGraphExtender<_Base> Graph; - - typedef typename Graph::Edge Edge; - typedef typename Graph::EdgeIt EdgeIt; - - typedef IterableMapExtender > Parent; - - //typedef typename Parent::Graph Graph; - typedef typename Parent::Value Value; - - EdgeMap(const Graph& g) - : Parent(g) {} - EdgeMap(const Graph& g, const Value& v) - : Parent(g, v) {} - - }; - - }; - -/// @} - -} - -#endif //LEMON_ARRAY_MAP_H