alpar@906: /* -*- C++ -*- ladanyi@1435: * lemon/default_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_DEFAULT_MAP_H alpar@921: #define LEMON_DEFAULT_MAP_H deba@822: deba@822: deba@1307: #include deba@1307: #include deba@822: alpar@1587: ///\ingroup graphmapfactory deba@822: ///\file klao@946: ///\brief Graph maps that construct and destruct deba@822: ///their elements dynamically. deba@822: alpar@921: namespace lemon { deba@822: deba@822: deba@1267: template klao@946: struct DefaultMapSelector { deba@1267: typedef ArrayMap<_Graph, _Item, _Value> Map; klao@946: }; deba@822: klao@946: // bool deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, bool> { deba@980: typedef VectorMap<_Graph, _Item, bool> Map; klao@946: }; deba@822: klao@946: // char deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, char> { deba@980: typedef VectorMap<_Graph, _Item, char> Map; klao@946: }; deba@822: deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, signed char> { deba@980: typedef VectorMap<_Graph, _Item, signed char> Map; klao@946: }; deba@822: deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, unsigned char> { deba@980: typedef VectorMap<_Graph, _Item, unsigned char> Map; klao@946: }; deba@822: deba@822: klao@946: // int deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, signed int> { deba@980: typedef VectorMap<_Graph, _Item, signed int> Map; klao@946: }; deba@822: deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, unsigned int> { deba@980: typedef VectorMap<_Graph, _Item, unsigned int> Map; klao@946: }; deba@822: deba@822: klao@946: // short deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, signed short> { deba@980: typedef VectorMap<_Graph, _Item, signed short> Map; klao@946: }; deba@822: deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, unsigned short> { deba@980: typedef VectorMap<_Graph, _Item, unsigned short> Map; klao@946: }; klao@946: klao@946: klao@946: // long deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, signed long> { deba@980: typedef VectorMap<_Graph, _Item, signed long> Map; klao@946: }; klao@946: deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, unsigned long> { deba@980: typedef VectorMap<_Graph, _Item, unsigned long> Map; klao@946: }; klao@946: klao@946: // \todo handling long long type klao@946: klao@946: klao@946: // float deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, float> { deba@980: typedef VectorMap<_Graph, _Item, float> Map; klao@946: }; klao@946: klao@946: klao@946: // double deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, double> { deba@980: typedef VectorMap<_Graph, _Item, double> Map; klao@946: }; klao@946: klao@946: klao@946: // long double deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, long double> { deba@980: typedef VectorMap<_Graph, _Item, long double> Map; klao@946: }; klao@946: klao@946: klao@946: // pointer deba@1267: template deba@1267: struct DefaultMapSelector<_Graph, _Item, _Ptr*> { deba@980: typedef VectorMap<_Graph, _Item, _Ptr*> Map; klao@946: }; klao@946: deba@1669: /// \e deba@1267: template < deba@1267: typename _Graph, deba@1267: typename _Item, deba@1267: typename _Value> deba@1267: class DefaultMap deba@1267: : public DefaultMapSelector<_Graph, _Item, _Value>::Map { klao@946: public: deba@1267: typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent; deba@1267: typedef DefaultMap<_Graph, _Item, _Value> Map; klao@946: klao@946: typedef typename Parent::Graph Graph; alpar@987: typedef typename Parent::Value Value; klao@946: deba@980: DefaultMap(const Graph& _g) : Parent(_g) {} alpar@987: DefaultMap(const Graph& _g, const Value& _v) : Parent(_g, _v) {} deba@1669: klao@946: }; klao@946: klao@946: deba@1669: /// \e klao@946: template deba@1669: class MappableGraphExtender : public _Base { klao@946: public: klao@946: deba@1669: typedef MappableGraphExtender<_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: klao@946: typedef typename Parent::Edge Edge; klao@946: typedef typename Parent::EdgeIt EdgeIt; klao@946: klao@946: klao@946: template deba@1267: class NodeMap deba@1267: : public IterableMapExtender > { klao@946: public: deba@1669: typedef MappableGraphExtender Graph; deba@1267: typedef IterableMapExtender > Parent; klao@946: deba@980: NodeMap(const Graph& _g) deba@980: : Parent(_g) {} klao@1022: NodeMap(const Graph& _g, const _Value& _v) deba@980: : Parent(_g, _v) {} deba@1669: deba@1672: NodeMap& operator=(const NodeMap& cmap) { deba@1672: return operator=(cmap); deba@1672: } deba@1672: deba@1672: deba@1669: /// \brief Template assign operator. deba@1669: /// deba@1669: /// The given parameter should be conform to the ReadMap deba@1669: /// concecpt and could be indiced by the current item set of deba@1669: /// the NodeMap. In this case the value for each item deba@1669: /// is assigned by the value of the given ReadMap. deba@1669: template deba@1669: NodeMap& operator=(const CMap& cmap) { deba@1669: checkConcept, CMap>(); deba@1669: const typename Parent::Graph* graph = Parent::getGraph(); deba@1669: Node it; deba@1669: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1669: Parent::set(it, cmap[it]); deba@1669: } deba@1669: return *this; deba@1669: } deba@1669: klao@946: }; klao@946: klao@946: template deba@1267: class EdgeMap deba@1267: : public IterableMapExtender > { klao@946: public: deba@1669: typedef MappableGraphExtender Graph; deba@1267: typedef IterableMapExtender > Parent; klao@946: deba@980: EdgeMap(const Graph& _g) deba@980: : Parent(_g) {} klao@1022: EdgeMap(const Graph& _g, const _Value& _v) deba@980: : Parent(_g, _v) {} deba@1669: deba@1672: EdgeMap& operator=(const EdgeMap& cmap) { deba@1672: return operator=(cmap); deba@1672: } deba@1672: deba@1669: template deba@1669: EdgeMap& operator=(const CMap& cmap) { deba@1669: checkConcept, CMap>(); deba@1669: const typename Parent::Graph* graph = Parent::getGraph(); deba@1669: Edge it; deba@1669: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1669: Parent::set(it, cmap[it]); deba@1669: } deba@1669: return *this; deba@1669: } klao@946: }; klao@946: klao@946: }; klao@946: deba@1669: /// \e klao@1022: template klao@1022: class MappableUndirGraphExtender : deba@1669: public MappableGraphExtender<_Base> { klao@1022: public: klao@1022: klao@1022: typedef MappableUndirGraphExtender Graph; deba@1669: typedef MappableGraphExtender<_Base> Parent; klao@1022: klao@1022: typedef typename Parent::UndirEdge UndirEdge; klao@1022: klao@1022: template deba@1267: class UndirEdgeMap deba@1267: : public IterableMapExtender > { klao@1022: public: klao@1022: typedef MappableUndirGraphExtender Graph; deba@1267: typedef IterableMapExtender< deba@1267: DefaultMap > Parent; klao@1022: klao@1022: UndirEdgeMap(const Graph& _g) klao@1022: : Parent(_g) {} klao@1022: UndirEdgeMap(const Graph& _g, const _Value& _v) klao@1022: : Parent(_g, _v) {} deba@1669: deba@1672: UndirEdgeMap& operator=(const UndirEdgeMap& cmap) { deba@1672: return operator=(cmap); deba@1672: } deba@1672: deba@1669: template deba@1669: UndirEdgeMap& operator=(const CMap& cmap) { deba@1669: checkConcept, CMap>(); deba@1669: const typename Parent::Graph* graph = Parent::getGraph(); deba@1669: UndirEdge it; deba@1669: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1669: Parent::set(it, cmap[it]); deba@1669: } deba@1669: return *this; deba@1669: } klao@1022: }; klao@1022: klao@1022: klao@1022: }; deba@822: deba@1820: deba@1820: template deba@1820: class MappableUndirBipartiteGraphExtender : public _Base { deba@1820: public: deba@1820: deba@1820: typedef _Base Parent; deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: deba@1820: typedef typename Parent::Node Node; deba@1820: typedef typename Parent::UpperNode UpperNode; deba@1820: typedef typename Parent::LowerNode LowerNode; deba@1820: typedef typename Parent::Edge Edge; deba@1820: typedef typename Parent::UndirEdge UndirEdge; deba@1820: deba@1820: template deba@1820: class UpperNodeMap deba@1820: : public IterableMapExtender > { deba@1820: public: deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: typedef IterableMapExtender > deba@1820: Parent; deba@1820: deba@1820: UpperNodeMap(const Graph& _g) deba@1820: : Parent(_g) {} deba@1820: UpperNodeMap(const Graph& _g, const _Value& _v) deba@1820: : Parent(_g, _v) {} deba@1820: deba@1820: UpperNodeMap& operator=(const UpperNodeMap& cmap) { deba@1820: return operator=(cmap); deba@1820: } deba@1820: deba@1820: deba@1820: /// \brief Template assign operator. deba@1820: /// deba@1820: /// The given parameter should be conform to the ReadMap deba@1820: /// concept and could be indiced by the current item set of deba@1820: /// the UpperNodeMap. In this case the value for each item deba@1820: /// is assigned by the value of the given ReadMap. deba@1820: template deba@1820: UpperNodeMap& operator=(const CMap& cmap) { deba@1820: checkConcept, CMap>(); deba@1820: const typename Parent::Graph* graph = Parent::getGraph(); deba@1820: UpperNode it; deba@1820: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1820: Parent::set(it, cmap[it]); deba@1820: } deba@1820: return *this; deba@1820: } deba@1820: deba@1820: }; deba@1820: deba@1820: template deba@1820: class LowerNodeMap deba@1820: : public IterableMapExtender > { deba@1820: public: deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: typedef IterableMapExtender > deba@1820: Parent; deba@1820: deba@1820: LowerNodeMap(const Graph& _g) deba@1820: : Parent(_g) {} deba@1820: LowerNodeMap(const Graph& _g, const _Value& _v) deba@1820: : Parent(_g, _v) {} deba@1820: deba@1820: LowerNodeMap& operator=(const LowerNodeMap& cmap) { deba@1820: return operator=(cmap); deba@1820: } deba@1820: deba@1820: deba@1820: /// \brief Template assign operator. deba@1820: /// deba@1820: /// The given parameter should be conform to the ReadMap deba@1820: /// concept and could be indiced by the current item set of deba@1820: /// the LowerNodeMap. In this case the value for each item deba@1820: /// is assigned by the value of the given ReadMap. deba@1820: template deba@1820: LowerNodeMap& operator=(const CMap& cmap) { deba@1820: checkConcept, CMap>(); deba@1820: const typename Parent::Graph* graph = Parent::getGraph(); deba@1820: LowerNode it; deba@1820: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1820: Parent::set(it, cmap[it]); deba@1820: } deba@1820: return *this; deba@1820: } deba@1820: deba@1820: }; deba@1820: deba@1820: protected: deba@1820: deba@1820: template deba@1820: class NodeMapBase : public Parent::NodeNotifier::ObserverBase { deba@1820: public: deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: deba@1820: typedef Node Key; deba@1820: typedef _Value Value; deba@1820: deba@1820: /// The reference type of the map; deba@1820: typedef typename LowerNodeMap<_Value>::Reference Reference; deba@1820: /// The pointer type of the map; deba@1820: typedef typename LowerNodeMap<_Value>::Pointer Pointer; deba@1820: deba@1820: /// The const value type of the map. deba@1820: typedef const Value ConstValue; deba@1820: /// The const reference type of the map; deba@1820: typedef typename LowerNodeMap<_Value>::ConstReference ConstReference; deba@1820: /// The pointer type of the map; deba@1820: typedef typename LowerNodeMap<_Value>::ConstPointer ConstPointer; deba@1820: deba@1820: typedef True ReferenceMapTag; deba@1820: deba@1820: NodeMapBase(const Graph& _g) deba@1820: : graph(&_g), lowerMap(_g), upperMap(_g) { deba@1820: Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); deba@1820: } deba@1820: NodeMapBase(const Graph& _g, const _Value& _v) deba@1820: : graph(&_g), lowerMap(_g, _v), deba@1820: upperMap(_g, _v) { deba@1820: Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); deba@1820: } deba@1820: deba@1820: virtual ~NodeMapBase() { deba@1820: if (Parent::NodeNotifier::ObserverBase::attached()) { deba@1820: Parent::NodeNotifier::ObserverBase::detach(); deba@1820: } deba@1820: } deba@1820: deba@1820: ConstReference operator[](const Key& node) const { deba@1820: if (Parent::upper(node)) { deba@1820: return upperMap[node]; deba@1820: } else { deba@1820: return lowerMap[node]; deba@1820: } deba@1820: } deba@1820: deba@1820: Reference operator[](const Key& node) { deba@1820: if (Parent::upper(node)) { deba@1820: return upperMap[node]; deba@1820: } else { deba@1820: return lowerMap[node]; deba@1820: } deba@1820: } deba@1820: deba@1820: void set(const Key& node, const Value& value) { deba@1820: if (Parent::upper(node)) { deba@1820: upperMap.set(node, value); deba@1820: } else { deba@1820: lowerMap.set(node, value); deba@1820: } deba@1820: } deba@1820: deba@1820: protected: deba@1820: deba@1820: virtual void add(const Node&) {} deba@1820: virtual void erase(const Node&) {} deba@1820: virtual void clear() {} deba@1820: virtual void build() {} deba@1820: deba@1820: const Graph* getGraph() const { return graph; } deba@1820: deba@1820: private: deba@1820: const Graph* graph; deba@1820: LowerNodeMap<_Value> lowerMap; deba@1820: UpperNodeMap<_Value> upperMap; deba@1820: }; deba@1820: deba@1820: public: deba@1820: deba@1820: template deba@1820: class NodeMap deba@1820: : public IterableMapExtender > { deba@1820: public: deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: typedef IterableMapExtender< NodeMapBase<_Value> > Parent; deba@1820: deba@1820: NodeMap(const Graph& _g) deba@1820: : Parent(_g) {} deba@1820: NodeMap(const Graph& _g, const _Value& _v) deba@1820: : Parent(_g, _v) {} deba@1820: deba@1820: NodeMap& operator=(const NodeMap& cmap) { deba@1820: return operator=(cmap); deba@1820: } deba@1820: deba@1820: deba@1820: /// \brief Template assign operator. deba@1820: /// deba@1820: /// The given parameter should be conform to the ReadMap deba@1820: /// concept and could be indiced by the current item set of deba@1820: /// the NodeMap. In this case the value for each item deba@1820: /// is assigned by the value of the given ReadMap. deba@1820: template deba@1820: NodeMap& operator=(const CMap& cmap) { deba@1820: checkConcept, CMap>(); deba@1820: const typename Parent::Graph* graph = Parent::getGraph(); deba@1820: Node it; deba@1820: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1820: Parent::set(it, cmap[it]); deba@1820: } deba@1820: return *this; deba@1820: } deba@1820: deba@1820: }; deba@1820: deba@1820: deba@1820: deba@1820: template deba@1820: class EdgeMap deba@1820: : public IterableMapExtender > { deba@1820: public: deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: typedef IterableMapExtender > Parent; deba@1820: deba@1820: EdgeMap(const Graph& _g) deba@1820: : Parent(_g) {} deba@1820: EdgeMap(const Graph& _g, const _Value& _v) deba@1820: : Parent(_g, _v) {} deba@1820: deba@1820: EdgeMap& operator=(const EdgeMap& cmap) { deba@1820: return operator=(cmap); deba@1820: } deba@1820: deba@1820: template deba@1820: EdgeMap& operator=(const CMap& cmap) { deba@1820: checkConcept, CMap>(); deba@1820: const typename Parent::Graph* graph = Parent::getGraph(); deba@1820: Edge it; deba@1820: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1820: Parent::set(it, cmap[it]); deba@1820: } deba@1820: return *this; deba@1820: } deba@1820: }; deba@1820: deba@1820: template deba@1820: class UndirEdgeMap deba@1820: : public IterableMapExtender > { deba@1820: public: deba@1820: typedef MappableUndirBipartiteGraphExtender Graph; deba@1820: typedef IterableMapExtender > deba@1820: Parent; deba@1820: deba@1820: UndirEdgeMap(const Graph& _g) deba@1820: : Parent(_g) {} deba@1820: UndirEdgeMap(const Graph& _g, const _Value& _v) deba@1820: : Parent(_g, _v) {} deba@1820: deba@1820: UndirEdgeMap& operator=(const UndirEdgeMap& cmap) { deba@1820: return operator=(cmap); deba@1820: } deba@1820: deba@1820: template deba@1820: UndirEdgeMap& operator=(const CMap& cmap) { deba@1820: checkConcept, CMap>(); deba@1820: const typename Parent::Graph* graph = Parent::getGraph(); deba@1820: UndirEdge it; deba@1820: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1820: Parent::set(it, cmap[it]); deba@1820: } deba@1820: return *this; deba@1820: } deba@1820: }; deba@1820: deba@1820: }; deba@1820: deba@822: } deba@822: deba@822: #endif