/* -*- C++ -*- * src/lemon/map_utils.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. * */ ///\ingroup mutils ///\file ///\brief Map utilities. #include namespace lemon { /// \addtogroup gutils /// @{ /// \brief General inversable map type. /// This type provides simple inversable map functions. /// The InversableMap wraps an arbitrary ReadWriteMap /// and if a key is setted to a new value then store it /// in the inverse map. template < typename _Graph, typename _Map > class InversableMap : protected _Map { public: typedef _Graph Graph; typedef _Map Map; typedef typename _Map::Key Key; typedef typename _Map::Value Value; typedef std::map InverseMap; typedef typename _Map::ConstReference ConstReference; /// \brief Constructor. /// /// Construct a new InversableMap for the graph. /// InversableMap(const Graph& graph) : Map(graph) {} /// \brief The setter function of the map. /// /// It sets the map and the inverse map to given key-value pair. void set(const Key& key, const Value& val) { Value oldval = Map::operator[](key); typename InverseMap::iterator it = inv_map.find(oldval); if (it != inv_map.end() && it->second == key) { inv_map.erase(it); } inv_map.insert(make_pair(val, key)); Map::set(key, val); } ConstReference operator[](const Key&) const { return Map::operator[](key); } virtual void add(const Key&) { Map::add(key); } virtual void erase(const Key&) { Value val = Map::operator[](key); typename InverseMap::iterator it = inv_map.find(val); if (it != inv_map.end() && it->second == key) { invMap.erase(it); } Map::erase(key); } const InverseMap& inverse() const { return inv_map; } private: InverseMap inv_map; }; /// \brief Provides a mutable, continous and unique descriptor for each /// item in the graph. /// /// The DescriptorMap class provides a mutable, continous and immutable /// mapping for each item in the graph. /// /// \param _Graph The graph class the \c DescriptorMap belongs to. /// \param _Item The Item is the Key of the Map. It may be Node, Edge or /// UndirEdge. /// \param _Map A ReadWriteMap mapping from the item type to integer. template < typename _Graph, typename _Item, typename _Map > class DescriptorMap : protected _Map { typedef _Item Item; typedef _Map Map; public: /// The graph class of DescriptorMap. typedef _Graph Graph; /// The key type of DescriptorMap (Node, Edge, UndirEdge). typedef typename _Map::Key Key; /// The value type of DescriptorMap. typedef typename _Map::Value Value; typedef std::vector InverseMap; /// \brief Constructor. /// /// Constructor for creating descriptor map. DescriptorMap(const Graph& _graph) : Map(_graph) { build(); } virtual void add(const Item& item) { Map::add(item); Map::set(item, inv_map.size()); inv_map.push_back(item); } virtual void erase(const Item& item) { Map::set(inv_map.back(), Map::operator[](item)); inv_map[Map::operator[](item)] = inv_map.back(); Map::erase(item); } virtual void build() { Map::build(); Item it; for (getGraph()->first(it); it != INVALID; getGraph()->next(it)) { Map::set(it, inv_map.size()); inv_map.push_back(it); } } virtual void clear() { inv_map.clear(); Map::clear(); } /// \brief Gives back the \e descriptor of the item. /// /// Gives back the mutable and unique \e descriptor of the map. int operator[](const Item& item) const { return Map::operator[](item); } /// \brief Gives back the inverse of the map. /// /// Gives back the inverse of the map. const InverseMap inverse() const { return inv_map; } private: vector inv_map; }; /// Provides an immutable and unique id for each item in the graph. /// The IdMap class provides an unique and immutable mapping for each item /// in the graph. /// template class IdMap { public: typedef _Graph Graph; typedef int Value; typedef _Item Item; /// \brief The class represents the inverse of the map. /// /// The class represents the inverse of the map. /// \see inverse() class InverseMap { protected: InverseMap(const Graph& _graph) : graph(_graph) {} public: /// \brief Gives back the given item by its id. /// /// Gives back the given item by its id. /// Item operator[](int id) const { return graph->fromId(id, Item());} private: Graph* graph; }; /// \brief Constructor. /// /// Constructor for creating id map. IdMap(const Graph& _graph) : graph(&_graph) {} /// \brief Gives back the \e id of the item. /// /// Gives back the immutable and unique \e id of the map. int operator[](const Item& item) const { return graph->id(item);} /// \brief Gives back the inverse of the map. /// /// Gives back the inverse of the map. InverseMap inverse() const { return InverseMap(*graph);} private: const Graph* graph; }; }