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@1791: #ifndef LEMON_GRAPH_EXTENDER_H deba@1791: #define LEMON_GRAPH_EXTENDER_H deba@1791: deba@1791: #include deba@1820: #include deba@1791: deba@1979: #include deba@1979: deba@1791: namespace lemon { deba@1791: 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@1979: typedef AlterationNotifier NodeNotifier; deba@1979: 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@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: 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@1979: _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@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef GraphExtender Graph; deba@1979: typedef IterableMapExtender > Parent; deba@1979: deba@1979: NodeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: NodeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} deba@1979: deba@1979: NodeMap& operator=(const NodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: deba@1979: /// \brief Template assign operator. deba@1979: /// deba@1979: /// The given parameter should be conform to the ReadMap deba@1979: /// concecpt and could be indiced by the current item set of deba@1979: /// the NodeMap. In this case the value for each item deba@1979: /// is assigned by the value of the given ReadMap. deba@1979: template deba@1979: NodeMap& operator=(const CMap& cmap) { deba@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: Node it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: template deba@1979: class EdgeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef GraphExtender Graph; deba@1979: typedef IterableMapExtender > Parent; deba@1979: deba@1979: EdgeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: EdgeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} 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@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: Edge it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } 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@1979: deba@1979: ~GraphExtender() { deba@1979: getNotifier(Edge()).clear(); deba@1979: getNotifier(Node()).clear(); deba@1979: } deba@1979: }; deba@1979: deba@1979: template deba@1979: class UGraphBaseExtender : public Base { deba@1979: deba@1979: public: deba@1979: deba@1979: typedef Base Parent; klao@1909: typedef typename Parent::Edge UEdge; deba@1791: typedef typename Parent::Node Node; deba@1791: deba@1979: typedef True UndirectedTag; deba@1979: klao@1909: class Edge : public UEdge { deba@1979: friend class UGraphBaseExtender; deba@1791: deba@1791: protected: deba@1791: bool forward; deba@1791: klao@1909: Edge(const UEdge &ue, bool _forward) : klao@1909: UEdge(ue), forward(_forward) {} deba@1791: deba@1791: public: deba@1791: Edge() {} deba@1791: deba@1791: /// Invalid edge constructor klao@1909: Edge(Invalid i) : UEdge(i), forward(true) {} deba@1791: deba@1791: bool operator==(const Edge &that) const { klao@1909: return forward==that.forward && UEdge(*this)==UEdge(that); deba@1791: } deba@1791: bool operator!=(const Edge &that) const { klao@1909: return forward!=that.forward || UEdge(*this)!=UEdge(that); deba@1791: } deba@1791: bool operator<(const Edge &that) const { deba@1791: return forward> 1), bool(id & 1)); deba@1979: } deba@1791: deba@1979: UEdge uEdgeFromId(int id) const { deba@1979: return Parent::edgeFromId(id >> 1); deba@1979: } deba@1791: deba@1791: int id(const Node &n) const { deba@1791: return Parent::id(n); deba@1791: } deba@1791: klao@1909: int id(const UEdge &e) const { deba@1791: return Parent::id(e); deba@1791: } deba@1791: deba@1791: int id(const Edge &e) const { deba@1791: return 2 * Parent::id(e) + int(e.forward); deba@1791: } deba@1791: deba@1791: int maxNodeId() const { deba@1791: return Parent::maxNodeId(); deba@1791: } deba@1791: deba@1791: int maxEdgeId() const { deba@1791: return 2 * Parent::maxEdgeId() + 1; deba@1791: } deba@1791: klao@1909: int maxUEdgeId() const { deba@1791: return Parent::maxEdgeId(); deba@1791: } deba@1791: deba@1791: deba@1791: int edgeNum() const { deba@1791: return 2 * Parent::edgeNum(); deba@1791: } deba@1791: klao@1909: int uEdgeNum() const { deba@1791: return Parent::edgeNum(); deba@1791: } deba@1791: deba@1791: Edge findEdge(Node source, Node target, Edge prev) const { deba@1791: if (prev == INVALID) { klao@1909: UEdge edge = Parent::findEdge(source, target); deba@1791: if (edge != INVALID) return direct(edge, true); deba@1791: edge = Parent::findEdge(target, source); deba@1791: if (edge != INVALID) return direct(edge, false); deba@1791: } else if (direction(prev)) { klao@1909: UEdge edge = Parent::findEdge(source, target, prev); deba@1791: if (edge != INVALID) return direct(edge, true); deba@1791: edge = Parent::findEdge(target, source); deba@1791: if (edge != INVALID) return direct(edge, false); deba@1791: } else { klao@1909: UEdge edge = Parent::findEdge(target, source, prev); deba@1791: if (edge != INVALID) return direct(edge, false); deba@1791: } deba@1791: return INVALID; deba@1791: } deba@1791: klao@1909: UEdge findUEdge(Node source, Node target, UEdge prev) const { deba@1791: if (prev == INVALID) { klao@1909: UEdge edge = Parent::findEdge(source, target); deba@1791: if (edge != INVALID) return edge; deba@1791: edge = Parent::findEdge(target, source); deba@1791: if (edge != INVALID) return edge; deba@1791: } else if (Parent::source(prev) == source) { klao@1909: UEdge edge = Parent::findEdge(source, target, prev); deba@1791: if (edge != INVALID) return edge; deba@1791: edge = Parent::findEdge(target, source); deba@1791: if (edge != INVALID) return edge; deba@1791: } else { klao@1909: UEdge edge = Parent::findEdge(target, source, prev); deba@1791: if (edge != INVALID) return edge; deba@1791: } deba@1791: return INVALID; deba@1791: } deba@1979: }; deba@1979: deba@1979: 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@1979: typedef AlterationNotifier NodeNotifier; deba@1979: typedef AlterationNotifier EdgeNotifier; deba@1979: 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@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: 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@1979: _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@1979: _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@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef UGraphExtender Graph; deba@1979: typedef IterableMapExtender > Parent; deba@1979: deba@1979: NodeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: NodeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} deba@1979: deba@1979: NodeMap& operator=(const NodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: deba@1979: /// \brief Template assign operator. deba@1979: /// deba@1979: /// The given parameter should be conform to the ReadMap deba@1979: /// concecpt and could be indiced by the current item set of deba@1979: /// the NodeMap. In this case the value for each item deba@1979: /// is assigned by the value of the given ReadMap. deba@1979: template deba@1979: NodeMap& operator=(const CMap& cmap) { deba@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: Node it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: template deba@1979: class EdgeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef UGraphExtender Graph; deba@1979: typedef IterableMapExtender > Parent; deba@1979: deba@1979: EdgeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: EdgeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} 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@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: Edge it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: deba@1979: template deba@1979: class UEdgeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef UGraphExtender Graph; deba@1979: typedef IterableMapExtender > Parent; deba@1979: deba@1979: UEdgeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: UEdgeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} 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@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: UEdge it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } 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@1979: ~UGraphExtender() { deba@1979: getNotifier(Edge()).clear(); deba@1979: getNotifier(UEdge()).clear(); deba@1979: getNotifier(Node()).clear(); deba@1979: } deba@1791: deba@1791: }; deba@1791: deba@1820: deba@1979: template deba@1979: class BpUGraphBaseExtender : public Base { deba@1820: public: deba@1979: typedef Base Parent; deba@1979: typedef BpUGraphBaseExtender Graph; deba@1820: deba@1820: typedef typename Parent::Node Node; klao@1909: typedef typename Parent::Edge UEdge; deba@1820: deba@1979: deba@1820: using Parent::first; deba@1820: using Parent::next; deba@1820: deba@1820: using Parent::id; deba@1820: deba@1979: class ANode : public Node { deba@1979: friend class BpUGraphBaseExtender; deba@1979: public: deba@1979: ANode() {} deba@1979: ANode(const Node& node) : Node(node) { deba@1979: LEMON_ASSERT(Parent::aNode(node) || node == INVALID, deba@1979: typename Parent::NodeSetError()); deba@1979: } deba@1979: ANode(Invalid) : Node(INVALID) {} deba@1979: }; deba@1979: deba@1979: void first(ANode& node) const { deba@1979: Parent::firstANode(static_cast(node)); deba@1979: } deba@1979: void next(ANode& node) const { deba@1979: Parent::nextANode(static_cast(node)); deba@1979: } deba@1979: deba@1979: int id(const ANode& node) const { deba@1979: return Parent::aNodeId(node); deba@1979: } deba@1979: deba@1979: class BNode : public Node { deba@1979: friend class BpUGraphBaseExtender; deba@1979: public: deba@1979: BNode() {} deba@1979: BNode(const Node& node) : Node(node) { deba@1979: LEMON_ASSERT(Parent::bNode(node) || node == INVALID, deba@1979: typename Parent::NodeSetError()); deba@1979: } deba@1979: BNode(Invalid) : Node(INVALID) {} deba@1979: }; deba@1979: deba@1979: void first(BNode& node) const { deba@1979: Parent::firstBNode(static_cast(node)); deba@1979: } deba@1979: void next(BNode& node) const { deba@1979: Parent::nextBNode(static_cast(node)); deba@1979: } deba@1979: deba@1979: int id(const BNode& node) const { deba@1979: return Parent::aNodeId(node); deba@1979: } deba@1979: klao@1909: Node source(const UEdge& edge) const { deba@1910: return aNode(edge); deba@1820: } klao@1909: Node target(const UEdge& edge) const { deba@1910: return bNode(edge); deba@1820: } deba@1820: klao@1909: void firstInc(UEdge& edge, bool& direction, const Node& node) const { deba@1910: if (Parent::aNode(node)) { deba@1910: Parent::firstOut(edge, node); deba@1820: direction = true; deba@1820: } else { deba@1910: Parent::firstIn(edge, node); klao@1909: direction = static_cast(edge) == INVALID; deba@1820: } deba@1820: } klao@1909: void nextInc(UEdge& edge, bool& direction) const { deba@1820: if (direction) { deba@1910: Parent::nextOut(edge); deba@1820: } else { deba@1910: Parent::nextIn(edge); deba@1820: if (edge == INVALID) direction = true; deba@1820: } deba@1820: } deba@1820: klao@1909: int maxUEdgeId() const { deba@1820: return Parent::maxEdgeId(); deba@1820: } deba@1820: klao@1909: UEdge uEdgeFromId(int id) const { deba@1820: return Parent::edgeFromId(id); deba@1820: } deba@1820: klao@1909: class Edge : public UEdge { deba@1979: friend class BpUGraphBaseExtender; deba@1820: protected: deba@1820: bool forward; deba@1820: klao@1909: Edge(const UEdge& edge, bool _forward) klao@1909: : UEdge(edge), forward(_forward) {} deba@1820: deba@1820: public: deba@1820: Edge() {} klao@1909: Edge (Invalid) : UEdge(INVALID), forward(true) {} deba@1820: bool operator==(const Edge& i) const { klao@1909: return UEdge::operator==(i) && forward == i.forward; deba@1820: } deba@1820: bool operator!=(const Edge& i) const { klao@1909: return UEdge::operator!=(i) || forward != i.forward; deba@1820: } deba@1820: bool operator<(const Edge& i) const { klao@1909: return UEdge::operator<(i) || klao@1909: (!(i.forward(edge)); deba@1820: edge.forward = true; deba@1820: } deba@1820: deba@1820: void next(Edge& edge) const { deba@1820: if (!edge.forward) { klao@1909: Parent::next(static_cast(edge)); deba@1820: } deba@1820: edge.forward = !edge.forward; deba@1820: } deba@1820: deba@1820: void firstOut(Edge& edge, const Node& node) const { deba@1910: if (Parent::aNode(node)) { deba@1910: Parent::firstOut(edge, node); deba@1820: edge.forward = true; deba@1820: } else { deba@1910: Parent::firstIn(edge, node); klao@1909: edge.forward = static_cast(edge) == INVALID; deba@1820: } deba@1820: } deba@1820: void nextOut(Edge& edge) const { deba@1820: if (edge.forward) { deba@1910: Parent::nextOut(edge); deba@1820: } else { deba@1910: Parent::nextIn(edge); klao@1909: edge.forward = static_cast(edge) == INVALID; deba@1820: } deba@1820: } deba@1820: deba@1820: void firstIn(Edge& edge, const Node& node) const { deba@1910: if (Parent::bNode(node)) { deba@1910: Parent::firstIn(edge, node); deba@1820: edge.forward = true; deba@1820: } else { deba@1910: Parent::firstOut(edge, node); klao@1909: edge.forward = static_cast(edge) == INVALID; deba@1820: } deba@1820: } deba@1820: void nextIn(Edge& edge) const { deba@1820: if (edge.forward) { deba@1910: Parent::nextIn(edge); deba@1820: } else { deba@1910: Parent::nextOut(edge); klao@1909: edge.forward = static_cast(edge) == INVALID; deba@1820: } deba@1820: } deba@1820: deba@1820: Node source(const Edge& edge) const { deba@1910: return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge); deba@1820: } deba@1820: Node target(const Edge& edge) const { deba@1910: return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge); deba@1820: } deba@1820: deba@1820: int id(const Edge& edge) const { deba@1820: return (Parent::id(edge) << 1) + (edge.forward ? 0 : 1); deba@1820: } deba@1820: Edge edgeFromId(int id) const { klao@1909: return Edge(Parent::fromId(id >> 1, UEdge()), (id & 1) == 0); deba@1820: } deba@1820: int maxEdgeId() const { klao@1909: return (Parent::maxId(UEdge()) << 1) + 1; deba@1820: } deba@1820: deba@1979: bool direction(const Edge& edge) const { deba@1979: return edge.forward; deba@1820: } deba@1820: deba@1979: Edge direct(const UEdge& edge, bool direction) const { deba@1979: return Edge(edge, direction); deba@1979: } deba@1979: }; deba@1979: 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@1979: typedef AlterationNotifier NodeNotifier; deba@1979: typedef AlterationNotifier BNodeNotifier; deba@1979: typedef AlterationNotifier ANodeNotifier; deba@1979: typedef AlterationNotifier EdgeNotifier; deba@1979: typedef AlterationNotifier UEdgeNotifier; deba@1979: deba@1979: protected: deba@1979: deba@1979: mutable NodeNotifier nodeNotifier; deba@1979: mutable BNodeNotifier bNodeNotifier; deba@1979: mutable ANodeNotifier aNodeNotifier; deba@1979: mutable EdgeNotifier edgeNotifier; deba@1979: mutable UEdgeNotifier uEdgeNotifier; deba@1979: deba@1979: public: deba@1979: deba@1979: NodeNotifier& getNotifier(Node) const { deba@1979: return nodeNotifier; deba@1820: } deba@1820: deba@1979: BNodeNotifier& getNotifier(BNode) const { deba@1979: return bNodeNotifier; deba@1979: } deba@1979: deba@1979: ANodeNotifier& getNotifier(ANode) const { deba@1979: return aNodeNotifier; deba@1979: } deba@1979: deba@1979: EdgeNotifier& getNotifier(Edge) const { deba@1979: return edgeNotifier; deba@1979: } deba@1979: deba@1979: UEdgeNotifier& getNotifier(UEdge) const { deba@1979: return uEdgeNotifier; 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@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1979: typedef IterableMapExtender > deba@1979: Parent; deba@1979: deba@1979: ANodeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: ANodeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} deba@1979: deba@1979: ANodeMap& operator=(const ANodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: deba@1979: /// \brief Template assign operator. deba@1979: /// deba@1979: /// The given parameter should be conform to the ReadMap deba@1979: /// concept and could be indiced by the current item set of deba@1979: /// the ANodeMap. In this case the value for each item deba@1979: /// is assigned by the value of the given ReadMap. deba@1979: template deba@1979: ANodeMap& operator=(const CMap& cmap) { deba@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: ANode it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: template deba@1979: class BNodeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1979: typedef IterableMapExtender > deba@1979: Parent; deba@1979: deba@1979: BNodeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: BNodeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} deba@1979: deba@1979: BNodeMap& operator=(const BNodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: deba@1979: /// \brief Template assign operator. deba@1979: /// deba@1979: /// The given parameter should be conform to the ReadMap deba@1979: /// concept and could be indiced by the current item set of deba@1979: /// the BNodeMap. In this case the value for each item deba@1979: /// is assigned by the value of the given ReadMap. deba@1979: template deba@1979: BNodeMap& operator=(const CMap& cmap) { deba@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: BNode it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: protected: deba@1979: deba@1979: template deba@1979: class NodeMapBase : public NodeNotifier::ObserverBase { 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@1979: typedef typename BNodeMap<_Value>::Reference Reference; deba@1979: /// The pointer type of the map; deba@1979: typedef typename BNodeMap<_Value>::Pointer Pointer; deba@1979: deba@1979: /// The const value type of the map. deba@1979: typedef const Value ConstValue; deba@1979: /// The const reference type of the map; deba@1979: typedef typename BNodeMap<_Value>::ConstReference ConstReference; deba@1979: /// The pointer type of the map; deba@1979: typedef typename BNodeMap<_Value>::ConstPointer ConstPointer; deba@1979: deba@1979: typedef True ReferenceMapTag; deba@1979: deba@1979: NodeMapBase(const Graph& _g) deba@1979: : graph(&_g), bNodeMap(_g), aNodeMap(_g) { deba@1979: NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); deba@1979: } deba@1979: NodeMapBase(const Graph& _g, const _Value& _v) deba@1979: : graph(&_g), bNodeMap(_g, _v), deba@1979: aNodeMap(_g, _v) { deba@1979: NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); deba@1979: } deba@1979: deba@1979: virtual ~NodeMapBase() { deba@1979: if (NodeNotifier::ObserverBase::attached()) { deba@1979: NodeNotifier::ObserverBase::detach(); deba@1979: } deba@1979: } 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@1979: protected: deba@1979: deba@1979: virtual void add(const Node&) {} deba@1979: virtual void add(const std::vector&) {} deba@1979: virtual void erase(const Node&) {} deba@1979: virtual void erase(const std::vector&) {} deba@1979: virtual void clear() {} deba@1979: virtual void build() {} deba@1979: deba@1979: const Graph* getGraph() const { return graph; } deba@1979: deba@1979: private: deba@1979: const Graph* graph; deba@1979: BNodeMap<_Value> bNodeMap; deba@1979: ANodeMap<_Value> aNodeMap; deba@1979: }; deba@1979: deba@1979: public: deba@1979: deba@1979: template deba@1979: class NodeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1979: typedef IterableMapExtender< NodeMapBase<_Value> > Parent; deba@1979: deba@1979: NodeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: NodeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} deba@1979: deba@1979: NodeMap& operator=(const NodeMap& cmap) { deba@1979: return operator=(cmap); deba@1979: } deba@1979: deba@1979: deba@1979: /// \brief Template assign operator. deba@1979: /// deba@1979: /// The given parameter should be conform to the ReadMap deba@1979: /// concept and could be indiced by the current item set of deba@1979: /// the NodeMap. In this case the value for each item deba@1979: /// is assigned by the value of the given ReadMap. deba@1979: template deba@1979: NodeMap& operator=(const CMap& cmap) { deba@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: Node it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: deba@1979: }; deba@1979: deba@1979: deba@1979: deba@1979: template deba@1979: class EdgeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1979: typedef IterableMapExtender > Parent; deba@1979: deba@1979: EdgeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: EdgeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} 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@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: Edge it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } deba@1979: return *this; deba@1979: } deba@1979: }; deba@1979: deba@1979: template deba@1979: class UEdgeMap deba@1979: : public IterableMapExtender > { deba@1979: public: deba@1979: typedef BpUGraphExtender Graph; deba@1979: typedef IterableMapExtender > deba@1979: Parent; deba@1979: deba@1979: UEdgeMap(const Graph& _g) deba@1979: : Parent(_g) {} deba@1979: UEdgeMap(const Graph& _g, const _Value& _v) deba@1979: : Parent(_g, _v) {} 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@1979: checkConcept, CMap>(); deba@1979: const typename Parent::Graph* graph = Parent::getGraph(); deba@1979: UEdge it; deba@1979: for (graph->first(it); it != INVALID; graph->next(it)) { deba@1979: Parent::set(it, cmap[it]); deba@1979: } 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@1979: ~BpUGraphExtender() { 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: } deba@1979: deba@1979: deba@1820: }; deba@1820: deba@1791: } deba@1791: deba@1791: #endif // LEMON_UNDIR_GRAPH_EXTENDER_H