/* -*- 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_GRAPH_EXTENDER_H #define LEMON_GRAPH_EXTENDER_H #include #include #include namespace lemon { 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 (ie. 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 (ie. 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 (ie. 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 (ie. the source in this case) of the /// iterator Node runningNode(const InEdgeIt &e) const { return Parent::source(e); } template class NodeMap : public IterableMapExtender > { public: typedef GraphExtender Graph; typedef IterableMapExtender > Parent; NodeMap(const Graph& _g) : Parent(_g) {} NodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concecpt and could be indiced by the current item set of /// the NodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Node it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class EdgeMap : public IterableMapExtender > { public: typedef GraphExtender Graph; typedef IterableMapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} EdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Edge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; 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() { getNotifier(Edge()).clear(); getNotifier(Node()).clear(); } }; template class UGraphBaseExtender : public Base { public: typedef Base Parent; typedef typename Parent::Edge UEdge; typedef typename Parent::Node Node; typedef True UndirectedTag; class Edge : public UEdge { friend class UGraphBaseExtender; protected: bool forward; Edge(const UEdge &ue, bool _forward) : UEdge(ue), forward(_forward) {} public: Edge() {} /// Invalid edge constructor Edge(Invalid i) : UEdge(i), forward(true) {} bool operator==(const Edge &that) const { return forward==that.forward && UEdge(*this)==UEdge(that); } bool operator!=(const Edge &that) const { return forward!=that.forward || UEdge(*this)!=UEdge(that); } bool operator<(const Edge &that) const { return forward> 1), bool(id & 1)); } UEdge uEdgeFromId(int id) const { return Parent::edgeFromId(id >> 1); } int id(const Node &n) const { return Parent::id(n); } int id(const UEdge &e) const { return Parent::id(e); } int id(const Edge &e) const { return 2 * Parent::id(e) + int(e.forward); } int maxNodeId() const { return Parent::maxNodeId(); } int maxEdgeId() const { return 2 * Parent::maxEdgeId() + 1; } int maxUEdgeId() const { return Parent::maxEdgeId(); } int edgeNum() const { return 2 * Parent::edgeNum(); } int uEdgeNum() const { return Parent::edgeNum(); } Edge findEdge(Node source, Node target, Edge prev) const { if (prev == INVALID) { UEdge edge = Parent::findEdge(source, target); if (edge != INVALID) return direct(edge, true); edge = Parent::findEdge(target, source); if (edge != INVALID) return direct(edge, false); } else if (direction(prev)) { UEdge edge = Parent::findEdge(source, target, prev); if (edge != INVALID) return direct(edge, true); edge = Parent::findEdge(target, source); if (edge != INVALID) return direct(edge, false); } else { UEdge edge = Parent::findEdge(target, source, prev); if (edge != INVALID) return direct(edge, false); } return INVALID; } UEdge findUEdge(Node source, Node target, UEdge prev) const { if (prev == INVALID) { UEdge edge = Parent::findEdge(source, target); if (edge != INVALID) return edge; edge = Parent::findEdge(target, source); if (edge != INVALID) return edge; } else if (Parent::source(prev) == source) { UEdge edge = Parent::findEdge(source, target, prev); if (edge != INVALID) return edge; edge = Parent::findEdge(target, source); if (edge != INVALID) return edge; } else { UEdge edge = Parent::findEdge(target, source, prev); if (edge != INVALID) return edge; } return INVALID; } }; template class UGraphExtender : public Base { public: typedef Base Parent; typedef UGraphExtender Graph; typedef typename Parent::Node Node; typedef typename Parent::Edge Edge; typedef typename Parent::UEdge UEdge; // UGraph extension int maxId(Node) const { return Parent::maxNodeId(); } int maxId(Edge) const { return Parent::maxEdgeId(); } int maxId(UEdge) const { return Parent::maxUEdgeId(); } Node fromId(int id, Node) const { return Parent::nodeFromId(id); } Edge fromId(int id, Edge) const { return Parent::edgeFromId(id); } UEdge fromId(int id, UEdge) const { return Parent::uEdgeFromId(id); } Node oppositeNode(const Node &n, const UEdge &e) const { if( n == Parent::source(e)) return Parent::target(e); else if( n == Parent::target(e)) return Parent::source(e); else return INVALID; } Edge oppositeEdge(const Edge &e) const { return Parent::direct(e, !Parent::direction(e)); } using Parent::direct; Edge direct(const UEdge &ue, const Node &s) const { return Parent::direct(ue, Parent::source(ue) == s); } // Alterable extension typedef AlterationNotifier NodeNotifier; typedef AlterationNotifier EdgeNotifier; typedef AlterationNotifier UEdgeNotifier; protected: mutable NodeNotifier node_notifier; mutable EdgeNotifier edge_notifier; mutable UEdgeNotifier uedge_notifier; public: NodeNotifier& getNotifier(Node) const { return node_notifier; } EdgeNotifier& getNotifier(Edge) const { return edge_notifier; } UEdgeNotifier& getNotifier(UEdge) const { return uedge_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; } }; class UEdgeIt : public Parent::UEdge { const Graph* graph; public: UEdgeIt() { } UEdgeIt(Invalid i) : UEdge(i) { } explicit UEdgeIt(const Graph& _graph) : graph(&_graph) { _graph.first(*static_cast(this)); } UEdgeIt(const Graph& _graph, const UEdge& e) : UEdge(e), graph(&_graph) { } UEdgeIt& operator++() { graph->next(*this); return *this; } }; class IncEdgeIt : public Parent::UEdge { friend class UGraphExtender; const Graph* graph; bool direction; public: IncEdgeIt() { } IncEdgeIt(Invalid i) : UEdge(i), direction(false) { } IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { _graph.firstInc(*this, direction, n); } IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n) : graph(&_graph), UEdge(ue) { direction = (_graph.source(ue) == n); } IncEdgeIt& operator++() { graph->nextInc(*this, direction); return *this; } }; /// \brief Base node of the iterator /// /// Returns the base node (ie. the source in this case) of the iterator Node baseNode(const OutEdgeIt &e) const { return Parent::source((Edge)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the target in this case) of the /// iterator Node runningNode(const OutEdgeIt &e) const { return Parent::target((Edge)e); } /// \brief Base node of the iterator /// /// Returns the base node (ie. the target in this case) of the iterator Node baseNode(const InEdgeIt &e) const { return Parent::target((Edge)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the source in this case) of the /// iterator Node runningNode(const InEdgeIt &e) const { return Parent::source((Edge)e); } /// Base node of the iterator /// /// Returns the base node of the iterator Node baseNode(const IncEdgeIt &e) const { return e.direction ? source(e) : target(e); } /// Running node of the iterator /// /// Returns the running node of the iterator Node runningNode(const IncEdgeIt &e) const { return e.direction ? target(e) : source(e); } // Mappable extension template class NodeMap : public IterableMapExtender > { public: typedef UGraphExtender Graph; typedef IterableMapExtender > Parent; NodeMap(const Graph& _g) : Parent(_g) {} NodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concecpt and could be indiced by the current item set of /// the NodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Node it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class EdgeMap : public IterableMapExtender > { public: typedef UGraphExtender Graph; typedef IterableMapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} EdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Edge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class UEdgeMap : public IterableMapExtender > { public: typedef UGraphExtender Graph; typedef IterableMapExtender > Parent; UEdgeMap(const Graph& _g) : Parent(_g) {} UEdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); } template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); UEdge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; // Alteration extension Node addNode() { Node node = Parent::addNode(); getNotifier(Node()).add(node); return node; } UEdge addEdge(const Node& from, const Node& to) { UEdge uedge = Parent::addEdge(from, to); getNotifier(UEdge()).add(uedge); getNotifier(Edge()).add(Parent::direct(uedge, true)); getNotifier(Edge()).add(Parent::direct(uedge, false)); return uedge; } void clear() { getNotifier(Edge()).clear(); getNotifier(UEdge()).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 UEdge& uedge) { getNotifier(Edge()).erase(Parent::direct(uedge, true)); getNotifier(Edge()).erase(Parent::direct(uedge, false)); getNotifier(UEdge()).erase(uedge); Parent::erase(uedge); } ~UGraphExtender() { getNotifier(Edge()).clear(); getNotifier(UEdge()).clear(); getNotifier(Node()).clear(); } }; template class BpUGraphBaseExtender : public Base { public: typedef Base Parent; typedef BpUGraphBaseExtender Graph; typedef typename Parent::Node Node; typedef typename Parent::Edge UEdge; using Parent::first; using Parent::next; using Parent::id; class ANode : public Node { friend class BpUGraphBaseExtender; public: ANode() {} ANode(const Node& node) : Node(node) { LEMON_ASSERT(Parent::aNode(node) || node == INVALID, typename Parent::NodeSetError()); } ANode(Invalid) : Node(INVALID) {} }; void first(ANode& node) const { Parent::firstANode(static_cast(node)); } void next(ANode& node) const { Parent::nextANode(static_cast(node)); } int id(const ANode& node) const { return Parent::aNodeId(node); } class BNode : public Node { friend class BpUGraphBaseExtender; public: BNode() {} BNode(const Node& node) : Node(node) { LEMON_ASSERT(Parent::bNode(node) || node == INVALID, typename Parent::NodeSetError()); } BNode(Invalid) : Node(INVALID) {} }; void first(BNode& node) const { Parent::firstBNode(static_cast(node)); } void next(BNode& node) const { Parent::nextBNode(static_cast(node)); } int id(const BNode& node) const { return Parent::aNodeId(node); } Node source(const UEdge& edge) const { return aNode(edge); } Node target(const UEdge& edge) const { return bNode(edge); } void firstInc(UEdge& edge, bool& direction, const Node& node) const { if (Parent::aNode(node)) { Parent::firstOut(edge, node); direction = true; } else { Parent::firstIn(edge, node); direction = static_cast(edge) == INVALID; } } void nextInc(UEdge& edge, bool& direction) const { if (direction) { Parent::nextOut(edge); } else { Parent::nextIn(edge); if (edge == INVALID) direction = true; } } int maxUEdgeId() const { return Parent::maxEdgeId(); } UEdge uEdgeFromId(int id) const { return Parent::edgeFromId(id); } class Edge : public UEdge { friend class BpUGraphBaseExtender; protected: bool forward; Edge(const UEdge& edge, bool _forward) : UEdge(edge), forward(_forward) {} public: Edge() {} Edge (Invalid) : UEdge(INVALID), forward(true) {} bool operator==(const Edge& i) const { return UEdge::operator==(i) && forward == i.forward; } bool operator!=(const Edge& i) const { return UEdge::operator!=(i) || forward != i.forward; } bool operator<(const Edge& i) const { return UEdge::operator<(i) || (!(i.forward(edge)); edge.forward = true; } void next(Edge& edge) const { if (!edge.forward) { Parent::next(static_cast(edge)); } edge.forward = !edge.forward; } void firstOut(Edge& edge, const Node& node) const { if (Parent::aNode(node)) { Parent::firstOut(edge, node); edge.forward = true; } else { Parent::firstIn(edge, node); edge.forward = static_cast(edge) == INVALID; } } void nextOut(Edge& edge) const { if (edge.forward) { Parent::nextOut(edge); } else { Parent::nextIn(edge); edge.forward = static_cast(edge) == INVALID; } } void firstIn(Edge& edge, const Node& node) const { if (Parent::bNode(node)) { Parent::firstIn(edge, node); edge.forward = true; } else { Parent::firstOut(edge, node); edge.forward = static_cast(edge) == INVALID; } } void nextIn(Edge& edge) const { if (edge.forward) { Parent::nextIn(edge); } else { Parent::nextOut(edge); edge.forward = static_cast(edge) == INVALID; } } Node source(const Edge& edge) const { return edge.forward ? Parent::aNode(edge) : Parent::bNode(edge); } Node target(const Edge& edge) const { return edge.forward ? Parent::bNode(edge) : Parent::aNode(edge); } int id(const Edge& edge) const { return (Parent::id(edge) << 1) + (edge.forward ? 0 : 1); } Edge edgeFromId(int id) const { return Edge(Parent::fromId(id >> 1, UEdge()), (id & 1) == 0); } int maxEdgeId() const { return (Parent::maxId(UEdge()) << 1) + 1; } bool direction(const Edge& edge) const { return edge.forward; } Edge direct(const UEdge& edge, bool direction) const { return Edge(edge, direction); } }; template class BpUGraphExtender : public Base { public: typedef Base Parent; typedef BpUGraphExtender Graph; typedef typename Parent::Node Node; typedef typename Parent::BNode BNode; typedef typename Parent::ANode ANode; typedef typename Parent::Edge Edge; typedef typename Parent::UEdge UEdge; Node oppositeNode(const UEdge& edge, const Node& node) const { return source(edge) == node ? target(edge) : source(edge); } using Parent::direct; Edge direct(const UEdge& edge, const Node& node) const { return Edge(edge, node == Parent::source(edge)); } Edge oppositeEdge(const Edge& edge) const { return Parent::direct(edge, !Parent::direction(edge)); } int maxId(Node) const { return Parent::maxNodeId(); } int maxId(BNode) const { return Parent::maxBNodeId(); } int maxId(ANode) const { return Parent::maxANodeId(); } int maxId(Edge) const { return Parent::maxEdgeId(); } int maxId(UEdge) const { return Parent::maxUEdgeId(); } Node fromId(int id, Node) const { return Parent::nodeFromId(id); } ANode fromId(int id, ANode) const { return Parent::fromANodeId(id); } BNode fromId(int id, BNode) const { return Parent::fromBNodeId(id); } Edge fromId(int id, Edge) const { return Parent::edgeFromId(id); } UEdge fromId(int id, UEdge) const { return Parent::uEdgeFromId(id); } typedef AlterationNotifier NodeNotifier; typedef AlterationNotifier BNodeNotifier; typedef AlterationNotifier ANodeNotifier; typedef AlterationNotifier EdgeNotifier; typedef AlterationNotifier UEdgeNotifier; protected: mutable NodeNotifier nodeNotifier; mutable BNodeNotifier bNodeNotifier; mutable ANodeNotifier aNodeNotifier; mutable EdgeNotifier edgeNotifier; mutable UEdgeNotifier uEdgeNotifier; public: NodeNotifier& getNotifier(Node) const { return nodeNotifier; } BNodeNotifier& getNotifier(BNode) const { return bNodeNotifier; } ANodeNotifier& getNotifier(ANode) const { return aNodeNotifier; } EdgeNotifier& getNotifier(Edge) const { return edgeNotifier; } UEdgeNotifier& getNotifier(UEdge) const { return uEdgeNotifier; } ~BpUGraphExtender() { getNotifier(UEdge()).clear(); getNotifier(Edge()).clear(); getNotifier(ANode()).clear(); getNotifier(BNode()).clear(); getNotifier(Node()).clear(); } class NodeIt : public Node { const Graph* graph; public: NodeIt() { } NodeIt(Invalid i) : Node(INVALID) { } 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 ANodeIt : public Node { friend class BpUGraphExtender; const Graph* graph; public: ANodeIt() { } ANodeIt(Invalid i) : Node(INVALID) { } explicit ANodeIt(const Graph& _graph) : graph(&_graph) { graph->firstANode(static_cast(*this)); } ANodeIt(const Graph& _graph, const Node& node) : Node(node), graph(&_graph) {} ANodeIt& operator++() { graph->nextANode(*this); return *this; } }; class BNodeIt : public Node { friend class BpUGraphExtender; const Graph* graph; public: BNodeIt() { } BNodeIt(Invalid i) : Node(INVALID) { } explicit BNodeIt(const Graph& _graph) : graph(&_graph) { graph->firstBNode(static_cast(*this)); } BNodeIt(const Graph& _graph, const Node& node) : Node(node), graph(&_graph) {} BNodeIt& operator++() { graph->nextBNode(*this); return *this; } }; class EdgeIt : public Edge { friend class BpUGraphExtender; const Graph* graph; public: EdgeIt() { } EdgeIt(Invalid i) : Edge(INVALID) { } explicit EdgeIt(const Graph& _graph) : graph(&_graph) { graph->first(static_cast(*this)); } EdgeIt(const Graph& _graph, const Edge& edge) : Edge(edge), graph(&_graph) { } EdgeIt& operator++() { graph->next(*this); return *this; } }; class UEdgeIt : public UEdge { friend class BpUGraphExtender; const Graph* graph; public: UEdgeIt() { } UEdgeIt(Invalid i) : UEdge(INVALID) { } explicit UEdgeIt(const Graph& _graph) : graph(&_graph) { graph->first(static_cast(*this)); } UEdgeIt(const Graph& _graph, const UEdge& edge) : UEdge(edge), graph(&_graph) { } UEdgeIt& operator++() { graph->next(*this); return *this; } }; class OutEdgeIt : public Edge { friend class BpUGraphExtender; 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 { friend class BpUGraphExtender; 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 (ie. the source in this case) of the iterator Node baseNode(const OutEdgeIt &e) const { return Parent::source((Edge&)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the target in this case) of the /// iterator Node runningNode(const OutEdgeIt &e) const { return Parent::target((Edge&)e); } /// \brief Base node of the iterator /// /// Returns the base node (ie. the target in this case) of the iterator Node baseNode(const InEdgeIt &e) const { return Parent::target((Edge&)e); } /// \brief Running node of the iterator /// /// Returns the running node (ie. the source in this case) of the /// iterator Node runningNode(const InEdgeIt &e) const { return Parent::source((Edge&)e); } class IncEdgeIt : public Parent::UEdge { friend class BpUGraphExtender; const Graph* graph; bool direction; public: IncEdgeIt() { } IncEdgeIt(Invalid i) : UEdge(i), direction(true) { } IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) { graph->firstInc(*this, direction, n); } IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n) : graph(&_graph), UEdge(ue) { direction = (graph->source(ue) == n); } IncEdgeIt& operator++() { graph->nextInc(*this, direction); return *this; } }; /// Base node of the iterator /// /// Returns the base node of the iterator Node baseNode(const IncEdgeIt &e) const { return e.direction ? source(e) : target(e); } /// Running node of the iterator /// /// Returns the running node of the iterator Node runningNode(const IncEdgeIt &e) const { return e.direction ? target(e) : source(e); } template class ANodeMap : public IterableMapExtender > { public: typedef BpUGraphExtender Graph; typedef IterableMapExtender > Parent; ANodeMap(const Graph& _g) : Parent(_g) {} ANodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} ANodeMap& operator=(const ANodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concept and could be indiced by the current item set of /// the ANodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template ANodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); ANode it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class BNodeMap : public IterableMapExtender > { public: typedef BpUGraphExtender Graph; typedef IterableMapExtender > Parent; BNodeMap(const Graph& _g) : Parent(_g) {} BNodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} BNodeMap& operator=(const BNodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concept and could be indiced by the current item set of /// the BNodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template BNodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); BNode it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; protected: template class NodeMapBase : public NodeNotifier::ObserverBase { public: typedef BpUGraphExtender Graph; typedef Node Key; typedef _Value Value; /// The reference type of the map; typedef typename BNodeMap<_Value>::Reference Reference; /// The pointer type of the map; typedef typename BNodeMap<_Value>::Pointer Pointer; /// The const value type of the map. typedef const Value ConstValue; /// The const reference type of the map; typedef typename BNodeMap<_Value>::ConstReference ConstReference; /// The pointer type of the map; typedef typename BNodeMap<_Value>::ConstPointer ConstPointer; typedef True ReferenceMapTag; NodeMapBase(const Graph& _g) : graph(&_g), bNodeMap(_g), aNodeMap(_g) { NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); } NodeMapBase(const Graph& _g, const _Value& _v) : graph(&_g), bNodeMap(_g, _v), aNodeMap(_g, _v) { NodeNotifier::ObserverBase::attach(_g.getNotifier(Node())); } virtual ~NodeMapBase() { if (NodeNotifier::ObserverBase::attached()) { NodeNotifier::ObserverBase::detach(); } } ConstReference operator[](const Key& node) const { if (Parent::aNode(node)) { return aNodeMap[node]; } else { return bNodeMap[node]; } } Reference operator[](const Key& node) { if (Parent::aNode(node)) { return aNodeMap[node]; } else { return bNodeMap[node]; } } void set(const Key& node, const Value& value) { if (Parent::aNode(node)) { aNodeMap.set(node, value); } else { bNodeMap.set(node, value); } } protected: virtual void add(const Node&) {} virtual void add(const std::vector&) {} virtual void erase(const Node&) {} virtual void erase(const std::vector&) {} virtual void clear() {} virtual void build() {} const Graph* getGraph() const { return graph; } private: const Graph* graph; BNodeMap<_Value> bNodeMap; ANodeMap<_Value> aNodeMap; }; public: template class NodeMap : public IterableMapExtender > { public: typedef BpUGraphExtender Graph; typedef IterableMapExtender< NodeMapBase<_Value> > Parent; NodeMap(const Graph& _g) : Parent(_g) {} NodeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} NodeMap& operator=(const NodeMap& cmap) { return operator=(cmap); } /// \brief Template assign operator. /// /// The given parameter should be conform to the ReadMap /// concept and could be indiced by the current item set of /// the NodeMap. In this case the value for each item /// is assigned by the value of the given ReadMap. template NodeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Node it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class EdgeMap : public IterableMapExtender > { public: typedef BpUGraphExtender Graph; typedef IterableMapExtender > Parent; EdgeMap(const Graph& _g) : Parent(_g) {} EdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} EdgeMap& operator=(const EdgeMap& cmap) { return operator=(cmap); } template EdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); Edge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; template class UEdgeMap : public IterableMapExtender > { public: typedef BpUGraphExtender Graph; typedef IterableMapExtender > Parent; UEdgeMap(const Graph& _g) : Parent(_g) {} UEdgeMap(const Graph& _g, const _Value& _v) : Parent(_g, _v) {} UEdgeMap& operator=(const UEdgeMap& cmap) { return operator=(cmap); } template UEdgeMap& operator=(const CMap& cmap) { checkConcept, CMap>(); const typename Parent::Graph* graph = Parent::getGraph(); UEdge it; for (graph->first(it); it != INVALID; graph->next(it)) { Parent::set(it, cmap[it]); } return *this; } }; Node addANode() { Node node = Parent::addANode(); getNotifier(ANode()).add(node); getNotifier(Node()).add(node); return node; } Node addBNode() { Node node = Parent::addBNode(); getNotifier(BNode()).add(node); getNotifier(Node()).add(node); return node; } UEdge addEdge(const Node& source, const Node& target) { UEdge uedge = Parent::addEdge(source, target); getNotifier(UEdge()).add(uedge); std::vector edges; edges.push_back(direct(uedge, true)); edges.push_back(direct(uedge, false)); getNotifier(Edge()).add(edges); return uedge; } void clear() { getNotifier(Edge()).clear(); getNotifier(UEdge()).clear(); getNotifier(Node()).clear(); getNotifier(BNode()).clear(); getNotifier(ANode()).clear(); Parent::clear(); } void erase(const Node& node) { UEdge uedge; bool dir; Parent::firstInc(uedge, dir, node); while (uedge != INVALID ) { erase(uedge); Parent::firstInc(uedge, dir, node); } getNotifier(Node()).erase(node); Parent::erase(node); } void erase(const UEdge& uedge) { std::vector edges; edges.push_back(direct(uedge, true)); edges.push_back(direct(uedge, false)); getNotifier(Edge()).erase(edges); getNotifier(UEdge()).erase(uedge); Parent::erase(uedge); } ~BpUGraphExtender() { getNotifier(Edge()).clear(); getNotifier(UEdge()).clear(); getNotifier(Node()).clear(); getNotifier(BNode()).clear(); getNotifier(ANode()).clear(); } }; } #endif // LEMON_UNDIR_GRAPH_EXTENDER_H