3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
20 #define LEMON_BITS_EDGE_SET_EXTENDER_H
22 #include <lemon/bits/invalid.h>
23 #include <lemon/error.h>
25 #include <lemon/bits/default_map.h>
29 ///\brief Extenders for the edge set types
32 /// \ingroup graphbits
34 /// \brief Extender for the EdgeSets
35 template <typename Base>
36 class EdgeSetExtender : public Base {
40 typedef EdgeSetExtender Graph;
44 typedef typename Parent::Node Node;
45 typedef typename Parent::Edge Edge;
47 int maxId(Node) const {
48 return Parent::maxNodeId();
51 int maxId(Edge) const {
52 return Parent::maxEdgeId();
55 Node fromId(int id, Node) const {
56 return Parent::nodeFromId(id);
59 Edge fromId(int id, Edge) const {
60 return Parent::edgeFromId(id);
63 Node oppositeNode(const Node &n, const Edge &e) const {
64 if (n == Parent::source(e))
65 return Parent::target(e);
66 else if(n==Parent::target(e))
67 return Parent::source(e);
73 // Alteration notifier extensions
75 /// The edge observer registry.
76 typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
80 mutable EdgeNotifier edge_notifier;
84 using Parent::getNotifier;
86 /// \brief Gives back the edge alteration notifier.
88 /// Gives back the edge alteration notifier.
89 EdgeNotifier& getNotifier(Edge) const {
93 // Iterable extensions
95 class NodeIt : public Node {
101 NodeIt(Invalid i) : Node(i) { }
103 explicit NodeIt(const Graph& _graph) : graph(&_graph) {
104 _graph.first(*static_cast<Node*>(this));
107 NodeIt(const Graph& _graph, const Node& node)
108 : Node(node), graph(&_graph) {}
110 NodeIt& operator++() {
118 class EdgeIt : public Edge {
124 EdgeIt(Invalid i) : Edge(i) { }
126 explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
127 _graph.first(*static_cast<Edge*>(this));
130 EdgeIt(const Graph& _graph, const Edge& e) :
131 Edge(e), graph(&_graph) { }
133 EdgeIt& operator++() {
141 class OutEdgeIt : public Edge {
147 OutEdgeIt(Invalid i) : Edge(i) { }
149 OutEdgeIt(const Graph& _graph, const Node& node)
151 _graph.firstOut(*this, node);
154 OutEdgeIt(const Graph& _graph, const Edge& edge)
155 : Edge(edge), graph(&_graph) {}
157 OutEdgeIt& operator++() {
158 graph->nextOut(*this);
165 class InEdgeIt : public Edge {
171 InEdgeIt(Invalid i) : Edge(i) { }
173 InEdgeIt(const Graph& _graph, const Node& node)
175 _graph.firstIn(*this, node);
178 InEdgeIt(const Graph& _graph, const Edge& edge) :
179 Edge(edge), graph(&_graph) {}
181 InEdgeIt& operator++() {
182 graph->nextIn(*this);
188 /// \brief Base node of the iterator
190 /// Returns the base node (ie. the source in this case) of the iterator
191 Node baseNode(const OutEdgeIt &e) const {
192 return Parent::source((Edge)e);
194 /// \brief Running node of the iterator
196 /// Returns the running node (ie. the target in this case) of the
198 Node runningNode(const OutEdgeIt &e) const {
199 return Parent::target((Edge)e);
202 /// \brief Base node of the iterator
204 /// Returns the base node (ie. the target in this case) of the iterator
205 Node baseNode(const InEdgeIt &e) const {
206 return Parent::target((Edge)e);
208 /// \brief Running node of the iterator
210 /// Returns the running node (ie. the source in this case) of the
212 Node runningNode(const InEdgeIt &e) const {
213 return Parent::source((Edge)e);
218 // Mappable extension
220 template <typename _Value>
222 : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
224 typedef EdgeSetExtender Graph;
225 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
227 EdgeMap(const Graph& _g)
229 EdgeMap(const Graph& _g, const _Value& _v)
232 EdgeMap& operator=(const EdgeMap& cmap) {
233 return operator=<EdgeMap>(cmap);
236 template <typename CMap>
237 EdgeMap& operator=(const CMap& cmap) {
238 checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
239 const typename Parent::Graph* graph = Parent::getGraph();
241 for (graph->first(it); it != INVALID; graph->next(it)) {
242 Parent::set(it, cmap[it]);
249 // Alteration extension
251 Edge addEdge(const Node& from, const Node& to) {
252 Edge edge = Parent::addEdge(from, to);
253 getNotifier(Edge()).add(edge);
258 getNotifier(Edge()).clear();
262 void erase(const Edge& edge) {
263 getNotifier(Edge()).erase(edge);
268 edge_notifier.setContainer(*this);
272 edge_notifier.clear();
278 /// \ingroup graphbits
280 /// \brief Extender for the UEdgeSets
281 template <typename Base>
282 class UEdgeSetExtender : public Base {
287 typedef UEdgeSetExtender Graph;
289 typedef typename Parent::Node Node;
290 typedef typename Parent::Edge Edge;
291 typedef typename Parent::UEdge UEdge;
294 int maxId(Node) const {
295 return Parent::maxNodeId();
298 int maxId(Edge) const {
299 return Parent::maxEdgeId();
302 int maxId(UEdge) const {
303 return Parent::maxUEdgeId();
306 Node fromId(int id, Node) const {
307 return Parent::nodeFromId(id);
310 Edge fromId(int id, Edge) const {
311 return Parent::edgeFromId(id);
314 UEdge fromId(int id, UEdge) const {
315 return Parent::uEdgeFromId(id);
318 Node oppositeNode(const Node &n, const UEdge &e) const {
319 if( n == Parent::source(e))
320 return Parent::target(e);
321 else if( n == Parent::target(e))
322 return Parent::source(e);
327 Edge oppositeEdge(const Edge &e) const {
328 return Parent::direct(e, !Parent::direction(e));
331 using Parent::direct;
332 Edge direct(const UEdge &ue, const Node &s) const {
333 return Parent::direct(ue, Parent::source(ue) == s);
336 typedef AlterationNotifier<UEdgeSetExtender, Edge> EdgeNotifier;
337 typedef AlterationNotifier<UEdgeSetExtender, UEdge> UEdgeNotifier;
342 mutable EdgeNotifier edge_notifier;
343 mutable UEdgeNotifier uedge_notifier;
347 using Parent::getNotifier;
349 EdgeNotifier& getNotifier(Edge) const {
350 return edge_notifier;
353 UEdgeNotifier& getNotifier(UEdge) const {
354 return uedge_notifier;
358 class NodeIt : public Node {
364 NodeIt(Invalid i) : Node(i) { }
366 explicit NodeIt(const Graph& _graph) : graph(&_graph) {
367 _graph.first(*static_cast<Node*>(this));
370 NodeIt(const Graph& _graph, const Node& node)
371 : Node(node), graph(&_graph) {}
373 NodeIt& operator++() {
381 class EdgeIt : public Edge {
387 EdgeIt(Invalid i) : Edge(i) { }
389 explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
390 _graph.first(*static_cast<Edge*>(this));
393 EdgeIt(const Graph& _graph, const Edge& e) :
394 Edge(e), graph(&_graph) { }
396 EdgeIt& operator++() {
404 class OutEdgeIt : public Edge {
410 OutEdgeIt(Invalid i) : Edge(i) { }
412 OutEdgeIt(const Graph& _graph, const Node& node)
414 _graph.firstOut(*this, node);
417 OutEdgeIt(const Graph& _graph, const Edge& edge)
418 : Edge(edge), graph(&_graph) {}
420 OutEdgeIt& operator++() {
421 graph->nextOut(*this);
428 class InEdgeIt : public Edge {
434 InEdgeIt(Invalid i) : Edge(i) { }
436 InEdgeIt(const Graph& _graph, const Node& node)
438 _graph.firstIn(*this, node);
441 InEdgeIt(const Graph& _graph, const Edge& edge) :
442 Edge(edge), graph(&_graph) {}
444 InEdgeIt& operator++() {
445 graph->nextIn(*this);
452 class UEdgeIt : public Parent::UEdge {
458 UEdgeIt(Invalid i) : UEdge(i) { }
460 explicit UEdgeIt(const Graph& _graph) : graph(&_graph) {
461 _graph.first(*static_cast<UEdge*>(this));
464 UEdgeIt(const Graph& _graph, const UEdge& e) :
465 UEdge(e), graph(&_graph) { }
467 UEdgeIt& operator++() {
474 class IncEdgeIt : public Parent::UEdge {
475 friend class UEdgeSetExtender;
482 IncEdgeIt(Invalid i) : UEdge(i), direction(false) { }
484 IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
485 _graph.firstInc(*this, direction, n);
488 IncEdgeIt(const Graph& _graph, const UEdge &ue, const Node &n)
489 : graph(&_graph), UEdge(ue) {
490 direction = (_graph.source(ue) == n);
493 IncEdgeIt& operator++() {
494 graph->nextInc(*this, direction);
499 /// \brief Base node of the iterator
501 /// Returns the base node (ie. the source in this case) of the iterator
502 Node baseNode(const OutEdgeIt &e) const {
503 return Parent::source((Edge)e);
505 /// \brief Running node of the iterator
507 /// Returns the running node (ie. the target in this case) of the
509 Node runningNode(const OutEdgeIt &e) const {
510 return Parent::target((Edge)e);
513 /// \brief Base node of the iterator
515 /// Returns the base node (ie. the target in this case) of the iterator
516 Node baseNode(const InEdgeIt &e) const {
517 return Parent::target((Edge)e);
519 /// \brief Running node of the iterator
521 /// Returns the running node (ie. the source in this case) of the
523 Node runningNode(const InEdgeIt &e) const {
524 return Parent::source((Edge)e);
527 /// Base node of the iterator
529 /// Returns the base node of the iterator
530 Node baseNode(const IncEdgeIt &e) const {
531 return e.direction ? source(e) : target(e);
533 /// Running node of the iterator
535 /// Returns the running node of the iterator
536 Node runningNode(const IncEdgeIt &e) const {
537 return e.direction ? target(e) : source(e);
541 template <typename _Value>
543 : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
545 typedef UEdgeSetExtender Graph;
546 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
548 EdgeMap(const Graph& _g)
550 EdgeMap(const Graph& _g, const _Value& _v)
553 EdgeMap& operator=(const EdgeMap& cmap) {
554 return operator=<EdgeMap>(cmap);
557 template <typename CMap>
558 EdgeMap& operator=(const CMap& cmap) {
559 checkConcept<concept::ReadMap<Edge, _Value>, CMap>();
560 const typename Parent::Graph* graph = Parent::getGraph();
562 for (graph->first(it); it != INVALID; graph->next(it)) {
563 Parent::set(it, cmap[it]);
570 template <typename _Value>
572 : public MapExtender<DefaultMap<Graph, UEdge, _Value> > {
574 typedef UEdgeSetExtender Graph;
575 typedef MapExtender<DefaultMap<Graph, UEdge, _Value> > Parent;
577 UEdgeMap(const Graph& _g)
579 UEdgeMap(const Graph& _g, const _Value& _v)
582 UEdgeMap& operator=(const UEdgeMap& cmap) {
583 return operator=<UEdgeMap>(cmap);
586 template <typename CMap>
587 UEdgeMap& operator=(const CMap& cmap) {
588 checkConcept<concept::ReadMap<UEdge, _Value>, CMap>();
589 const typename Parent::Graph* graph = Parent::getGraph();
591 for (graph->first(it); it != INVALID; graph->next(it)) {
592 Parent::set(it, cmap[it]);
599 // Alteration extension
601 UEdge addEdge(const Node& from, const Node& to) {
602 UEdge uedge = Parent::addEdge(from, to);
603 getNotifier(UEdge()).add(uedge);
604 getNotifier(Edge()).add(Parent::direct(uedge, true));
605 getNotifier(Edge()).add(Parent::direct(uedge, false));
610 getNotifier(Edge()).clear();
611 getNotifier(UEdge()).clear();
615 void erase(const UEdge& uedge) {
616 getNotifier(Edge()).erase(Parent::direct(uedge, true));
617 getNotifier(Edge()).erase(Parent::direct(uedge, false));
618 getNotifier(UEdge()).erase(uedge);
619 Parent::erase(uedge);
624 edge_notifier.setContainer(*this);
625 uedge_notifier.setContainer(*this);
628 ~UEdgeSetExtender() {
629 uedge_notifier.clear();
630 edge_notifier.clear();