/* -*- C++ -*- * src/lemon/vector_map.h - Part of LEMON, a generic C++ optimization library * * Copyright (C) 2005 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 #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 AlterationNotifier 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 < typename _Graph, typename _Item, typename _Value > class VectorMap : public AlterationNotifier<_Item>::ObserverBase { public: /// The graph type of the map. typedef _Graph Graph; /// The key type of the map. typedef _Item Key; /// The id map type of the map. typedef AlterationNotifier<_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 reference type of the map; typedef typename Container::reference Reference; /// The pointer type of the map; typedef typename Container::pointer Pointer; /// The const value type of the map. typedef const Value ConstValue; /// The const reference type of the map; typedef typename Container::const_reference ConstReference; /// The pointer type of the map; typedef typename Container::const_pointer ConstPointer; typedef True FullTypeTag; /// 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) : graph(&_g) { attach(_g.getNotifier(_Item())); 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, const Value& _v) : graph(&_g) { attach(_g.getNotifier(_Item())); container.resize(graph->maxId(_Item()) + 1, _v); } VectorMap(const VectorMap& _copy) : graph(_copy.getGraph()) { if (_copy.attached()) { attach(*_copy.getRegistry()); container = _copy.container; } } using Parent::attach; using Parent::detach; using Parent::attached; /** 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. Reference operator[](const Key& key) { return container[graph->id(key)]; } /// The const subcript operator. /// The const subscript operator. The map can be subscripted by the /// actual items of the graph. ConstReference operator[](const Key& key) const { return container[graph->id(key)]; } /// The setter function of the map. /// It the same as operator[](key) = value expression. /// void set(const Key& key, const Value& 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 Key& key) { int id = graph->id(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 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(graph->maxId(_Item()) + 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::NodeNotifier NodeObserverRegistry; typedef typename Parent::Edge Edge; typedef typename Parent::EdgeIt EdgeIt; typedef typename Parent::EdgeIdMap EdgeIdMap; typedef typename Parent::EdgeNotifier EdgeObserverRegistry; template class NodeMap : public IterableMapExtender > { public: typedef VectorMappableGraphExtender<_Base> Graph; typedef typename Graph::Node Node; 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 VectorMappableGraphExtender<_Base> Graph; typedef typename Graph::Edge Edge; 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