/* -*- C++ -*- * * This file is a part of LEMON, a generic C++ optimization library * * Copyright (C) 2003-2006 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Research Group on Combinatorial Optimization, 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_DEFAULT_MAP_H #define LEMON_DEFAULT_MAP_H #include #include ///\ingroup graphmapfactory ///\file ///\brief Graph maps that construct and destruct ///their elements dynamically. namespace lemon { template struct DefaultMapSelector { typedef ArrayMap<_Graph, _Item, _Value> Map; }; // bool template struct DefaultMapSelector<_Graph, _Item, bool> { typedef VectorMap<_Graph, _Item, bool> Map; }; // char template struct DefaultMapSelector<_Graph, _Item, char> { typedef VectorMap<_Graph, _Item, char> Map; }; template struct DefaultMapSelector<_Graph, _Item, signed char> { typedef VectorMap<_Graph, _Item, signed char> Map; }; template struct DefaultMapSelector<_Graph, _Item, unsigned char> { typedef VectorMap<_Graph, _Item, unsigned char> Map; }; // int template struct DefaultMapSelector<_Graph, _Item, signed int> { typedef VectorMap<_Graph, _Item, signed int> Map; }; template struct DefaultMapSelector<_Graph, _Item, unsigned int> { typedef VectorMap<_Graph, _Item, unsigned int> Map; }; // short template struct DefaultMapSelector<_Graph, _Item, signed short> { typedef VectorMap<_Graph, _Item, signed short> Map; }; template struct DefaultMapSelector<_Graph, _Item, unsigned short> { typedef VectorMap<_Graph, _Item, unsigned short> Map; }; // long template struct DefaultMapSelector<_Graph, _Item, signed long> { typedef VectorMap<_Graph, _Item, signed long> Map; }; template struct DefaultMapSelector<_Graph, _Item, unsigned long> { typedef VectorMap<_Graph, _Item, unsigned long> Map; }; // \todo handling long long type // float template struct DefaultMapSelector<_Graph, _Item, float> { typedef VectorMap<_Graph, _Item, float> Map; }; // double template struct DefaultMapSelector<_Graph, _Item, double> { typedef VectorMap<_Graph, _Item, double> Map; }; // long double template struct DefaultMapSelector<_Graph, _Item, long double> { typedef VectorMap<_Graph, _Item, long double> Map; }; // pointer template struct DefaultMapSelector<_Graph, _Item, _Ptr*> { typedef VectorMap<_Graph, _Item, _Ptr*> Map; }; /// \e template < typename _Graph, typename _Item, typename _Value> class DefaultMap : public DefaultMapSelector<_Graph, _Item, _Value>::Map { public: typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent; typedef DefaultMap<_Graph, _Item, _Value> Map; typedef typename Parent::Graph Graph; typedef typename Parent::Value Value; DefaultMap(const Graph& _g) : Parent(_g) {} DefaultMap(const Graph& _g, const Value& _v) : Parent(_g, _v) {} }; /// \e template class MappableGraphExtender : public _Base { public: typedef MappableGraphExtender<_Base> Graph; typedef _Base Parent; typedef typename Parent::Node Node; typedef typename Parent::NodeIt NodeIt; typedef typename Parent::Edge Edge; typedef typename Parent::EdgeIt EdgeIt; template class NodeMap : public IterableMapExtender > { public: typedef MappableGraphExtender Graph; typedef IterableMapExtender > Parent; NodeMap(const Graph& _g) : Parent(_g) {} NodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concecpt and could be indiced by the current item set of /// the NodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Node it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class EdgeMap : public IterableMapExtender > { public: typedef MappableGraphExtender Graph; typedef IterableMapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} EdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Edge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; }; /// \e template class MappableEdgeSetExtender : public _Base { public: typedef MappableEdgeSetExtender<_Base> Graph; typedef _Base Parent; typedef typename Parent::Edge Edge; typedef typename Parent::EdgeIt EdgeIt; template class EdgeMap : public IterableMapExtender > { public: typedef MappableEdgeSetExtender Graph; typedef IterableMapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} EdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Edge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; }; /// \e template class MappableUGraphExtender : public MappableGraphExtender<_Base> { public: typedef MappableUGraphExtender Graph; typedef MappableGraphExtender<_Base> Parent; typedef typename Parent::UEdge UEdge; template class UEdgeMap : public IterableMapExtender > { public: typedef MappableUGraphExtender Graph; typedef IterableMapExtender< DefaultMap > Parent; UEdgeMap(const Graph& _g) : Parent(_g) {} UEdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); } template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); UEdge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; }; /// \e template class MappableUEdgeSetExtender : public MappableEdgeSetExtender<_Base> { public: typedef MappableUEdgeSetExtender Graph; typedef MappableEdgeSetExtender<_Base> Parent; typedef typename Parent::UEdge UEdge; template class UEdgeMap : public IterableMapExtender > { public: typedef MappableUEdgeSetExtender Graph; typedef IterableMapExtender< DefaultMap > Parent; UEdgeMap(const Graph& _g) : Parent(_g) {} UEdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); } template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); UEdge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; }; template class MappableBpUGraphExtender : public _Base { public: typedef _Base Parent; typedef MappableBpUGraphExtender Graph; typedef typename Parent::Node Node; typedef typename Parent::ANode ANode; typedef typename Parent::BNode BNode; typedef typename Parent::Edge Edge; typedef typename Parent::UEdge UEdge; template class ANodeMap : public IterableMapExtender > { public: typedef MappableBpUGraphExtender Graph; typedef IterableMapExtender > Parent; ANodeMap(const Graph& _g) : Parent(_g) {} ANodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} ANodeMap& operator=(const ANodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concept and could be indiced by the current item set of /// the ANodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template ANodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); ANode it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class BNodeMap : public IterableMapExtender > { public: typedef MappableBpUGraphExtender Graph; typedef IterableMapExtender > Parent; BNodeMap(const Graph& _g) : Parent(_g) {} BNodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} BNodeMap& operator=(const BNodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concept and could be indiced by the current item set of /// the BNodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template BNodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); BNode it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; protected: template class NodeMapBase : public Parent::NodeNotifier::ObserverBase { public: typedef MappableBpUGraphExtender Graph; typedef Node Key; typedef _Value Value; /// The reference type of the map; typedef typename BNodeMap<_Value>::Reference Reference; /// The pointer type of the map; typedef typename BNodeMap<_Value>::Pointer Pointer; /// The const value type of the map. typedef const Value ConstValue; /// The const reference type of the map; typedef typename BNodeMap<_Value>::ConstReference ConstReference; /// The pointer type of the map; typedef typename BNodeMap<_Value>::ConstPointer ConstPointer; typedef True ReferenceMapTag; NodeMapBase(const Graph& _g) : graph(&_g), bNodeMap(_g), aNodeMap(_g) { Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); } NodeMapBase(const Graph& _g, const _Value& _v) : graph(&_g), bNodeMap(_g, _v), aNodeMap(_g, _v) { Parent::NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); } virtual ~NodeMapBase() { if (Parent::NodeNotifier::ObserverBase::attached()) { Parent::NodeNotifier::ObserverBase::detach(); } } ConstReference operator[](const Key& node) const { if (Parent::aNode(node)) { return aNodeMap[node]; } else { return bNodeMap[node]; } } Reference operator[](const Key& node) { if (Parent::aNode(node)) { return aNodeMap[node]; } else { return bNodeMap[node]; } } void set(const Key& node, const Value& value) { if (Parent::aNode(node)) { aNodeMap.set(node, value); } else { bNodeMap.set(node, value); } } protected: virtual void add(const Node&) {} virtual void erase(const Node&) {} virtual void clear() {} virtual void build() {} const Graph* getGraph() const { return graph; } private: const Graph* graph; BNodeMap<_Value> bNodeMap; ANodeMap<_Value> aNodeMap; }; public: template class NodeMap : public IterableMapExtender > { public: typedef MappableBpUGraphExtender Graph; typedef IterableMapExtender< NodeMapBase<_Value> > Parent; NodeMap(const Graph& _g) : Parent(_g) {} NodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concept and could be indiced by the current item set of /// the NodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Node it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class EdgeMap : public IterableMapExtender > { public: typedef MappableBpUGraphExtender Graph; typedef IterableMapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} EdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Edge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class UEdgeMap : public IterableMapExtender > { public: typedef MappableBpUGraphExtender Graph; typedef IterableMapExtender > Parent; UEdgeMap(const Graph& _g) : Parent(_g) {} UEdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); } template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); UEdge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; }; } #endif