alpar@906: /* -*- C++ -*- ladanyi@1435: * lemon/vector_map.h - Part of LEMON, a generic C++ optimization library alpar@906: * alpar@1164: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1359: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@906: * alpar@906: * Permission to use, modify and distribute this software is granted alpar@906: * provided that this copyright notice appears in all copies. For alpar@906: * precise terms see the accompanying LICENSE file. alpar@906: * alpar@906: * This software is provided "AS IS" with no warranty of any kind, alpar@906: * express or implied, and with no claim as to its suitability for any alpar@906: * purpose. alpar@906: * alpar@906: */ alpar@906: alpar@921: #ifndef LEMON_VECTOR_MAP_H alpar@921: #define LEMON_VECTOR_MAP_H deba@822: deba@822: #include klao@946: #include deba@822: deba@1267: #include deba@1307: #include deba@1307: #include deba@822: deba@822: ///\ingroup graphmaps deba@822: ///\file deba@822: ///\brief Vector based graph maps. deba@822: alpar@921: namespace lemon { deba@822: deba@822: /// \addtogroup graphmaps deba@822: /// @{ deba@822: klao@946: /// The VectorMap template class is graph map structure what klao@946: /// automatically updates the map when a key is added to or erased from klao@946: /// the map. This map factory uses the allocators to implement klao@946: /// the container functionality. This map factory klao@946: /// uses the std::vector to implement the container function. klao@946: /// deba@1039: /// \param Registry The AlterationNotifier that will notify this map. klao@946: /// \param IdMap The IdMap type of the graph items. klao@946: /// \param Value The value type of the map. klao@946: /// klao@946: /// \author Balazs Dezso klao@946: klao@946: deba@1267: template < deba@1267: typename _Graph, deba@1267: typename _Item, deba@1267: typename _Value deba@1267: > deba@1039: class VectorMap : public AlterationNotifier<_Item>::ObserverBase { deba@822: public: deba@822: klao@946: /// The graph type of the map. klao@946: typedef _Graph Graph; klao@946: /// The key type of the map. alpar@987: typedef _Item Key; klao@946: /// The id map type of the map. deba@1039: typedef AlterationNotifier<_Item> Registry; klao@946: /// The value type of the map. klao@946: typedef _Value Value; deba@822: deba@822: /// The map type. deba@822: typedef VectorMap Map; klao@946: /// The base class of the map. klao@946: typedef typename Registry::ObserverBase Parent; deba@822: deba@822: private: deba@822: deba@822: /// The container type of the map. deba@822: typedef std::vector Container; deba@822: deba@822: public: deba@822: deba@822: /// The reference type of the map; alpar@987: typedef typename Container::reference Reference; deba@822: /// The pointer type of the map; alpar@987: typedef typename Container::pointer Pointer; deba@822: deba@822: /// The const value type of the map. alpar@987: typedef const Value ConstValue; deba@822: /// The const reference type of the map; alpar@987: typedef typename Container::const_reference ConstReference; deba@822: /// The pointer type of the map; alpar@987: typedef typename Container::const_pointer ConstPointer; deba@822: deba@1267: typedef True FullTypeTag; deba@1267: klao@946: /// Constructor to attach the new map into the registry. deba@937: klao@946: /// It construates a map and attachs it into the registry. klao@946: /// It adds all the items of the graph to the map. klao@946: deba@980: VectorMap(const Graph& _g) : graph(&_g) { deba@1039: attach(_g.getNotifier(_Item())); klao@946: build(); klao@946: } deba@822: deba@937: /// Constructor uses given value to initialize the map. deba@937: klao@946: /// It construates a map uses a given value to initialize the map. klao@946: /// It adds all the items of the graph to the map. klao@946: deba@980: VectorMap(const Graph& _g, const Value& _v) : graph(&_g) { deba@1039: attach(_g.getNotifier(_Item())); deba@980: container.resize(graph->maxId(_Item()) + 1, _v); klao@946: } deba@822: deba@1374: VectorMap(const VectorMap& _copy) deba@1374: : Parent(), graph(_copy.getGraph()) { deba@980: if (_copy.attached()) { deba@980: attach(*_copy.getRegistry()); deba@980: container = _copy.container; deba@822: } deba@822: } deba@822: klao@978: using Parent::attach; klao@978: using Parent::detach; klao@978: using Parent::attached; deba@937: klao@946: /** Assign operator to copy a map of the same map type. deba@822: */ klao@946: VectorMap& operator=(const VectorMap& copy) { klao@946: if (© == this) return *this; klao@946: klao@946: if (graph != copy.graph) { klao@946: if (attached()) { klao@946: detach(); klao@946: } klao@946: if (copy.attached()) { klao@946: attach(*copy.getRegistry()); klao@946: } deba@897: } klao@946: container = copy.container; klao@946: klao@946: return *this; klao@946: } klao@946: klao@946: klao@946: virtual ~VectorMap() { klao@946: if (attached()) { klao@946: detach(); deba@822: } klao@946: } klao@946: klao@946: const Graph* getGraph() const { klao@946: return graph; deba@822: } deba@937: deba@937: /// The subcript operator. deba@937: klao@946: /// The subscript operator. The map can be subscripted by the klao@946: /// actual items of the graph. klao@946: alpar@987: Reference operator[](const Key& key) { deba@980: return container[graph->id(key)]; deba@822: } deba@822: deba@937: /// The const subcript operator. deba@937: klao@946: /// The const subscript operator. The map can be subscripted by the klao@946: /// actual items of the graph. klao@946: alpar@987: ConstReference operator[](const Key& key) const { deba@980: return container[graph->id(key)]; deba@822: } deba@822: deba@937: klao@946: /// The setter function of the map. klao@946: klao@946: /// It the same as operator[](key) = value expression. klao@946: /// klao@946: alpar@987: void set(const Key& key, const Value& value) { klao@946: (*this)[key] = value; deba@822: } klao@946: deba@937: /// Adds a new key to the map. deba@822: klao@946: /// It adds a new key to the map. It called by the observer registry klao@946: /// and it overrides the add() member function of the observer base. klao@946: alpar@987: void add(const Key& key) { deba@980: int id = graph->id(key); deba@822: if (id >= (int)container.size()) { deba@822: container.resize(id + 1); deba@822: } deba@822: } deba@937: deba@937: /// Erases a key from the map. deba@822: klao@946: /// Erase a key from the map. It called by the observer registry klao@946: /// and it overrides the erase() member function of the observer base. alpar@987: void erase(const Key&) {} deba@822: klao@946: /// Buildes the map. klao@946: klao@946: /// It buildes the map. It called by the observer registry klao@946: /// and it overrides the build() member function of the observer base. deba@937: klao@946: void build() { deba@980: container.resize(graph->maxId(_Item()) + 1); klao@946: } deba@937: klao@946: /// Clear the map. klao@946: klao@946: /// It erase all items from the map. It called by the observer registry klao@946: /// and it overrides the clear() member function of the observer base. deba@822: void clear() { deba@822: container.clear(); deba@822: } deba@1267: deba@822: private: deba@822: deba@822: Container container; klao@946: const Graph *graph; deba@822: klao@946: }; klao@946: klao@946: klao@946: template klao@946: class VectorMappableGraphExtender : public _Base { deba@844: public: klao@946: klao@946: typedef VectorMappableGraphExtender<_Base> Graph; klao@946: typedef _Base Parent; klao@946: klao@946: typedef typename Parent::Node Node; klao@946: typedef typename Parent::NodeIt NodeIt; klao@946: typedef typename Parent::NodeIdMap NodeIdMap; deba@1039: typedef typename Parent::NodeNotifier NodeObserverRegistry; klao@946: klao@946: typedef typename Parent::Edge Edge; klao@946: typedef typename Parent::EdgeIt EdgeIt; klao@946: typedef typename Parent::EdgeIdMap EdgeIdMap; deba@1039: typedef typename Parent::EdgeNotifier EdgeObserverRegistry; klao@946: klao@946: klao@946: template deba@1267: class NodeMap : deba@1267: public IterableMapExtender > { klao@946: public: klao@946: typedef VectorMappableGraphExtender<_Base> Graph; klao@946: klao@946: typedef typename Graph::Node Node; klao@946: deba@1267: typedef IterableMapExtender > Parent; klao@946: klao@979: //typedef typename Parent::Graph Graph; klao@946: typedef typename Parent::Value Value; klao@946: klao@946: NodeMap(const Graph& g) deba@980: : Parent(g) {} klao@946: NodeMap(const Graph& g, const Value& v) deba@980: : Parent(g, v) {} klao@946: klao@946: }; klao@946: klao@946: template deba@1267: class EdgeMap deba@1267: : public IterableMapExtender > { klao@946: public: klao@946: typedef VectorMappableGraphExtender<_Base> Graph; klao@946: klao@946: typedef typename Graph::Edge Edge; klao@946: deba@1267: typedef IterableMapExtender > Parent; klao@946: klao@979: //typedef typename Parent::Graph Graph; klao@946: typedef typename Parent::Value Value; klao@946: klao@946: EdgeMap(const Graph& g) deba@980: : Parent(g) {} klao@946: EdgeMap(const Graph& g, const Value& v) deba@980: : Parent(g, v) {} klao@946: klao@946: }; klao@946: deba@822: }; deba@822: deba@822: /// @} deba@822: deba@822: } deba@822: deba@822: #endif