/* -*- 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_BITS_GRAPH_EXTENDER_H #define LEMON_BITS_GRAPH_EXTENDER_H #include #include #include ///\ingroup graphbits ///\file ///\brief Extenders for the graph types namespace lemon { /// \ingroup graphbits /// /// \brief Extender for the Graphs template class GraphExtender : public Base { public: typedef Base Parent; typedef GraphExtender Graph; // Base extensions typedef typename Parent::Node Node; typedef typename Parent::Edge Edge; int maxId(Node) const { return Parent::maxNodeId(); } int maxId(Edge) const { return Parent::maxEdgeId(); } Node fromId(int id, Node) const { return Parent::nodeFromId(id); } Edge fromId(int id, Edge) const { return Parent::edgeFromId(id); } Node oppositeNode(const Node &n, const Edge &e) const { if (n == Parent::source(e)) return Parent::target(e); else if(n==Parent::target(e)) return Parent::source(e); else return INVALID; } // Alterable extension typedef AlterationNotifier NodeNotifier; typedef AlterationNotifier EdgeNotifier; protected: mutable NodeNotifier node_notifier; mutable EdgeNotifier edge_notifier; public: NodeNotifier& getNotifier(Node) const { return node_notifier; } EdgeNotifier& getNotifier(Edge) const { return edge_notifier; } class NodeIt : public Node { const Graph* graph; public: NodeIt() {} NodeIt(Invalid i) : Node(i) { } explicit NodeIt(const Graph& _graph) : graph(&_graph) { _graph.first(static_cast(*this)); } NodeIt(const Graph& _graph, const Node& node) : Node(node), graph(&_graph) {} NodeIt& operator++() { graph->next(*this); return *this; } }; class EdgeIt : public Edge { const Graph* graph; public: EdgeIt() { } EdgeIt(Invalid i) : Edge(i) { } explicit EdgeIt(const Graph& _graph) : graph(&_graph) { _graph.first(static_cast(*this)); } EdgeIt(const Graph& _graph, const Edge& e) : Edge(e), graph(&_graph) { } EdgeIt& operator++() { graph->next(*this); return *this; } }; class OutEdgeIt : public Edge { const Graph* graph; public: OutEdgeIt() { } OutEdgeIt(Invalid i) : Edge(i) { } OutEdgeIt(const Graph& _graph, const Node& node) : graph(&_graph) { _graph.firstOut(*this, node); } OutEdgeIt(const Graph& _graph, const Edge& edge) : Edge(edge), graph(&_graph) {} OutEdgeIt& operator++() { graph->nextOut(*this); return *this; } }; class InEdgeIt : public Edge { const Graph* graph; public: InEdgeIt() { } InEdgeIt(Invalid i) : Edge(i) { } InEdgeIt(const Graph& _graph, const Node& node) : graph(&_graph) { _graph.firstIn(*this, node); } InEdgeIt(const Graph& _graph, const Edge& edge) : Edge(edge), graph(&_graph) {} InEdgeIt& operator++() { graph->nextIn(*this); return *this; } }; /// \brief Base node of the iterator /// /// Returns the base node (i.e. the source in this case) of the iterator Node baseNode(const OutEdgeIt &e) const { return Parent::source(e); } /// \brief Running node of the iterator /// /// Returns the running node (i.e. the target in this case) of the /// iterator Node runningNode(const OutEdgeIt &e) const { return Parent::target(e); } /// \brief Base node of the iterator /// /// Returns the base node (i.e. the target in this case) of the iterator Node baseNode(const InEdgeIt &e) const { return Parent::target(e); } /// \brief Running node of the iterator /// /// Returns the running node (i.e. the source in this case) of the /// iterator Node runningNode(const InEdgeIt &e) const { return Parent::source(e); } template class NodeMap : public MapExtender > { public: typedef GraphExtender Graph; typedef MapExtender > Parent; explicit NodeMap(const Graph& graph) : Parent(graph) {} NodeMap(const Graph& graph, const _Value& value) : Parent(graph, value) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); } template NodeMap& operator=(const CMap& cmap) { Parent::operator=(cmap); return *this; } }; template class EdgeMap : public MapExtender > { public: typedef GraphExtender Graph; typedef MapExtender > Parent; explicit EdgeMap(const Graph& graph) : Parent(graph) {} EdgeMap(const Graph& graph, const _Value& value) : Parent(graph, value) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { Parent::operator=(cmap); return *this; } }; Node addNode() { Node node = Parent::addNode(); getNotifier(Node()).add(node); return node; } Edge addEdge(const Node& from, const Node& to) { Edge edge = Parent::addEdge(from, to); getNotifier(Edge()).add(edge); return edge; } void clear() { getNotifier(Edge()).clear(); getNotifier(Node()).clear(); Parent::clear(); } void erase(const Node& node) { Edge edge; Parent::firstOut(edge, node); while (edge != INVALID ) { erase(edge); Parent::firstOut(edge, node); } Parent::firstIn(edge, node); while (edge != INVALID ) { erase(edge); Parent::firstIn(edge, node); } getNotifier(Node()).erase(node); Parent::erase(node); } void erase(const Edge& edge) { getNotifier(Edge()).erase(edge); Parent::erase(edge); } GraphExtender() { node_notifier.setContainer(*this); edge_notifier.setContainer(*this); } ~GraphExtender() { edge_notifier.clear(); node_notifier.clear(); } }; } #endif