diff -r ef2d00e46897 -r c2992fd74dad lemon/bits/edge_set_extender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/bits/edge_set_extender.h Wed Feb 22 18:26:56 2006 +0000 @@ -0,0 +1,606 @@ +/* -*- 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. + * + */ + + +namespace lemon { + + template + class EdgeSetExtender : public Base { + public: + + typedef Base Parent; + typedef EdgeSetExtender 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; + } + + + // Alteration notifier extensions + + /// The edge observer registry. + typedef AlterationNotifier EdgeNotifier; + + protected: + + mutable EdgeNotifier edge_notifier; + + public: + + /// \brief Gives back the edge alteration notifier. + /// + /// Gives back the edge alteration notifier. + EdgeNotifier& getNotifier(Edge) const { + return edge_notifier; + } + + // Iterable extensions + + 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((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); + } + + using Parent::first; + + // Mappable extension + + template + class EdgeMap + : public IterableMapExtender > { + public: + typedef EdgeSetExtender 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; + } + }; + + + // Alteration extension + + 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(); + Parent::clear(); + } + + void erase(const Edge& edge) { + getNotifier(Edge()).erase(edge); + Parent::erase(edge); + } + + + ~EdgeSetExtender() { + edge_notifier.clear(); + } + + }; + + + template + class UEdgeSetExtender : public Base { + + public: + + typedef Base Parent; + typedef UEdgeSetExtender Graph; + + typedef typename Parent::Node Node; + typedef typename Parent::Edge Edge; + typedef typename Parent::UEdge UEdge; + + + 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); + } + + typedef AlterationNotifier EdgeNotifier; + typedef AlterationNotifier UEdgeNotifier; + + + protected: + + mutable EdgeNotifier edge_notifier; + mutable UEdgeNotifier uedge_notifier; + + public: + + 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 UEdgeSetExtender; + 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); + } + + + template + class EdgeMap + : public IterableMapExtender > { + public: + typedef UEdgeSetExtender 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 UEdgeSetExtender 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 + + 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(); + Parent::clear(); + } + + 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); + } + + + ~UEdgeSetExtender() { + getNotifier(Edge()).clear(); + getNotifier(UEdge()).clear(); + } + + }; +}