In C++98 array size shall be an integral constant expression. Fixes
ticket 12.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
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_EDGE_SET_H
20 #define LEMON_EDGE_SET_H
23 #include <lemon/bits/default_map.h>
24 #include <lemon/bits/edge_set_extender.h>
26 /// \ingroup semi_adaptors
28 /// \brief EdgeSet classes.
30 /// Graphs which use another graph's node-set as own.
34 template <typename _Graph>
35 class ListEdgeSetBase {
39 typedef typename Graph::Node Node;
40 typedef typename Graph::NodeIt NodeIt;
45 int first_out, first_in;
46 NodeT() : first_out(-1), first_in(-1) {}
49 typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
55 int next_out, next_in;
56 int prev_out, prev_in;
57 EdgeT() : prev_out(-1), prev_in(-1) {}
60 std::vector<EdgeT> edges;
67 void initalize(const Graph& _graph, NodesImplBase& _nodes) {
75 friend class ListEdgeSetBase<Graph>;
77 Edge(int _id) : id(_id) {}
81 Edge(Invalid) : id(-1) {}
82 bool operator==(const Edge& edge) const { return id == edge.id; }
83 bool operator!=(const Edge& edge) const { return id != edge.id; }
84 bool operator<(const Edge& edge) const { return id < edge.id; }
87 ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {}
89 Edge addEdge(const Node& u, const Node& v) {
91 if (first_free_edge == -1) {
93 edges.push_back(EdgeT());
96 first_free_edge = edges[first_free_edge].next_in;
98 edges[n].next_in = (*nodes)[v].first_in;
99 if ((*nodes)[v].first_in != -1) {
100 edges[(*nodes)[v].first_in].prev_in = n;
102 (*nodes)[v].first_in = n;
103 edges[n].next_out = (*nodes)[u].first_out;
104 if ((*nodes)[u].first_out != -1) {
105 edges[(*nodes)[u].first_out].prev_out = n;
107 (*nodes)[u].first_out = n;
113 void erase(const Edge& edge) {
115 if (edges[n].prev_in != -1) {
116 edges[edges[n].prev_in].next_in = edges[n].next_in;
118 (*nodes)[edges[n].target].first_in = edges[n].next_in;
120 if (edges[n].next_in != -1) {
121 edges[edges[n].next_in].prev_in = edges[n].prev_in;
124 if (edges[n].prev_out != -1) {
125 edges[edges[n].prev_out].next_out = edges[n].next_out;
127 (*nodes)[edges[n].source].first_out = edges[n].next_out;
129 if (edges[n].next_out != -1) {
130 edges[edges[n].next_out].prev_out = edges[n].prev_out;
137 for (first(node); node != INVALID; next(node)) {
138 (*nodes)[node].first_in = -1;
139 (*nodes)[node].first_out = -1;
143 first_free_edge = -1;
146 void first(Node& node) const {
150 void next(Node& node) const {
154 void first(Edge& edge) const {
156 for (first(node); node != INVALID && (*nodes)[node].first_in == -1;
158 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
161 void next(Edge& edge) const {
162 if (edges[edge.id].next_in != -1) {
163 edge.id = edges[edge.id].next_in;
165 Node node = edges[edge.id].target;
166 for (next(node); node != INVALID && (*nodes)[node].first_in == -1;
168 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
172 void firstOut(Edge& edge, const Node& node) const {
173 edge.id = (*nodes)[node].first_out;
176 void nextOut(Edge& edge) const {
177 edge.id = edges[edge.id].next_out;
180 void firstIn(Edge& edge, const Node& node) const {
181 edge.id = (*nodes)[node].first_in;
184 void nextIn(Edge& edge) const {
185 edge.id = edges[edge.id].next_in;
188 int id(const Node& node) const { return graph->id(node); }
189 int id(const Edge& edge) const { return edge.id; }
191 Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
192 Edge edgeFromId(int ix) const { return Edge(ix); }
194 int maxNodeId() const { return graph->maxNodeId(); };
195 int maxEdgeId() const { return edges.size() - 1; }
197 Node source(const Edge& edge) const { return edges[edge.id].source;}
198 Node target(const Edge& edge) const { return edges[edge.id].target;}
200 typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
202 NodeNotifier& notifier(Node) const {
203 return graph->notifier(Node());
206 template <typename _Value>
207 class NodeMap : public Graph::template NodeMap<_Value> {
210 typedef typename _Graph::template NodeMap<_Value> Parent;
212 explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset)
213 : Parent(*edgeset.graph) {}
215 NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
216 : Parent(*edgeset.graph, value) {}
218 NodeMap& operator=(const NodeMap& cmap) {
219 return operator=<NodeMap>(cmap);
222 template <typename CMap>
223 NodeMap& operator=(const CMap& cmap) {
224 Parent::operator=(cmap);
231 /// \ingroup semi_adaptors
233 /// \brief Graph using a node set of another graph and an
236 /// This structure can be used to establish another graph over a node set
237 /// of an existing one. The node iterator will go through the nodes of the
240 /// \param _Graph The type of the graph which shares its node set with
241 /// this class. Its interface must conform to the \ref concepts::Graph
244 template <typename _Graph>
245 class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
249 typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
251 typedef typename Parent::Node Node;
252 typedef typename Parent::Edge Edge;
254 typedef _Graph Graph;
257 typedef typename Parent::NodesImplBase NodesImplBase;
259 void eraseNode(const Node& node) {
261 Parent::firstOut(edge, node);
262 while (edge != INVALID ) {
264 Parent::firstOut(edge, node);
267 Parent::firstIn(edge, node);
268 while (edge != INVALID ) {
270 Parent::firstIn(edge, node);
278 class NodesImpl : public NodesImplBase {
280 typedef NodesImplBase Parent;
282 NodesImpl(const Graph& graph, ListEdgeSet& edgeset)
283 : Parent(graph), _edgeset(edgeset) {}
285 virtual ~NodesImpl() {}
289 virtual void erase(const Node& node) {
290 _edgeset.eraseNode(node);
293 virtual void erase(const std::vector<Node>& nodes) {
294 for (int i = 0; i < int(nodes.size()); ++i) {
295 _edgeset.eraseNode(nodes[i]);
297 Parent::erase(nodes);
299 virtual void clear() {
300 _edgeset.clearNodes();
305 ListEdgeSet& _edgeset;
312 /// \brief Constructor of the adaptor.
314 /// Constructor of the adaptor.
315 ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
316 Parent::initalize(graph, nodes);
321 template <typename _Graph>
322 class ListUEdgeSetBase {
325 typedef _Graph Graph;
326 typedef typename Graph::Node Node;
327 typedef typename Graph::NodeIt NodeIt;
333 NodeT() : first_out(-1) {}
336 typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
338 NodesImplBase* nodes;
342 int prev_out, next_out;
343 EdgeT() : prev_out(-1), next_out(-1) {}
346 std::vector<EdgeT> edges;
353 void initalize(const Graph& _graph, NodesImplBase& _nodes) {
361 friend class ListUEdgeSetBase;
365 explicit UEdge(int _id) { id = _id;}
369 UEdge (Invalid) { id = -1; }
370 bool operator==(const UEdge& edge) const {return id == edge.id;}
371 bool operator!=(const UEdge& edge) const {return id != edge.id;}
372 bool operator<(const UEdge& edge) const {return id < edge.id;}
376 friend class ListUEdgeSetBase;
378 Edge(int _id) : id(_id) {}
381 operator UEdge() const { return uEdgeFromId(id / 2); }
384 Edge(Invalid) : id(-1) {}
385 bool operator==(const Edge& edge) const { return id == edge.id; }
386 bool operator!=(const Edge& edge) const { return id != edge.id; }
387 bool operator<(const Edge& edge) const { return id < edge.id; }
390 ListUEdgeSetBase() : first_edge(-1), first_free_edge(-1) {}
392 UEdge addEdge(const Node& u, const Node& v) {
395 if (first_free_edge == -1) {
397 edges.push_back(EdgeT());
398 edges.push_back(EdgeT());
401 first_free_edge = edges[n].next_out;
405 edges[n | 1].target = v;
407 edges[n].next_out = (*nodes)[v].first_out;
408 if ((*nodes)[v].first_out != -1) {
409 edges[(*nodes)[v].first_out].prev_out = n;
411 (*nodes)[v].first_out = n;
412 edges[n].prev_out = -1;
414 if ((*nodes)[u].first_out != -1) {
415 edges[(*nodes)[u].first_out].prev_out = (n | 1);
417 edges[n | 1].next_out = (*nodes)[u].first_out;
418 (*nodes)[u].first_out = (n | 1);
419 edges[n | 1].prev_out = -1;
424 void erase(const UEdge& edge) {
427 if (edges[n].next_out != -1) {
428 edges[edges[n].next_out].prev_out = edges[n].prev_out;
431 if (edges[n].prev_out != -1) {
432 edges[edges[n].prev_out].next_out = edges[n].next_out;
434 (*nodes)[edges[n | 1].target].first_out = edges[n].next_out;
437 if (edges[n | 1].next_out != -1) {
438 edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
441 if (edges[n | 1].prev_out != -1) {
442 edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
444 (*nodes)[edges[n].target].first_out = edges[n | 1].next_out;
447 edges[n].next_out = first_free_edge;
454 for (first(node); node != INVALID; next(node)) {
455 (*nodes)[node].first_out = -1;
459 first_free_edge = -1;
462 void first(Node& node) const {
466 void next(Node& node) const {
470 void first(Edge& edge) const {
473 while (node != INVALID && (*nodes)[node].first_out == -1) {
476 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
479 void next(Edge& edge) const {
480 if (edges[edge.id].next_out != -1) {
481 edge.id = edges[edge.id].next_out;
483 Node node = edges[edge.id ^ 1].target;
485 while(node != INVALID && (*nodes)[node].first_out == -1) {
488 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
492 void first(UEdge& uedge) const {
495 while (node != INVALID) {
496 uedge.id = (*nodes)[node].first_out;
497 while ((uedge.id & 1) != 1) {
498 uedge.id = edges[uedge.id].next_out;
500 if (uedge.id != -1) {
509 void next(UEdge& uedge) const {
510 Node node = edges[uedge.id * 2].target;
511 uedge.id = edges[(uedge.id * 2) | 1].next_out;
512 while ((uedge.id & 1) != 1) {
513 uedge.id = edges[uedge.id].next_out;
515 if (uedge.id != -1) {
520 while (node != INVALID) {
521 uedge.id = (*nodes)[node].first_out;
522 while ((uedge.id & 1) != 1) {
523 uedge.id = edges[uedge.id].next_out;
525 if (uedge.id != -1) {
534 void firstOut(Edge& edge, const Node& node) const {
535 edge.id = (*nodes)[node].first_out;
538 void nextOut(Edge& edge) const {
539 edge.id = edges[edge.id].next_out;
542 void firstIn(Edge& edge, const Node& node) const {
543 edge.id = (((*nodes)[node].first_out) ^ 1);
544 if (edge.id == -2) edge.id = -1;
547 void nextIn(Edge& edge) const {
548 edge.id = ((edges[edge.id ^ 1].next_out) ^ 1);
549 if (edge.id == -2) edge.id = -1;
552 void firstInc(UEdge &edge, bool& dir, const Node& node) const {
553 int de = (*nodes)[node].first_out;
556 dir = ((de & 1) == 1);
562 void nextInc(UEdge &edge, bool& dir) const {
563 int de = (edges[(edge.id * 2) | (dir ? 1 : 0)].next_out);
566 dir = ((de & 1) == 1);
573 static bool direction(Edge edge) {
574 return (edge.id & 1) == 1;
577 static Edge direct(UEdge uedge, bool dir) {
578 return Edge(uedge.id * 2 + (dir ? 1 : 0));
581 int id(const Node& node) const { return graph->id(node); }
582 static int id(Edge e) { return e.id; }
583 static int id(UEdge e) { return e.id; }
585 Node nodeFromId(int id) const { return graph->nodeFromId(id); }
586 static Edge edgeFromId(int id) { return Edge(id);}
587 static UEdge uEdgeFromId(int id) { return UEdge(id);}
589 int maxNodeId() const { return graph->maxNodeId(); };
590 int maxUEdgeId() const { return edges.size() / 2 - 1; }
591 int maxEdgeId() const { return edges.size()-1; }
593 Node source(Edge e) const { return edges[e.id ^ 1].target; }
594 Node target(Edge e) const { return edges[e.id].target; }
596 Node source(UEdge e) const { return edges[2 * e.id].target; }
597 Node target(UEdge e) const { return edges[2 * e.id + 1].target; }
599 typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
601 NodeNotifier& notifier(Node) const {
602 return graph->notifier(Node());
605 template <typename _Value>
606 class NodeMap : public Graph::template NodeMap<_Value> {
609 typedef typename _Graph::template NodeMap<_Value> Parent;
611 explicit NodeMap(const ListUEdgeSetBase<Graph>& edgeset)
612 : Parent(*edgeset.graph) {}
614 NodeMap(const ListUEdgeSetBase<Graph>& edgeset, const _Value& value)
615 : Parent(*edgeset.graph, value) {}
617 NodeMap& operator=(const NodeMap& cmap) {
618 return operator=<NodeMap>(cmap);
621 template <typename CMap>
622 NodeMap& operator=(const CMap& cmap) {
623 Parent::operator=(cmap);
630 /// \ingroup semi_adaptors
632 /// \brief Graph using a node set of another graph and an
635 /// This structure can be used to establish another graph over a node set
636 /// of an existing one. The node iterator will go through the nodes of the
639 /// \param _Graph The type of the graph which shares its node set with
640 /// this class. Its interface must conform to the \ref concepts::Graph
643 /// In the edge extension and removing it conforms to the
644 /// \ref concepts::UGraph "UGraph" concept.
645 template <typename _Graph>
646 class ListUEdgeSet : public UEdgeSetExtender<ListUEdgeSetBase<_Graph> > {
650 typedef UEdgeSetExtender<ListUEdgeSetBase<_Graph> > Parent;
652 typedef typename Parent::Node Node;
653 typedef typename Parent::Edge Edge;
655 typedef _Graph Graph;
658 typedef typename Parent::NodesImplBase NodesImplBase;
660 void eraseNode(const Node& node) {
662 Parent::firstOut(edge, node);
663 while (edge != INVALID ) {
665 Parent::firstOut(edge, node);
674 class NodesImpl : public NodesImplBase {
676 typedef NodesImplBase Parent;
678 NodesImpl(const Graph& graph, ListUEdgeSet& edgeset)
679 : Parent(graph), _edgeset(edgeset) {}
681 virtual ~NodesImpl() {}
685 virtual void erase(const Node& node) {
686 _edgeset.eraseNode(node);
689 virtual void erase(const std::vector<Node>& nodes) {
690 for (int i = 0; i < int(nodes.size()); ++i) {
691 _edgeset.eraseNode(nodes[i]);
693 Parent::erase(nodes);
695 virtual void clear() {
696 _edgeset.clearNodes();
701 ListUEdgeSet& _edgeset;
708 /// \brief Constructor of the adaptor.
710 /// Constructor of the adaptor.
711 ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
712 Parent::initalize(graph, nodes);
717 template <typename _Graph>
718 class SmartEdgeSetBase {
721 typedef _Graph Graph;
722 typedef typename Graph::Node Node;
723 typedef typename Graph::NodeIt NodeIt;
728 int first_out, first_in;
729 NodeT() : first_out(-1), first_in(-1) {}
732 typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
734 NodesImplBase* nodes;
738 int next_out, next_in;
742 std::vector<EdgeT> edges;
746 void initalize(const Graph& _graph, NodesImplBase& _nodes) {
754 friend class SmartEdgeSetBase<Graph>;
756 Edge(int _id) : id(_id) {}
760 Edge(Invalid) : id(-1) {}
761 bool operator==(const Edge& edge) const { return id == edge.id; }
762 bool operator!=(const Edge& edge) const { return id != edge.id; }
763 bool operator<(const Edge& edge) const { return id < edge.id; }
766 SmartEdgeSetBase() {}
768 Edge addEdge(const Node& u, const Node& v) {
769 int n = edges.size();
770 edges.push_back(EdgeT());
771 edges[n].next_in = (*nodes)[v].first_in;
772 (*nodes)[v].first_in = n;
773 edges[n].next_out = (*nodes)[u].first_out;
774 (*nodes)[u].first_out = n;
782 for (first(node); node != INVALID; next(node)) {
783 (*nodes)[node].first_in = -1;
784 (*nodes)[node].first_out = -1;
789 void first(Node& node) const {
793 void next(Node& node) const {
797 void first(Edge& edge) const {
798 edge.id = edges.size() - 1;
801 void next(Edge& edge) const {
805 void firstOut(Edge& edge, const Node& node) const {
806 edge.id = (*nodes)[node].first_out;
809 void nextOut(Edge& edge) const {
810 edge.id = edges[edge.id].next_out;
813 void firstIn(Edge& edge, const Node& node) const {
814 edge.id = (*nodes)[node].first_in;
817 void nextIn(Edge& edge) const {
818 edge.id = edges[edge.id].next_in;
821 int id(const Node& node) const { return graph->id(node); }
822 int id(const Edge& edge) const { return edge.id; }
824 Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
825 Edge edgeFromId(int ix) const { return Edge(ix); }
827 int maxNodeId() const { return graph->maxNodeId(); };
828 int maxEdgeId() const { return edges.size() - 1; }
830 Node source(const Edge& edge) const { return edges[edge.id].source;}
831 Node target(const Edge& edge) const { return edges[edge.id].target;}
833 typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
835 NodeNotifier& notifier(Node) const {
836 return graph->notifier(Node());
839 template <typename _Value>
840 class NodeMap : public Graph::template NodeMap<_Value> {
843 typedef typename _Graph::template NodeMap<_Value> Parent;
845 explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset)
846 : Parent(*edgeset.graph) { }
848 NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
849 : Parent(*edgeset.graph, value) { }
851 NodeMap& operator=(const NodeMap& cmap) {
852 return operator=<NodeMap>(cmap);
855 template <typename CMap>
856 NodeMap& operator=(const CMap& cmap) {
857 Parent::operator=(cmap);
865 /// \ingroup semi_adaptors
867 /// \brief Graph using a node set of another graph and an
870 /// This structure can be used to establish another graph over a node set
871 /// of an existing one. The node iterator will go through the nodes of the
874 /// \param _Graph The type of the graph which shares its node set with
875 /// this class. Its interface must conform to the \ref concepts::Graph
878 /// In the edge extension and removing it conforms to the
879 /// \ref concepts::Graph "Graph" concept.
880 template <typename _Graph>
881 class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
885 typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
887 typedef typename Parent::Node Node;
888 typedef typename Parent::Edge Edge;
890 typedef _Graph Graph;
894 typedef typename Parent::NodesImplBase NodesImplBase;
896 void eraseNode(const Node& node) {
897 if (Parent::InEdgeIt(*this, node) == INVALID &&
898 Parent::OutEdgeIt(*this, node) == INVALID) {
901 throw typename NodesImplBase::Notifier::ImmediateDetach();
908 class NodesImpl : public NodesImplBase {
910 typedef NodesImplBase Parent;
912 NodesImpl(const Graph& graph, SmartEdgeSet& edgeset)
913 : Parent(graph), _edgeset(edgeset) {}
915 virtual ~NodesImpl() {}
917 bool attached() const {
918 return Parent::attached();
923 virtual void erase(const Node& node) {
925 _edgeset.eraseNode(node);
927 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
932 virtual void erase(const std::vector<Node>& nodes) {
934 for (int i = 0; i < int(nodes.size()); ++i) {
935 _edgeset.eraseNode(nodes[i]);
937 Parent::erase(nodes);
938 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
943 virtual void clear() {
944 _edgeset.clearNodes();
949 SmartEdgeSet& _edgeset;
956 /// \brief Constructor of the adaptor.
958 /// Constructor of the adaptor.
959 SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
960 Parent::initalize(graph, nodes);
964 return nodes.attached();
970 template <typename _Graph>
971 class SmartUEdgeSetBase {
974 typedef _Graph Graph;
975 typedef typename Graph::Node Node;
976 typedef typename Graph::NodeIt NodeIt;
982 NodeT() : first_out(-1) {}
985 typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
987 NodesImplBase* nodes;
995 std::vector<EdgeT> edges;
999 void initalize(const Graph& _graph, NodesImplBase& _nodes) {
1007 friend class SmartUEdgeSetBase;
1011 explicit UEdge(int _id) { id = _id;}
1015 UEdge (Invalid) { id = -1; }
1016 bool operator==(const UEdge& edge) const {return id == edge.id;}
1017 bool operator!=(const UEdge& edge) const {return id != edge.id;}
1018 bool operator<(const UEdge& edge) const {return id < edge.id;}
1022 friend class SmartUEdgeSetBase;
1024 Edge(int _id) : id(_id) {}
1027 operator UEdge() const { return uEdgeFromId(id / 2); }
1030 Edge(Invalid) : id(-1) {}
1031 bool operator==(const Edge& edge) const { return id == edge.id; }
1032 bool operator!=(const Edge& edge) const { return id != edge.id; }
1033 bool operator<(const Edge& edge) const { return id < edge.id; }
1036 SmartUEdgeSetBase() {}
1038 UEdge addEdge(const Node& u, const Node& v) {
1039 int n = edges.size();
1040 edges.push_back(EdgeT());
1041 edges.push_back(EdgeT());
1043 edges[n].target = u;
1044 edges[n | 1].target = v;
1046 edges[n].next_out = (*nodes)[v].first_out;
1047 (*nodes)[v].first_out = n;
1049 edges[n | 1].next_out = (*nodes)[u].first_out;
1050 (*nodes)[u].first_out = (n | 1);
1052 return UEdge(n / 2);
1057 for (first(node); node != INVALID; next(node)) {
1058 (*nodes)[node].first_out = -1;
1063 void first(Node& node) const {
1067 void next(Node& node) const {
1071 void first(Edge& edge) const {
1072 edge.id = edges.size() - 1;
1075 void next(Edge& edge) const {
1079 void first(UEdge& edge) const {
1080 edge.id = edges.size() / 2 - 1;
1083 void next(UEdge& edge) const {
1087 void firstOut(Edge& edge, const Node& node) const {
1088 edge.id = (*nodes)[node].first_out;
1091 void nextOut(Edge& edge) const {
1092 edge.id = edges[edge.id].next_out;
1095 void firstIn(Edge& edge, const Node& node) const {
1096 edge.id = (((*nodes)[node].first_out) ^ 1);
1097 if (edge.id == -2) edge.id = -1;
1100 void nextIn(Edge& edge) const {
1101 edge.id = ((edges[edge.id ^ 1].next_out) ^ 1);
1102 if (edge.id == -2) edge.id = -1;
1105 void firstInc(UEdge &edge, bool& dir, const Node& node) const {
1106 int de = (*nodes)[node].first_out;
1109 dir = ((de & 1) == 1);
1115 void nextInc(UEdge &edge, bool& dir) const {
1116 int de = (edges[(edge.id * 2) | (dir ? 1 : 0)].next_out);
1119 dir = ((de & 1) == 1);
1126 static bool direction(Edge edge) {
1127 return (edge.id & 1) == 1;
1130 static Edge direct(UEdge uedge, bool dir) {
1131 return Edge(uedge.id * 2 + (dir ? 1 : 0));
1134 int id(Node node) const { return graph->id(node); }
1135 static int id(Edge edge) { return edge.id; }
1136 static int id(UEdge edge) { return edge.id; }
1138 Node nodeFromId(int id) const { return graph->nodeFromId(id); }
1139 static Edge edgeFromId(int id) { return Edge(id); }
1140 static UEdge uEdgeFromId(int id) { return UEdge(id);}
1142 int maxNodeId() const { return graph->maxNodeId(); };
1143 int maxEdgeId() const { return edges.size() - 1; }
1144 int maxUEdgeId() const { return edges.size() / 2 - 1; }
1146 Node source(Edge e) const { return edges[e.id ^ 1].target; }
1147 Node target(Edge e) const { return edges[e.id].target; }
1149 Node source(UEdge e) const { return edges[2 * e.id].target; }
1150 Node target(UEdge e) const { return edges[2 * e.id + 1].target; }
1152 typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
1154 NodeNotifier& notifier(Node) const {
1155 return graph->notifier(Node());
1158 template <typename _Value>
1159 class NodeMap : public Graph::template NodeMap<_Value> {
1162 typedef typename _Graph::template NodeMap<_Value> Parent;
1164 explicit NodeMap(const SmartUEdgeSetBase<Graph>& edgeset)
1165 : Parent(*edgeset.graph) { }
1167 NodeMap(const SmartUEdgeSetBase<Graph>& edgeset, const _Value& value)
1168 : Parent(*edgeset.graph, value) { }
1170 NodeMap& operator=(const NodeMap& cmap) {
1171 return operator=<NodeMap>(cmap);
1174 template <typename CMap>
1175 NodeMap& operator=(const CMap& cmap) {
1176 Parent::operator=(cmap);
1183 /// \ingroup semi_adaptors
1185 /// \brief Graph using a node set of another graph and an
1188 /// This structure can be used to establish another graph over a node set
1189 /// of an existing one. The node iterator will go through the nodes of the
1192 /// \param _Graph The type of the graph which shares its node set with
1193 /// this class. Its interface must conform to the \ref concepts::Graph
1194 /// "Graph" concept.
1196 /// In the edge extension and removing it conforms to the
1197 /// \ref concepts::UGraph "UGraph" concept.
1198 template <typename _Graph>
1199 class SmartUEdgeSet : public UEdgeSetExtender<SmartUEdgeSetBase<_Graph> > {
1203 typedef UEdgeSetExtender<SmartUEdgeSetBase<_Graph> > Parent;
1205 typedef typename Parent::Node Node;
1206 typedef typename Parent::Edge Edge;
1208 typedef _Graph Graph;
1212 typedef typename Parent::NodesImplBase NodesImplBase;
1214 void eraseNode(const Node& node) {
1215 if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
1218 throw typename NodesImplBase::Notifier::ImmediateDetach();
1225 class NodesImpl : public NodesImplBase {
1227 typedef NodesImplBase Parent;
1229 NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset)
1230 : Parent(graph), _edgeset(edgeset) {}
1232 virtual ~NodesImpl() {}
1234 bool attached() const {
1235 return Parent::attached();
1240 virtual void erase(const Node& node) {
1242 _edgeset.eraseNode(node);
1243 Parent::erase(node);
1244 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1249 virtual void erase(const std::vector<Node>& nodes) {
1251 for (int i = 0; i < int(nodes.size()); ++i) {
1252 _edgeset.eraseNode(nodes[i]);
1254 Parent::erase(nodes);
1255 } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1260 virtual void clear() {
1261 _edgeset.clearNodes();
1266 SmartUEdgeSet& _edgeset;
1273 /// \brief Constructor of the adaptor.
1275 /// Constructor of the adaptor.
1276 SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
1277 Parent::initalize(graph, nodes);
1280 bool valid() const {
1281 return nodes.attached();