/* -*- C++ -*- * src/lemon/vector_map.h - Part of LEMON, a generic C++ optimization library * * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Combinatorial Optimization Research Group, 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_VECTOR_MAP_H #define LEMON_VECTOR_MAP_H #include #include #include ///\ingroup graphmaps ///\file ///\brief Vector based graph maps. namespace lemon { /// \addtogroup graphmaps /// @{ /// The VectorMap 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. This map factory /// uses the std::vector to implement the container function. /// /// \param Registry The AlterationObserverRegistry that will notify this map. /// \param IdMap The IdMap type of the graph items. /// \param Value The value type of the map. /// /// \author Balazs Dezso template class VectorMap : public AlterationObserverRegistry<_Item>::ObserverBase { public: /// The graph type of the map. typedef _Graph Graph; /// The key type of the map. typedef _Item KeyType; /// The id map type of the map. typedef _IdMap IdMap; /// The registry type of the map. typedef AlterationObserverRegistry<_Item> Registry; /// The value type of the map. typedef _Value Value; /// The map type. typedef VectorMap Map; /// The base class of the map. typedef typename Registry::ObserverBase Parent; private: /// The container type of the map. typedef std::vector Container; public: /// The value type of the map. typedef Value ValueType; /// The reference type of the map; typedef typename Container::reference ReferenceType; /// The pointer type of the map; typedef typename Container::pointer PointerType; /// The const value type of the map. typedef const Value ConstValueType; /// The const reference type of the map; typedef typename Container::const_reference ConstReferenceType; /// The pointer type of the map; typedef typename Container::const_pointer ConstPointerType; /// Constructor to attach the new map into the registry. /// It construates a map and attachs it into the registry. /// It adds all the items of the graph to the map. VectorMap(const Graph& _g, Registry& _r) : graph(&_g) { attach(_r); build(); } /// Constructor uses given value to initialize the map. /// It construates a map uses a given value to initialize the map. /// It adds all the items of the graph to the map. VectorMap(const Graph& g, Registry& r, const Value& v) : graph(&g) { attach(r); container.resize(IdMap(*graph).maxId() + 1, v); } VectorMap(const VectorMap& copy) : graph(copy.getGraph()) { if (copy.attached()) { attach(*copy.getRegistry()); container = copy.container; } } /** Assign operator to copy a map of the same map type. */ VectorMap& operator=(const VectorMap& copy) { if (© == this) return *this; if (graph != copy.graph) { if (attached()) { detach(); } if (copy.attached()) { attach(*copy.getRegistry()); } } container = copy.container; return *this; } virtual ~VectorMap() { if (attached()) { detach(); } } const Graph* getGraph() const { return graph; } /// The subcript operator. /// The subscript operator. The map can be subscripted by the /// actual items of the graph. ReferenceType operator[](const KeyType& key) { return container[IdMap(*graph)[key]]; } /// The const subcript operator. /// The const subscript operator. The map can be subscripted by the /// actual items of the graph. ConstReferenceType operator[](const KeyType& key) const { return container[IdMap(*graph)[key]]; } /// The setter function of the map. /// It the same as operator[](key) = value expression. /// void set(const KeyType& key, const ValueType& value) { (*this)[key] = value; } /// Adds a new key to the map. /// It adds a new key to the map. It called by the observer registry /// and it overrides the add() member function of the observer base. void add(const KeyType& key) { int id = IdMap(*graph)[key]; if (id >= (int)container.size()) { container.resize(id + 1); } } /// Erases a key from the map. /// Erase a key from the map. It called by the observer registry /// and it overrides the erase() member function of the observer base. void erase(const KeyType& key) {} /// Buildes the map. /// It buildes the map. It called by the observer registry /// and it overrides the build() member function of the observer base. void build() { container.resize(IdMap(*graph).maxId() + 1); } /// Clear the map. /// It erase all items from the map. It called by the observer registry /// and it overrides the clear() member function of the observer base. void clear() { container.clear(); } private: Container container; const Graph *graph; }; template class VectorMappableGraphExtender : public _Base { public: typedef VectorMappableGraphExtender<_Base> Graph; typedef _Base Parent; typedef typename Parent::Node Node; typedef typename Parent::NodeIt NodeIt; typedef typename Parent::NodeIdMap NodeIdMap; typedef typename Parent::NodeObserverRegistry NodeObserverRegistry; typedef typename Parent::Edge Edge; typedef typename Parent::EdgeIt EdgeIt; typedef typename Parent::EdgeIdMap EdgeIdMap; typedef typename Parent::EdgeObserverRegistry EdgeObserverRegistry; template class NodeMap : public VectorMap { public: typedef VectorMappableGraphExtender<_Base> Graph; typedef typename Graph::Node Node; typedef typename Graph::NodeIdMap NodeIdMap; typedef VectorMap Parent; typedef typename Parent::Graph Graph; typedef typename Parent::Value Value; NodeMap(const Graph& g) : Parent(g, g.getNodeObserverRegistry()) {} NodeMap(const Graph& g, const Value& v) : Parent(g, g.getNodeObserverRegistry(), v) {} }; template class EdgeMap : public VectorMap { public: typedef VectorMappableGraphExtender<_Base> Graph; typedef typename Graph::Edge Edge; typedef typename Graph::EdgeIdMap EdgeIdMap; typedef VectorMap Parent; typedef typename Parent::Graph Graph; typedef typename Parent::Value Value; EdgeMap(const Graph& g) : Parent(g, g.getEdgeObserverRegistry()) {} EdgeMap(const Graph& g, const Value& v) : Parent(g, g.getEdgeObserverRegistry(), v) {} }; }; /// @} } #endif