deba@1791: /* -*- C++ -*- deba@1791: * alpar@1956: * This file is a part of LEMON, a generic C++ optimization library alpar@1956: * alpar@1956: * Copyright (C) 2003-2006 alpar@1956: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1956: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@1791: * deba@1791: * Permission to use, modify and distribute this software is granted deba@1791: * provided that this copyright notice appears in all copies. For deba@1791: * precise terms see the accompanying LICENSE file. deba@1791: * deba@1791: * This software is provided "AS IS" with no warranty of any kind, deba@1791: * express or implied, and with no claim as to its suitability for any deba@1791: * purpose. deba@1791: * deba@1791: */ deba@1791: deba@1996: #ifndef LEMON_BITS_GRAPH_EXTENDER_H deba@1996: #define LEMON_BITS_GRAPH_EXTENDER_H deba@1791: deba@1993: #include deba@1820: #include deba@1791: deba@1999: #include deba@1979: #include deba@1979: deba@1999: #include deba@1999: #include deba@1999: deba@1996: ///\ingroup graphbits deba@1996: ///\file deba@1996: ///\brief Extenders for the graph types deba@1791: namespace lemon { deba@1791: deba@1996: /// \ingroup graphbits deba@1996: /// deba@1996: /// \brief Extender for the Graphs deba@1979: template deba@1979: class GraphExtender : public Base { deba@1791: public: deba@1791: deba@1979: typedef Base Parent; deba@1791: typedef GraphExtender Graph; deba@1791: deba@1979: // Base extensions deba@1979: deba@1791: typedef typename Parent::Node Node; deba@1791: typedef typename Parent::Edge Edge; deba@1791: deba@1791: int maxId(Node) const { deba@1791: return Parent::maxNodeId(); deba@1791: } deba@1791: deba@1791: int maxId(Edge) const { deba@1791: return Parent::maxEdgeId(); deba@1791: } deba@1791: deba@1791: Node fromId(int id, Node) const { deba@1791: return Parent::nodeFromId(id); deba@1791: } deba@1791: deba@1791: Edge fromId(int id, Edge) const { deba@1791: return Parent::edgeFromId(id); deba@1791: } deba@1791: deba@1791: Node oppositeNode(const Node &n, const Edge &e) const { deba@1791: if (n == Parent::source(e)) deba@1791: return Parent::target(e); deba@1791: else if(n==Parent::target(e)) deba@1791: return Parent::source(e); deba@1791: else deba@1791: return INVALID; deba@1791: } deba@1791: deba@1979: // Alterable extension deba@1791: deba@1999: typedef AlterationNotifier NodeNotifier; deba@1999: typedef AlterationNotifier EdgeNotifier; deba@1979: deba@1979: deba@1979: protected: deba@1979: deba@1979: mutable NodeNotifier node_notifier; deba@1979: mutable EdgeNotifier edge_notifier; deba@1791: deba@1791: public: deba@1791: deba@1979: NodeNotifier& getNotifier(Node) const { deba@1979: return node_notifier; deba@1979: } deba@1979: deba@1979: EdgeNotifier& getNotifier(Edge) const { deba@1979: return edge_notifier; deba@1979: } deba@1979: deba@1979: class NodeIt : public Node { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: NodeIt() {} deba@1979: deba@1979: NodeIt(Invalid i) : Node(i) { } deba@1979: deba@1979: explicit NodeIt(const Graph& _graph) : graph(&_graph) { deba@2031: _graph.first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: NodeIt(const Graph& _graph, const Node& node) deba@1979: : Node(node), graph(&_graph) {} deba@1979: deba@1979: NodeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class EdgeIt : public Edge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: EdgeIt() { } deba@1979: deba@1979: EdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: explicit EdgeIt(const Graph& _graph) : graph(&_graph) { deba@2031: _graph.first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: EdgeIt(const Graph& _graph, const Edge& e) : deba@1979: Edge(e), graph(&_graph) { } deba@1979: deba@1979: EdgeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class OutEdgeIt : public Edge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: OutEdgeIt() { } deba@1979: deba@1979: OutEdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: OutEdgeIt(const Graph& _graph, const Node& node) deba@1979: : graph(&_graph) { deba@1979: _graph.firstOut(*this, node); deba@1979: } deba@1979: deba@1979: OutEdgeIt(const Graph& _graph, const Edge& edge) deba@1979: : Edge(edge), graph(&_graph) {} deba@1979: deba@1979: OutEdgeIt& operator++() { deba@1979: graph->nextOut(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class InEdgeIt : public Edge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: InEdgeIt() { } deba@1979: deba@1979: InEdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: InEdgeIt(const Graph& _graph, const Node& node) deba@1979: : graph(&_graph) { deba@1979: _graph.firstIn(*this, node); deba@1979: } deba@1979: deba@1979: InEdgeIt(const Graph& _graph, const Edge& edge) : deba@1979: Edge(edge), graph(&_graph) {} deba@1979: deba@1979: InEdgeIt& operator++() { deba@1979: graph->nextIn(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: /// \brief Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node (ie. the source in this case) of the iterator deba@1979: Node baseNode(const OutEdgeIt &e) const { deba@1979: return Parent::source(e); deba@1979: } deba@1979: /// \brief Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node (ie. the target in this case) of the deba@1979: /// iterator deba@1979: Node runningNode(const OutEdgeIt &e) const { deba@1979: return Parent::target(e); deba@1979: } deba@1979: deba@1979: /// \brief Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node (ie. the target in this case) of the iterator deba@1979: Node baseNode(const InEdgeIt &e) const { deba@1979: return Parent::target(e); deba@1979: } deba@1979: /// \brief Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node (ie. the source in this case) of the deba@1979: /// iterator deba@1979: Node runningNode(const InEdgeIt &e) const { deba@1979: return Parent::source(e); deba@1979: } deba@1979: deba@1979: deba@1979: template deba@1979: class NodeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef GraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: NodeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: NodeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: NodeMap& operator=(const NodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: NodeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: template deba@1979: class EdgeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef GraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: EdgeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: EdgeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: EdgeMap& operator=(const EdgeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: EdgeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: deba@1979: Node addNode() { deba@1979: Node node = Parent::addNode(); deba@1979: getNotifier(Node()).add(node); deba@1979: return node; deba@1979: } deba@1979: deba@1979: Edge addEdge(const Node& from, const Node& to) { deba@1979: Edge edge = Parent::addEdge(from, to); deba@1979: getNotifier(Edge()).add(edge); deba@1979: return edge; deba@1979: } deba@1979: deba@1979: void clear() { deba@1979: getNotifier(Edge()).clear(); deba@1979: getNotifier(Node()).clear(); deba@1979: Parent::clear(); deba@1979: } deba@1979: deba@1979: deba@1979: void erase(const Node& node) { deba@1979: Edge edge; deba@1979: Parent::firstOut(edge, node); deba@1979: while (edge != INVALID ) { deba@1979: erase(edge); deba@1979: Parent::firstOut(edge, node); deba@1979: } deba@1979: deba@1979: Parent::firstIn(edge, node); deba@1979: while (edge != INVALID ) { deba@1979: erase(edge); deba@1979: Parent::firstIn(edge, node); deba@1979: } deba@1979: deba@1979: getNotifier(Node()).erase(node); deba@1979: Parent::erase(node); deba@1979: } deba@1979: deba@1979: void erase(const Edge& edge) { deba@1979: getNotifier(Edge()).erase(edge); deba@1979: Parent::erase(edge); deba@1979: } deba@1979: deba@1999: GraphExtender() { deba@1999: node_notifier.setContainer(*this); deba@1999: edge_notifier.setContainer(*this); deba@1999: } deba@1999: deba@1979: deba@1979: ~GraphExtender() { deba@1999: edge_notifier.clear(); deba@1999: node_notifier.clear(); deba@1979: } deba@1979: }; deba@1979: deba@1996: /// \ingroup graphbits deba@1996: /// deba@1996: /// \brief Extender for the UGraphs deba@1979: template deba@1979: class UGraphExtender : public Base { deba@1979: public: deba@1979: deba@1979: typedef Base Parent; deba@1979: typedef UGraphExtender Graph; deba@1979: deba@1979: typedef typename Parent::Node Node; deba@1979: typedef typename Parent::Edge Edge; deba@1979: typedef typename Parent::UEdge UEdge; deba@1979: deba@1979: // UGraph extension deba@1979: deba@1979: int maxId(Node) const { deba@1979: return Parent::maxNodeId(); deba@1979: } deba@1979: deba@1979: int maxId(Edge) const { deba@1979: return Parent::maxEdgeId(); deba@1979: } deba@1979: deba@1979: int maxId(UEdge) const { deba@1979: return Parent::maxUEdgeId(); deba@1979: } deba@1979: deba@1979: Node fromId(int id, Node) const { deba@1979: return Parent::nodeFromId(id); deba@1979: } deba@1979: deba@1979: Edge fromId(int id, Edge) const { deba@1979: return Parent::edgeFromId(id); deba@1979: } deba@1979: deba@1979: UEdge fromId(int id, UEdge) const { deba@1979: return Parent::uEdgeFromId(id); deba@1979: } deba@1979: deba@1979: Node oppositeNode(const Node &n, const UEdge &e) const { deba@1979: if( n == Parent::source(e)) deba@1979: return Parent::target(e); deba@1979: else if( n == Parent::target(e)) deba@1979: return Parent::source(e); deba@1979: else deba@1979: return INVALID; deba@1979: } deba@1979: deba@1979: Edge oppositeEdge(const Edge &e) const { deba@1979: return Parent::direct(e, !Parent::direction(e)); deba@1979: } deba@1979: deba@1979: using Parent::direct; deba@1979: Edge direct(const UEdge &ue, const Node &s) const { deba@1979: return Parent::direct(ue, Parent::source(ue) == s); deba@1979: } deba@1979: deba@1979: // Alterable extension deba@1979: deba@1999: typedef AlterationNotifier NodeNotifier; deba@1999: typedef AlterationNotifier EdgeNotifier; deba@1999: typedef AlterationNotifier UEdgeNotifier; deba@1979: deba@1979: deba@1979: protected: deba@1979: deba@1979: mutable NodeNotifier node_notifier; deba@1979: mutable EdgeNotifier edge_notifier; deba@1979: mutable UEdgeNotifier uedge_notifier; deba@1979: deba@1979: public: deba@1979: deba@1979: NodeNotifier& getNotifier(Node) const { deba@1979: return node_notifier; deba@1979: } deba@1979: deba@1979: EdgeNotifier& getNotifier(Edge) const { deba@1979: return edge_notifier; deba@1979: } deba@1979: deba@1979: UEdgeNotifier& getNotifier(UEdge) const { deba@1979: return uedge_notifier; deba@1979: } deba@1979: deba@1979: deba@1979: deba@1979: class NodeIt : public Node { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: NodeIt() {} deba@1979: deba@1979: NodeIt(Invalid i) : Node(i) { } deba@1979: deba@1979: explicit NodeIt(const Graph& _graph) : graph(&_graph) { deba@2031: _graph.first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: NodeIt(const Graph& _graph, const Node& node) deba@1979: : Node(node), graph(&_graph) {} deba@1979: deba@1979: NodeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class EdgeIt : public Edge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: EdgeIt() { } deba@1979: deba@1979: EdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: explicit EdgeIt(const Graph& _graph) : graph(&_graph) { deba@2031: _graph.first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: EdgeIt(const Graph& _graph, const Edge& e) : deba@1979: Edge(e), graph(&_graph) { } deba@1979: deba@1979: EdgeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class OutEdgeIt : public Edge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: OutEdgeIt() { } deba@1979: deba@1979: OutEdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: OutEdgeIt(const Graph& _graph, const Node& node) deba@1979: : graph(&_graph) { deba@1979: _graph.firstOut(*this, node); deba@1979: } deba@1979: deba@1979: OutEdgeIt(const Graph& _graph, const Edge& edge) deba@1979: : Edge(edge), graph(&_graph) {} deba@1979: deba@1979: OutEdgeIt& operator++() { deba@1979: graph->nextOut(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class InEdgeIt : public Edge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: InEdgeIt() { } deba@1979: deba@1979: InEdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: InEdgeIt(const Graph& _graph, const Node& node) deba@1979: : graph(&_graph) { deba@1979: _graph.firstIn(*this, node); deba@1979: } deba@1979: deba@1979: InEdgeIt(const Graph& _graph, const Edge& edge) : deba@1979: Edge(edge), graph(&_graph) {} deba@1979: deba@1979: InEdgeIt& operator++() { deba@1979: graph->nextIn(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class UEdgeIt : public Parent::UEdge { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: UEdgeIt() { } deba@1979: deba@1979: UEdgeIt(Invalid i) : UEdge(i) { } deba@1979: deba@1979: explicit UEdgeIt(const Graph& _graph) : graph(&_graph) { deba@2031: _graph.first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: UEdgeIt(const Graph& _graph, const UEdge& e) : deba@1979: UEdge(e), graph(&_graph) { } deba@1979: deba@1979: UEdgeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: class IncEdgeIt : public Parent::UEdge { deba@1979: friend class UGraphExtender; deba@1979: const Graph* graph; deba@1979: bool direction; deba@1979: public: deba@1979: deba@1979: IncEdgeIt() { } deba@1979: deba@1979: IncEdgeIt(Invalid i) : UEdge(i), direction(false) { } deba@1979: deba@1979: IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { deba@1979: _graph.firstInc(*this, direction, n); deba@1979: } deba@1979: deba@1979: IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n) deba@1979: : graph(&_graph), UEdge(ue) { deba@1979: direction = (_graph.source(ue) == n); deba@1979: } deba@1979: deba@1979: IncEdgeIt& operator++() { deba@1979: graph->nextInc(*this, direction); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: /// \brief Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node (ie. the source in this case) of the iterator deba@1979: Node baseNode(const OutEdgeIt &e) const { deba@1979: return Parent::source((Edge)e); deba@1979: } deba@1979: /// \brief Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node (ie. the target in this case) of the deba@1979: /// iterator deba@1979: Node runningNode(const OutEdgeIt &e) const { deba@1979: return Parent::target((Edge)e); deba@1979: } deba@1979: deba@1979: /// \brief Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node (ie. the target in this case) of the iterator deba@1979: Node baseNode(const InEdgeIt &e) const { deba@1979: return Parent::target((Edge)e); deba@1979: } deba@1979: /// \brief Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node (ie. the source in this case) of the deba@1979: /// iterator deba@1979: Node runningNode(const InEdgeIt &e) const { deba@1979: return Parent::source((Edge)e); deba@1979: } deba@1979: deba@1979: /// Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node of the iterator deba@1979: Node baseNode(const IncEdgeIt &e) const { deba@1979: return e.direction ? source(e) : target(e); deba@1979: } deba@1979: /// Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node of the iterator deba@1979: Node runningNode(const IncEdgeIt &e) const { deba@1979: return e.direction ? target(e) : source(e); deba@1979: } deba@1979: deba@1979: // Mappable extension deba@1979: deba@1979: template deba@1979: class NodeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef UGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: NodeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: NodeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: NodeMap& operator=(const NodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: NodeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: template deba@1979: class EdgeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef UGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: EdgeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: EdgeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: EdgeMap& operator=(const EdgeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: EdgeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: deba@1979: template deba@1979: class UEdgeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef UGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: UEdgeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@2031: deba@1999: UEdgeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: UEdgeMap& operator=(const UEdgeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: UEdgeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@2031: deba@1979: }; deba@1979: deba@1979: // Alteration extension deba@1979: deba@1979: Node addNode() { deba@1979: Node node = Parent::addNode(); deba@1979: getNotifier(Node()).add(node); deba@1979: return node; deba@1979: } deba@1979: deba@1979: UEdge addEdge(const Node& from, const Node& to) { deba@1979: UEdge uedge = Parent::addEdge(from, to); deba@1979: getNotifier(UEdge()).add(uedge); deba@1979: getNotifier(Edge()).add(Parent::direct(uedge, true)); deba@1979: getNotifier(Edge()).add(Parent::direct(uedge, false)); deba@1979: return uedge; deba@1979: } deba@1979: deba@1979: void clear() { deba@1979: getNotifier(Edge()).clear(); deba@1979: getNotifier(UEdge()).clear(); deba@1979: getNotifier(Node()).clear(); deba@1979: Parent::clear(); deba@1979: } deba@1979: deba@1979: void erase(const Node& node) { deba@1979: Edge edge; deba@1979: Parent::firstOut(edge, node); deba@1979: while (edge != INVALID ) { deba@1979: erase(edge); deba@1979: Parent::firstOut(edge, node); deba@1979: } deba@1979: deba@1979: Parent::firstIn(edge, node); deba@1979: while (edge != INVALID ) { deba@1979: erase(edge); deba@1979: Parent::firstIn(edge, node); deba@1979: } deba@1979: deba@1979: getNotifier(Node()).erase(node); deba@1979: Parent::erase(node); deba@1979: } deba@1979: deba@1979: void erase(const UEdge& uedge) { deba@1979: getNotifier(Edge()).erase(Parent::direct(uedge, true)); deba@1979: getNotifier(Edge()).erase(Parent::direct(uedge, false)); deba@1979: getNotifier(UEdge()).erase(uedge); deba@1979: Parent::erase(uedge); deba@1979: } deba@1979: deba@1999: UGraphExtender() { deba@1999: node_notifier.setContainer(*this); deba@1999: edge_notifier.setContainer(*this); deba@1999: uedge_notifier.setContainer(*this); deba@1999: } deba@1999: deba@1979: ~UGraphExtender() { deba@1999: uedge_notifier.clear(); deba@1999: edge_notifier.clear(); deba@1999: node_notifier.clear(); deba@1999: } deba@1791: deba@1791: }; deba@1791: deba@1996: /// \ingroup graphbits deba@1996: /// deba@1996: /// \brief Extender for the BpUGraphs deba@1979: template deba@1979: class BpUGraphExtender : public Base { deba@1979: public: deba@1979: typedef Base Parent; deba@1979: typedef BpUGraphExtender Graph; deba@1979: deba@1979: typedef typename Parent::Node Node; deba@1979: typedef typename Parent::BNode BNode; deba@1979: typedef typename Parent::ANode ANode; deba@1979: typedef typename Parent::Edge Edge; deba@1979: typedef typename Parent::UEdge UEdge; deba@1979: deba@1979: Node oppositeNode(const UEdge& edge, const Node& node) const { deba@1979: return source(edge) == node ? deba@1979: target(edge) : source(edge); deba@1820: } deba@1820: deba@1979: using Parent::direct; deba@1979: Edge direct(const UEdge& edge, const Node& node) const { deba@1979: return Edge(edge, node == Parent::source(edge)); deba@1820: } deba@1820: deba@1979: Edge oppositeEdge(const Edge& edge) const { deba@1979: return Parent::direct(edge, !Parent::direction(edge)); deba@1979: } deba@1820: deba@1820: deba@1820: int maxId(Node) const { deba@1820: return Parent::maxNodeId(); deba@1820: } deba@1910: int maxId(BNode) const { deba@1910: return Parent::maxBNodeId(); deba@1820: } deba@1910: int maxId(ANode) const { deba@1910: return Parent::maxANodeId(); deba@1820: } deba@1820: int maxId(Edge) const { deba@1979: return Parent::maxEdgeId(); deba@1820: } klao@1909: int maxId(UEdge) const { deba@1979: return Parent::maxUEdgeId(); deba@1820: } deba@1820: deba@1820: deba@1820: Node fromId(int id, Node) const { deba@1820: return Parent::nodeFromId(id); deba@1820: } deba@1910: ANode fromId(int id, ANode) const { deba@1910: return Parent::fromANodeId(id); deba@1820: } deba@1910: BNode fromId(int id, BNode) const { deba@1910: return Parent::fromBNodeId(id); deba@1820: } deba@1820: Edge fromId(int id, Edge) const { deba@1979: return Parent::edgeFromId(id); deba@1820: } klao@1909: UEdge fromId(int id, UEdge) const { deba@1979: return Parent::uEdgeFromId(id); deba@1979: } deba@1979: deba@1999: typedef AlterationNotifier ANodeNotifier; deba@1999: typedef AlterationNotifier BNodeNotifier; deba@1999: typedef AlterationNotifier NodeNotifier; deba@1999: typedef AlterationNotifier EdgeNotifier; deba@1999: typedef AlterationNotifier UEdgeNotifier; deba@1979: deba@1979: protected: deba@1979: deba@1999: mutable ANodeNotifier anode_notifier; deba@1999: mutable BNodeNotifier bnode_notifier; deba@1999: mutable NodeNotifier node_notifier; deba@1999: mutable EdgeNotifier edge_notifier; deba@1999: mutable UEdgeNotifier uedge_notifier; deba@1979: deba@1979: public: deba@1979: deba@1979: NodeNotifier& getNotifier(Node) const { deba@1999: return node_notifier; deba@1999: } deba@1999: deba@1999: ANodeNotifier& getNotifier(ANode) const { deba@1999: return anode_notifier; deba@1820: } deba@1820: deba@1979: BNodeNotifier& getNotifier(BNode) const { deba@1999: return bnode_notifier; deba@1979: } deba@1979: deba@1979: EdgeNotifier& getNotifier(Edge) const { deba@1999: return edge_notifier; deba@1979: } deba@1979: deba@1979: UEdgeNotifier& getNotifier(UEdge) const { deba@1999: return uedge_notifier; deba@1979: } deba@1979: deba@1979: class NodeIt : public Node { deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: NodeIt() { } deba@1979: deba@1979: NodeIt(Invalid i) : Node(INVALID) { } deba@1979: deba@1979: explicit NodeIt(const Graph& _graph) : graph(&_graph) { deba@1979: graph->first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: NodeIt(const Graph& _graph, const Node& node) deba@1979: : Node(node), graph(&_graph) { } deba@1979: deba@1979: NodeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: class ANodeIt : public Node { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: ANodeIt() { } deba@1979: deba@1979: ANodeIt(Invalid i) : Node(INVALID) { } deba@1979: deba@1979: explicit ANodeIt(const Graph& _graph) : graph(&_graph) { deba@1979: graph->firstANode(static_cast(*this)); deba@1979: } deba@1979: deba@1979: ANodeIt(const Graph& _graph, const Node& node) deba@1979: : Node(node), graph(&_graph) {} deba@1979: deba@1979: ANodeIt& operator++() { deba@1979: graph->nextANode(*this); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: class BNodeIt : public Node { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: BNodeIt() { } deba@1979: deba@1979: BNodeIt(Invalid i) : Node(INVALID) { } deba@1979: deba@1979: explicit BNodeIt(const Graph& _graph) : graph(&_graph) { deba@1979: graph->firstBNode(static_cast(*this)); deba@1979: } deba@1979: deba@1979: BNodeIt(const Graph& _graph, const Node& node) deba@1979: : Node(node), graph(&_graph) {} deba@1979: deba@1979: BNodeIt& operator++() { deba@1979: graph->nextBNode(*this); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: class EdgeIt : public Edge { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: EdgeIt() { } deba@1979: deba@1979: EdgeIt(Invalid i) : Edge(INVALID) { } deba@1979: deba@1979: explicit EdgeIt(const Graph& _graph) : graph(&_graph) { deba@1979: graph->first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: EdgeIt(const Graph& _graph, const Edge& edge) deba@1979: : Edge(edge), graph(&_graph) { } deba@1979: deba@1979: EdgeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: class UEdgeIt : public UEdge { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: UEdgeIt() { } deba@1979: deba@1979: UEdgeIt(Invalid i) : UEdge(INVALID) { } deba@1979: deba@1979: explicit UEdgeIt(const Graph& _graph) : graph(&_graph) { deba@1979: graph->first(static_cast(*this)); deba@1979: } deba@1979: deba@1979: UEdgeIt(const Graph& _graph, const UEdge& edge) deba@1979: : UEdge(edge), graph(&_graph) { } deba@1979: deba@1979: UEdgeIt& operator++() { deba@1979: graph->next(*this); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: class OutEdgeIt : public Edge { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: OutEdgeIt() { } deba@1979: deba@1979: OutEdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: OutEdgeIt(const Graph& _graph, const Node& node) deba@1979: : graph(&_graph) { deba@1979: graph->firstOut(*this, node); deba@1979: } deba@1979: deba@1979: OutEdgeIt(const Graph& _graph, const Edge& edge) deba@1979: : Edge(edge), graph(&_graph) {} deba@1979: deba@1979: OutEdgeIt& operator++() { deba@1979: graph->nextOut(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: class InEdgeIt : public Edge { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: public: deba@1979: deba@1979: InEdgeIt() { } deba@1979: deba@1979: InEdgeIt(Invalid i) : Edge(i) { } deba@1979: deba@1979: InEdgeIt(const Graph& _graph, const Node& node) deba@1979: : graph(&_graph) { deba@1979: graph->firstIn(*this, node); deba@1979: } deba@1979: deba@1979: InEdgeIt(const Graph& _graph, const Edge& edge) : deba@1979: Edge(edge), graph(&_graph) {} deba@1979: deba@1979: InEdgeIt& operator++() { deba@1979: graph->nextIn(*this); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: /// \brief Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node (ie. the source in this case) of the iterator deba@1979: Node baseNode(const OutEdgeIt &e) const { deba@1979: return Parent::source((Edge&)e); deba@1979: } deba@1979: /// \brief Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node (ie. the target in this case) of the deba@1979: /// iterator deba@1979: Node runningNode(const OutEdgeIt &e) const { deba@1979: return Parent::target((Edge&)e); deba@1979: } deba@1979: deba@1979: /// \brief Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node (ie. the target in this case) of the iterator deba@1979: Node baseNode(const InEdgeIt &e) const { deba@1979: return Parent::target((Edge&)e); deba@1979: } deba@1979: /// \brief Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node (ie. the source in this case) of the deba@1979: /// iterator deba@1979: Node runningNode(const InEdgeIt &e) const { deba@1979: return Parent::source((Edge&)e); deba@1979: } deba@1979: deba@1979: class IncEdgeIt : public Parent::UEdge { deba@1979: friend class BpUGraphExtender; deba@1979: const Graph* graph; deba@1979: bool direction; deba@1979: public: deba@1979: deba@1979: IncEdgeIt() { } deba@1979: deba@1979: IncEdgeIt(Invalid i) : UEdge(i), direction(true) { } deba@1979: deba@1979: IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { deba@1979: graph->firstInc(*this, direction, n); deba@1979: } deba@1979: deba@1979: IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n) deba@1979: : graph(&_graph), UEdge(ue) { deba@1979: direction = (graph->source(ue) == n); deba@1979: } deba@1979: deba@1979: IncEdgeIt& operator++() { deba@1979: graph->nextInc(*this, direction); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: deba@1979: /// Base node of the iterator deba@1979: /// deba@1979: /// Returns the base node of the iterator deba@1979: Node baseNode(const IncEdgeIt &e) const { deba@1979: return e.direction ? source(e) : target(e); deba@1979: } deba@1979: deba@1979: /// Running node of the iterator deba@1979: /// deba@1979: /// Returns the running node of the iterator deba@1979: Node runningNode(const IncEdgeIt &e) const { deba@1979: return e.direction ? target(e) : source(e); deba@1979: } deba@1979: deba@1979: template deba@1979: class ANodeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: ANodeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: ANodeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: ANodeMap& operator=(const ANodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: ANodeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: template deba@1979: class BNodeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: BNodeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: BNodeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: BNodeMap& operator=(const BNodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: BNodeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@2031: public: deba@1979: deba@1979: template deba@2031: class NodeMap { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1979: deba@1979: typedef Node Key; deba@1979: typedef _Value Value; deba@1979: deba@1979: /// The reference type of the map; deba@1999: typedef typename ANodeMap<_Value>::Reference Reference; deba@1979: /// The const reference type of the map; deba@1999: typedef typename ANodeMap<_Value>::ConstReference ConstReference; deba@1979: deba@1979: typedef True ReferenceMapTag; deba@1979: deba@2031: NodeMap(const Graph& _graph) deba@2031: : graph(_graph), aNodeMap(_graph), bNodeMap(_graph) {} deba@2031: NodeMap(const Graph& _graph, const _Value& _value) deba@2031: : graph(_graph), aNodeMap(_graph, _value), bNodeMap(_graph, _value) {} deba@2031: deba@2031: NodeMap& operator=(const NodeMap& cmap) { deba@2031: return operator=(cmap); deba@2031: } deba@2031: deba@2031: template deba@2031: NodeMap& operator=(const CMap& cmap) { deba@2031: checkConcept, CMap>(); deba@2031: const typename Parent::Notifier* notifier = Parent::getNotifier(); deba@2031: Edge it; deba@2031: for (graph.first(it); it != INVALID; graph.next(it)) { deba@2031: Parent::set(it, cmap[it]); deba@2031: } deba@2031: return *this; deba@2031: } deba@1979: deba@1979: ConstReference operator[](const Key& node) const { deba@1979: if (Parent::aNode(node)) { deba@1979: return aNodeMap[node]; deba@1979: } else { deba@1979: return bNodeMap[node]; deba@1979: } deba@1979: } deba@1979: deba@1979: Reference operator[](const Key& node) { deba@1979: if (Parent::aNode(node)) { deba@1979: return aNodeMap[node]; deba@1979: } else { deba@1979: return bNodeMap[node]; deba@1979: } deba@1979: } deba@1979: deba@1979: void set(const Key& node, const Value& value) { deba@1979: if (Parent::aNode(node)) { deba@1979: aNodeMap.set(node, value); deba@1979: } else { deba@1979: bNodeMap.set(node, value); deba@1979: } deba@1979: } deba@1979: deba@2031: class MapIt : public NodeIt { deba@2031: public: deba@1979: deba@2031: typedef NodeIt Parent; deba@2031: deba@2031: explicit MapIt(NodeMap& _map) deba@2031: : Parent(_map.graph), map(_map) {} deba@2031: deba@2031: typename MapTraits::ConstReturnValue operator*() const { deba@2031: return map[*this]; deba@2031: } deba@2031: deba@2031: typename MapTraits::ReturnValue operator*() { deba@2031: return map[*this]; deba@2031: } deba@2031: deba@2031: void set(const Value& value) { deba@2031: map.set(*this, value); deba@2031: } deba@2031: deba@2031: private: deba@2031: NodeMap& map; deba@2031: }; deba@2031: deba@2031: class ConstMapIt : public NodeIt { deba@2031: public: deba@2031: deba@2031: typedef NodeIt Parent; deba@2031: deba@2031: explicit ConstMapIt(const NodeMap& _map) deba@2031: : Parent(_map.graph), map(_map) {} deba@2031: deba@2031: typename MapTraits::ConstReturnValue operator*() const { deba@2031: return map[*this]; deba@2031: } deba@2031: deba@2031: private: deba@2031: const NodeMap& map; deba@2031: }; deba@2031: deba@2031: class ItemIt : public NodeIt { deba@2031: public: deba@2031: deba@2031: typedef NodeIt Parent; deba@2031: deba@2031: explicit ItemIt(const NodeMap& _map) deba@2031: : Parent(_map.graph) {} deba@2031: deba@2031: }; deba@2031: deba@1979: private: deba@2031: const Graph& graph; deba@1991: ANodeMap<_Value> aNodeMap; deba@1979: BNodeMap<_Value> bNodeMap; deba@1979: }; deba@1979: deba@1979: deba@1979: template deba@1979: class EdgeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: EdgeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: EdgeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: EdgeMap& operator=(const EdgeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: EdgeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: template deba@1979: class UEdgeMap deba@1999: : public MapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1999: typedef MapExtender > Parent; deba@1979: deba@1999: UEdgeMap(const Graph& graph) deba@1999: : Parent(graph) {} deba@1999: UEdgeMap(const Graph& graph, const _Value& value) deba@1999: : Parent(graph, value) {} deba@1979: deba@1979: UEdgeMap& operator=(const UEdgeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: template deba@1979: UEdgeMap& operator=(const CMap& cmap) { deba@2031: Parent::operator=(cmap); deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: deba@1979: Node addANode() { deba@1979: Node node = Parent::addANode(); deba@1979: getNotifier(ANode()).add(node); deba@1979: getNotifier(Node()).add(node); deba@1979: return node; deba@1979: } deba@1979: deba@1979: Node addBNode() { deba@1979: Node node = Parent::addBNode(); deba@1979: getNotifier(BNode()).add(node); deba@1979: getNotifier(Node()).add(node); deba@1979: return node; deba@1979: } deba@1979: deba@1979: UEdge addEdge(const Node& source, const Node& target) { deba@1979: UEdge uedge = Parent::addEdge(source, target); deba@1979: getNotifier(UEdge()).add(uedge); deba@1979: deba@1979: std::vector edges; deba@1979: edges.push_back(direct(uedge, true)); deba@1979: edges.push_back(direct(uedge, false)); deba@1979: getNotifier(Edge()).add(edges); deba@1979: deba@1979: return uedge; deba@1979: } deba@1979: deba@1979: void clear() { deba@1979: getNotifier(Edge()).clear(); deba@1979: getNotifier(UEdge()).clear(); deba@1979: getNotifier(Node()).clear(); deba@1979: getNotifier(BNode()).clear(); deba@1979: getNotifier(ANode()).clear(); deba@1979: Parent::clear(); deba@1979: } deba@1979: deba@1979: void erase(const Node& node) { deba@1979: UEdge uedge; deba@1979: bool dir; deba@1979: Parent::firstInc(uedge, dir, node); deba@1979: while (uedge != INVALID ) { deba@1979: erase(uedge); deba@1979: Parent::firstInc(uedge, dir, node); deba@1979: } deba@1979: deba@1979: getNotifier(Node()).erase(node); deba@1979: Parent::erase(node); deba@1979: } deba@1979: deba@1979: void erase(const UEdge& uedge) { deba@1979: std::vector edges; deba@1979: edges.push_back(direct(uedge, true)); deba@1979: edges.push_back(direct(uedge, false)); deba@1979: getNotifier(Edge()).erase(edges); deba@1979: getNotifier(UEdge()).erase(uedge); deba@1979: Parent::erase(uedge); deba@1979: } deba@1979: deba@1979: deba@1999: BpUGraphExtender() { deba@1999: anode_notifier.setContainer(*this); deba@1999: bnode_notifier.setContainer(*this); deba@1999: node_notifier.setContainer(*this); deba@1999: edge_notifier.setContainer(*this); deba@1999: uedge_notifier.setContainer(*this); deba@1999: } deba@1999: deba@1979: ~BpUGraphExtender() { deba@1999: uedge_notifier.clear(); deba@1999: edge_notifier.clear(); deba@1999: node_notifier.clear(); deba@1999: anode_notifier.clear(); deba@1999: bnode_notifier.clear(); deba@1979: } deba@1979: deba@1979: deba@1820: }; deba@1820: deba@1791: } deba@1791: deba@1996: #endif