Ticket #325: stl-iterators-V2-15af6cbd7751.patch
File stl-iterators-V2-15af6cbd7751.patch, 58.1 KB (added by , 11 years ago) |
---|
-
contrib/stlit_test/stlit_test.cc
# HG changeset patch # User Gabor Gevay <ggab90@gmail.com> # Date 1389902120 -3600 # Thu Jan 16 20:55:20 2014 +0100 # Node ID 15af6cbd77513ccf5ebcff573c1275858c6dd166 # Parent be9aea8c23aef50ccebb617f98c7b541b12cd3f2 Proof of concept implementation of STL style iterators V2 (#325) diff --git a/contrib/stlit_test/stlit_test.cc b/contrib/stlit_test/stlit_test.cc
a b 4 4 5 5 #include <iostream> 6 6 #include <lemon/list_graph.h> 7 #include <lemon/ stl_iterators.h>7 #include <lemon/bits/stl_iterators.h> 8 8 9 9 10 10 using namespace std; … … 21 21 22 22 23 23 // //for(ListDigraph::NodeIt u(g); u!=INVALID; ++u) 24 // for(auto u: g.node Coll())24 // for(auto u: g.nodes()) 25 25 // cout<<g.id(u)<<endl; 26 26 27 27 … … 30 30 for(int k=0; k<100000; k++){ 31 31 int i=0; 32 32 for(ListDigraph::NodeIt u(g); u!=INVALID; ++u){ 33 //for(auto u: g.node Coll()){33 //for(auto u: g.nodes()){ 34 34 v[i]=u; 35 35 i++; 36 36 } … … 57 57 for(int i=0; i<n; i++) 58 58 g.addNode(); 59 59 60 for(auto u: g.node Coll())60 for(auto u: g.nodes()) 61 61 cout<<g.id(u)<<endl; 62 62 63 //Test postincrement 64 // for(auto it=g.nodeColl().begin(); it!=g.nodeColl().end(); it++) { 65 // auto u=*it; 66 // cout<<g.id(u)<<endl; 67 // } 68 63 /*//Test postincrement 64 for(auto it=g.nodes().begin(); it!=g.nodes().end(); it++) { 65 auto u=*it; 66 cout<<g.id(u)<<endl; 67 }*/ 69 68 70 69 71 70 cout<<endl; 72 71 73 72 vector<ListDigraph::Node> v1(n); 74 copy(g.node Coll().begin(), g.nodeColl().end(), v1.begin());73 copy(g.nodes().begin(), g.nodes().end(), v1.begin()); 75 74 76 vector<ListDigraph::Node> v(g.node Coll().begin(), g.nodeColl().end());75 vector<ListDigraph::Node> v(g.nodes().begin(), g.nodes().end()); 77 76 g.addArc(v[0],v[1]); 78 77 g.addArc(v[0],v[2]); 79 78 … … 83 82 cout<<endl; 84 83 85 84 86 ToStlit<ListDigraph::NodeIt> st1 = g.nodeColl().begin();87 //auto st1 = g.node Coll().begin();85 LemonItWrapper<ListDigraph::NodeIt> st1 = g.nodes().begin(); 86 //auto st1 = g.nodes().begin(); 88 87 auto st2 = st1; //test assignment 89 88 ++st1; //test preincrement 90 89 st1++; //test postincrement … … 94 93 95 94 st1->operator==(st2); 96 95 96 97 ListGraph g2; 98 for(auto u: g2.nodes()) 99 cout<<g2.id(u)<<endl; 100 for(auto a: g2.outArcs(*g2.nodes().begin())) 101 cout<<g2.id(g2.target(a))<<endl; 102 97 103 return 0; 98 104 } -
lemon/bits/graph_extender.h
diff --git a/lemon/bits/graph_extender.h b/lemon/bits/graph_extender.h
a b 27 27 #include <lemon/concept_check.h> 28 28 #include <lemon/concepts/maps.h> 29 29 30 #include <lemon/ stl_iterators.h>30 #include <lemon/bits/stl_iterators.h> 31 31 32 32 //\ingroup graphbits 33 33 //\file … … 118 118 119 119 }; 120 120 121 Lemon itWrapper1<NodeIt, Digraph> nodeColl(){122 return Lemon itWrapper1<NodeIt, Digraph>(*this);121 LemonRangeWrapper1<NodeIt, Digraph> nodes() const { 122 return LemonRangeWrapper1<NodeIt, Digraph>(*this); 123 123 } 124 124 125 125 126 class ArcIt : public Arc { 126 127 const Digraph* _digraph; 127 128 public: … … 144 145 145 146 }; 146 147 148 LemonRangeWrapper1<ArcIt, Digraph> arcs() const { 149 return LemonRangeWrapper1<ArcIt, Digraph>(*this); 150 } 151 147 152 148 153 class OutArcIt : public Arc { 149 154 const Digraph* _digraph; … … 168 173 169 174 }; 170 175 171 Lemon itWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u){172 return Lemon itWrapper2<OutArcIt, Digraph, Node>(*this, u);176 LemonRangeWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u) const { 177 return LemonRangeWrapper2<OutArcIt, Digraph, Node>(*this, u); 173 178 } 174 179 175 180 … … 196 201 197 202 }; 198 203 204 LemonRangeWrapper2<InArcIt, Digraph, Node> inArcs(const Node& u) const { 205 return LemonRangeWrapper2<InArcIt, Digraph, Node>(*this, u); 206 } 207 199 208 // \brief Base node of the iterator 200 209 // 201 210 // Returns the base node (i.e. the source in this case) of the iterator … … 445 454 446 455 }; 447 456 457 LemonRangeWrapper1<NodeIt, Graph> nodes() const { 458 return LemonRangeWrapper1<NodeIt, Graph>(*this); 459 } 460 448 461 449 462 class ArcIt : public Arc { 450 463 const Graph* _graph; … … 468 481 469 482 }; 470 483 484 LemonRangeWrapper1<ArcIt, Graph> arcs() const { 485 return LemonRangeWrapper1<ArcIt, Graph>(*this); 486 } 487 471 488 472 489 class OutArcIt : public Arc { 473 490 const Graph* _graph; … … 492 509 493 510 }; 494 511 512 LemonRangeWrapper2<OutArcIt, Graph, Node> outArcs(const Node& u) const { 513 return LemonRangeWrapper2<OutArcIt, Graph, Node>(*this, u); 514 } 515 495 516 496 517 class InArcIt : public Arc { 497 518 const Graph* _graph; … … 516 537 517 538 }; 518 539 540 LemonRangeWrapper2<InArcIt, Graph, Node> inArcs(const Node& u) const { 541 return LemonRangeWrapper2<InArcIt, Graph, Node>(*this, u); 542 } 543 519 544 520 545 class EdgeIt : public Parent::Edge { 521 546 const Graph* _graph; … … 539 564 540 565 }; 541 566 567 LemonRangeWrapper1<EdgeIt, Graph> edges() const { 568 return LemonRangeWrapper1<EdgeIt, Graph>(*this); 569 } 570 571 542 572 class IncEdgeIt : public Parent::Edge { 543 573 friend class GraphExtender; 544 574 const Graph* _graph; … … 564 594 } 565 595 }; 566 596 597 LemonRangeWrapper2<IncEdgeIt, Graph, Node> incEdges(const Node& u) const { 598 return LemonRangeWrapper2<IncEdgeIt, Graph, Node>(*this, u); 599 } 600 601 567 602 // \brief Base node of the iterator 568 603 // 569 604 // Returns the base node (ie. the source in this case) of the iterator -
stl_iterators.h
diff --git a/lemon/stl_iterators.h b/lemon/bits/stl_iterators.h rename from lemon/stl_iterators.h rename to lemon/bits/stl_iterators.h
old new 1 1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 2 */ 3 3 4 #ifndef LEMON_ITERATOR_WRAPPERS_H_5 #define LEMON_ITERATOR_WRAPPERS_H_4 #ifndef STL_ITERATORS_H_ 5 #define STL_ITERATORS_H_ 6 6 7 7 #include <lemon/core.h> 8 8 … … 16 16 /// (so that STL algorithms work). 17 17 /// \c T should be the lemon iterator to be decorated. 18 18 template<class T> 19 struct ToStlit19 struct LemonItWrapper 20 20 : public T, public std::iterator<std::input_iterator_tag, T> { 21 21 22 ToStlit(const T &x) : T(x) {}22 LemonItWrapper(const T &x) : T(x) {} 23 23 24 24 //Lemon iterators don't have operator*, (because they rather 25 25 //inherit from their "value_type"), 26 26 //so we add one that just returns the object. 27 27 const T& operator*() const { 28 return *this;28 return static_cast<const T&>(*this); 29 29 } 30 30 31 31 //I can't think of any use case for this with Lemon iterators, 32 32 //but maybe it should be included for completeness. 33 T* operator->() {34 return this;33 const T* operator->() { 34 return static_cast<const T*>(this); 35 35 } 36 36 37 37 //Lemon iterators don't have postincrement. 38 38 void operator++(int) { 39 39 T::operator++(); 40 40 } 41 //We also have to redefine preincrement, because it disappeared 42 //when postincrement was defined. 43 T& operator++() { 44 return T::operator++(); 45 } 41 42 using T::operator++; 46 43 47 44 }; 48 45 … … 57 54 /// \c LIT is the Lemon iterator that will be wrapped 58 55 /// \c P is the type of the parameter of the constructor of \c LIT. 59 56 template<class LIT, class P> 60 class Lemon itWrapper1{57 class LemonRangeWrapper1{ 61 58 const P &_p; 62 typedef ToStlit<LIT> It;59 typedef LemonItWrapper<LIT> It; 63 60 public: 64 Lemon itWrapper1(const P &p) : _p(p) {}61 LemonRangeWrapper1(const P &p) : _p(p) {} 65 62 It begin() const { 66 63 return It(LIT(_p)); 67 64 } … … 70 67 } 71 68 }; 72 69 73 /*74 /// \brief Gets the collection of nodes of a graph.75 ///76 /// This function can be used for iterating on77 /// the nodes of a graph. It returns a wrapped NodeIt, which looks like78 /// an STL container (by having begin() and end())79 /// which you can use in range-based for loops, stl algorithms, etc.80 /// For example you can write:81 ///\code82 /// ListDigraph g;83 /// for(auto v: nodeColl(g))84 /// doSomething(v);85 ///86 /// //Using an STL algorithm:87 /// copy(nodes(g).begin(), nodes(g).end(), vect);88 ///\endcode89 template<class GR>90 LemonitWrapper1<typename GR::NodeIt, GR> nodeColl(const GR &g){91 return LemonitWrapper1<typename GR::NodeIt, GR>(g);92 }93 */94 70 95 71 /// \brief A generic wrapper for Lemon iterators for range-based for loops. 96 72 /// … … 103 79 /// \c P1 and \c P2 are the types of the parameters 104 80 /// of the constructor of \c LIT. 105 81 template<class LIT, class P1, class P2> 106 class Lemon itWrapper2{82 class LemonRangeWrapper2{ 107 83 const P1 &_p1; 108 84 const P2 &_p2; 109 typedef ToStlit<LIT> It;85 typedef LemonItWrapper<LIT> It; 110 86 public: 111 Lemon itWrapper2(const P1 &p1, const P2 &p2) : _p1(p1), _p2(p2) {}87 LemonRangeWrapper2(const P1 &p1, const P2 &p2) : _p1(p1), _p2(p2) {} 112 88 It begin() const { 113 89 return It(LIT(_p1, _p2)); 114 90 } … … 117 93 } 118 94 }; 119 95 120 /*template<class GR>121 LemonitWrapper2<typename GR::OutArcIt, GR, typename GR::Node>122 outArcs(const GR &g, typename GR::Node n){123 return LemonitWrapper2<typename GR::OutArcIt, GR, typename GR::Node>(g,n);124 }*/125 126 127 128 129 130 131 /*132 //This is a variadic template version of LemonitWrapper,133 //to avoid having separate classes for 1 and 2 parameter versions.134 //The drawback of this is that it would require a C++11 compiler.135 136 #include <tuple>137 138 template<class LIT, class... P>139 class LemonitWrapper {140 const std::tuple<const P&...> _p;141 typedef ToStlit<LIT> It;142 143 //This is based on http://stackoverflow.com/a/7858971/708357144 template<int ...> struct Seq {};145 template<int N, int ...S> struct Gens : Gens<N-1, N-1, S...> {};146 template<int ...S> struct Gens<0, S...>{ typedef Seq<S...> Type; };147 template<int ...S> It callConstr(Seq<S...>) const {148 return LIT(std::get<S>(_p)...);149 }150 public:151 LemonitWrapper(const P&... p) : _p(p...) {}152 153 It begin() const {154 return It(callConstr(typename Gens<sizeof...(P)>::Type()));155 }156 It end() const {157 return It(lemon::INVALID);158 }159 };160 161 162 template<class GR>163 LemonitWrapper<typename GR::NodeIt, GR> nodes___var(const GR &g){164 return LemonitWrapper<typename GR::NodeIt, GR>(g);165 }166 167 template<class GR>168 LemonitWrapper<typename GR::OutArcIt, GR, typename GR::Node>169 outArcs___var(const GR &g, typename GR::Node n){170 return LemonitWrapper<typename GR::OutArcIt, GR, typename GR::Node>(g,n);171 }172 */173 96 174 97 } 175 98 176 #endif /* LEMON_ITERATOR_WRAPPERS_H_ */99 #endif /* STL_ITERATORS_H_ */ -
lemon/concepts/digraph.h
diff --git a/lemon/concepts/digraph.h b/lemon/concepts/digraph.h
a b 27 27 #include <lemon/concepts/maps.h> 28 28 #include <lemon/concept_check.h> 29 29 #include <lemon/concepts/graph_components.h> 30 #include <lemon/ stl_iterators.h>30 #include <lemon/bits/stl_iterators.h> 31 31 32 32 namespace lemon { 33 33 namespace concepts { … … 157 157 /// For example you can write: 158 158 ///\code 159 159 /// ListDigraph g; 160 /// for(auto v: g.node Coll())160 /// for(auto v: g.nodes()) 161 161 /// doSomething(v); 162 162 /// 163 163 /// //Using an STL algorithm: 164 /// copy(g.node Coll().begin(), g.nodeColl().end(), vect.begin());164 /// copy(g.nodes().begin(), g.nodes().end(), vect.begin()); 165 165 ///\endcode 166 Lemon itWrapper1<NodeIt, Digraph> nodeColl(){167 return Lemon itWrapper1<NodeIt, Digraph>(*this);166 LemonRangeWrapper1<NodeIt, Digraph> nodes() const { 167 return LemonRangeWrapper1<NodeIt, Digraph>(*this); 168 168 } 169 169 170 170 … … 257 257 OutArcIt& operator++() { return *this; } 258 258 }; 259 259 260 LemonitWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u){ 261 return LemonitWrapper2<OutArcIt, Digraph, Node>(*this, u); 260 /// \brief Gets the collection of the outgoing arcs of a certain node 261 /// of the digraph. 262 /// 263 /// This function can be used for iterating on the 264 /// outgoing arcs of a certain node of the digraph. It returns a wrapped 265 /// OutArcIt, which looks like an STL container 266 /// (by having begin() and end()) which you can use in range-based 267 /// for loops, stl algorithms, etc. 268 /// For example if g is a Digraph and u is a node, you can write: 269 ///\code 270 /// for(auto a: g.outArcs(u)) 271 /// doSomething(a); 272 /// 273 /// //Using an STL algorithm: 274 /// copy(g.outArcs(u).begin(), g.outArcs(u).end(), vect.begin()); 275 ///\endcode 276 LemonRangeWrapper2<OutArcIt, Digraph, Node> outArcs(const Node& u) const { 277 return LemonRangeWrapper2<OutArcIt, Digraph, Node>(*this, u); 262 278 } 263 279 264 280 … … 307 323 InArcIt& operator++() { return *this; } 308 324 }; 309 325 326 /// \brief Gets the collection of the incoming arcs of a certain node 327 /// of the digraph. 328 /// 329 /// This function can be used for iterating on the 330 /// incoming arcs of a certain node of the digraph. It returns a wrapped 331 /// InArcIt, which looks like an STL container 332 /// (by having begin() and end()) which you can use in range-based 333 /// for loops, stl algorithms, etc. 334 /// For example if g is a Digraph and u is a node, you can write: 335 ///\code 336 /// for(auto a: g.inArcs(u)) 337 /// doSomething(a); 338 /// 339 /// //Using an STL algorithm: 340 /// copy(g.inArcs(u).begin(), g.inArcs(u).end(), vect.begin()); 341 ///\endcode 342 LemonRangeWrapper2<InArcIt, Digraph, Node> inArcs(const Node& u) const { 343 return LemonRangeWrapper2<InArcIt, Digraph, Node>(*this, u); 344 } 345 346 310 347 /// Iterator class for the arcs. 311 348 312 349 /// This iterator goes through each arc of the digraph. … … 352 389 ArcIt& operator++() { return *this; } 353 390 }; 354 391 392 /// \brief Gets the collection of the arcs of the digraph. 393 /// 394 /// This function can be used for iterating on the 395 /// arcs of the digraph. It returns a wrapped 396 /// ArcIt, which looks like an STL container 397 /// (by having begin() and end()) which you can use in range-based 398 /// for loops, stl algorithms, etc. 399 /// For example you can write: 400 ///\code 401 /// ListDigraph g; 402 /// for(auto a: g.arcs()) 403 /// doSomething(a); 404 /// 405 /// //Using an STL algorithm: 406 /// copy(g.arcs().begin(), g.arcs().end(), vect.begin()); 407 ///\endcode 408 LemonRangeWrapper1<ArcIt, Digraph> arcs() const { 409 return LemonRangeWrapper1<ArcIt, Digraph>(*this); 410 } 411 412 355 413 /// \brief The source node of the arc. 356 414 /// 357 415 /// Returns the source node of the given arc. -
lemon/concepts/graph.h
diff --git a/lemon/concepts/graph.h b/lemon/concepts/graph.h
a b 180 180 NodeIt& operator++() { return *this; } 181 181 }; 182 182 183 /// \brief Gets the collection of the nodes of the graph. 184 /// 185 /// This function can be used for iterating on 186 /// the nodes of the graph. It returns a wrapped NodeIt, which looks 187 /// like an STL container (by having begin() and end()) 188 /// which you can use in range-based for loops, stl algorithms, etc. 189 /// For example you can write: 190 ///\code 191 /// ListGraph g; 192 /// for(auto v: g.nodes()) 193 /// doSomething(v); 194 /// 195 /// //Using an STL algorithm: 196 /// copy(g.nodes().begin(), g.nodes().end(), vect.begin()); 197 ///\endcode 198 LemonRangeWrapper1<NodeIt, Graph> nodes() const { 199 return LemonRangeWrapper1<NodeIt, Graph>(*this); 200 } 201 183 202 184 203 /// The edge type of the graph 185 204 … … 268 287 EdgeIt& operator++() { return *this; } 269 288 }; 270 289 290 /// \brief Gets the collection of the edges of the graph. 291 /// 292 /// This function can be used for iterating on the 293 /// edges of the graph. It returns a wrapped 294 /// EdgeIt, which looks like an STL container 295 /// (by having begin() and end()) which you can use in range-based 296 /// for loops, stl algorithms, etc. 297 /// For example you can write: 298 ///\code 299 /// ListGraph g; 300 /// for(auto e: g.edges()) 301 /// doSomething(e); 302 /// 303 /// //Using an STL algorithm: 304 /// copy(g.edges().begin(), g.edges().end(), vect.begin()); 305 ///\endcode 306 LemonRangeWrapper1<EdgeIt, Graph> edges() const { 307 return LemonRangeWrapper1<EdgeIt, Graph>(*this); 308 } 309 310 271 311 /// Iterator class for the incident edges of a node. 272 312 273 313 /// This iterator goes trough the incident undirected edges … … 316 356 IncEdgeIt& operator++() { return *this; } 317 357 }; 318 358 359 /// \brief Gets the collection of the incident undirected edges 360 /// of a certain node of the graph. 361 /// 362 /// This function can be used for iterating on the 363 /// incident undirected edges of a certain node of the graph. 364 /// It returns a wrapped 365 /// IncEdgeIt, which looks like an STL container 366 /// (by having begin() and end()) which you can use in range-based 367 /// for loops, stl algorithms, etc. 368 /// For example if g is a Graph and u is a Node, you can write: 369 ///\code 370 /// for(auto e: g.incEdges(u)) 371 /// doSomething(e); 372 /// 373 /// //Using an STL algorithm: 374 /// copy(g.incEdges(u).begin(), g.incEdges(u).end(), vect.begin()); 375 ///\endcode 376 LemonRangeWrapper2<IncEdgeIt, Graph, Node> incEdges(const Node& u) const { 377 return LemonRangeWrapper2<IncEdgeIt, Graph, Node>(*this, u); 378 } 379 380 319 381 /// The arc type of the graph 320 382 321 383 /// This class identifies a directed arc of the graph. It also serves … … 411 473 ArcIt& operator++() { return *this; } 412 474 }; 413 475 476 /// \brief Gets the collection of the directed arcs of the graph. 477 /// 478 /// This function can be used for iterating on the 479 /// arcs of the graph. It returns a wrapped 480 /// ArcIt, which looks like an STL container 481 /// (by having begin() and end()) which you can use in range-based 482 /// for loops, stl algorithms, etc. 483 /// For example you can write: 484 ///\code 485 /// ListGraph g; 486 /// for(auto a: g.arcs()) 487 /// doSomething(a); 488 /// 489 /// //Using an STL algorithm: 490 /// copy(g.arcs().begin(), g.arcs().end(), vect.begin()); 491 ///\endcode 492 LemonRangeWrapper1<ArcIt, Graph> arcs() const { 493 return LemonRangeWrapper1<ArcIt, Graph>(*this); 494 } 495 496 414 497 /// Iterator class for the outgoing arcs of a node. 415 498 416 499 /// This iterator goes trough the \e outgoing directed arcs of a … … 459 542 OutArcIt& operator++() { return *this; } 460 543 }; 461 544 545 /// \brief Gets the collection of the outgoing directed arcs of a 546 /// certain node of the graph. 547 /// 548 /// This function can be used for iterating on the 549 /// outgoing arcs of a certain node of the graph. It returns a wrapped 550 /// OutArcIt, which looks like an STL container 551 /// (by having begin() and end()) which you can use in range-based 552 /// for loops, stl algorithms, etc. 553 /// For example if g is a Graph and u is a Node, you can write: 554 ///\code 555 /// for(auto a: g.outArcs(u)) 556 /// doSomething(a); 557 /// 558 /// //Using an STL algorithm: 559 /// copy(g.outArcs(u).begin(), g.outArcs(u).end(), vect.begin()); 560 ///\endcode 561 LemonRangeWrapper2<OutArcIt, Graph, Node> outArcs(const Node& u) const { 562 return LemonRangeWrapper2<OutArcIt, Graph, Node>(*this, u); 563 } 564 565 462 566 /// Iterator class for the incoming arcs of a node. 463 567 464 568 /// This iterator goes trough the \e incoming directed arcs of a … … 507 611 InArcIt& operator++() { return *this; } 508 612 }; 509 613 614 /// \brief Gets the collection of the incoming directed arcs of 615 /// a certain node of the graph. 616 /// 617 /// This function can be used for iterating on the 618 /// incoming directed arcs of a certain node of the graph. It returns 619 /// a wrapped InArcIt, which looks like an STL container 620 /// (by having begin() and end()) which you can use in range-based 621 /// for loops, stl algorithms, etc. 622 /// For example if g is a Graph and u is a Node, you can write: 623 ///\code 624 /// for(auto a: g.inArcs(u)) 625 /// doSomething(a); 626 /// 627 /// //Using an STL algorithm: 628 /// copy(g.inArcs(u).begin(), g.inArcs(u).end(), vect.begin()); 629 ///\endcode 630 LemonRangeWrapper2<InArcIt, Graph, Node> inArcs(const Node& u) const { 631 return LemonRangeWrapper2<InArcIt, Graph, Node>(*this, u); 632 } 633 510 634 /// \brief Standard graph map type for the nodes. 511 635 /// 512 636 /// Standard graph map type for the nodes. -
lemon/list_graph.h
diff --git a/lemon/list_graph.h b/lemon/list_graph.h
a b 48 48 int next_in, next_out; 49 49 }; 50 50 51 std::vector<NodeT> nodes;51 std::vector<NodeT> _nodes; 52 52 53 53 int first_node; 54 54 55 55 int first_free_node; 56 56 57 std::vector<ArcT> arcs;57 std::vector<ArcT> _arcs; 58 58 59 59 int first_free_arc; 60 60 … … 97 97 98 98 99 99 ListDigraphBase() 100 : nodes(), first_node(-1),101 first_free_node(-1), arcs(), first_free_arc(-1) {}102 103 104 int maxNodeId() const { return nodes.size()-1; }105 int maxArcId() const { return arcs.size()-1; }106 107 Node source(Arc e) const { return Node( arcs[e.id].source); }108 Node target(Arc e) const { return Node( arcs[e.id].target); }100 : _nodes(), first_node(-1), 101 first_free_node(-1), _arcs(), first_free_arc(-1) {} 102 103 104 int maxNodeId() const { return _nodes.size()-1; } 105 int maxArcId() const { return _arcs.size()-1; } 106 107 Node source(Arc e) const { return Node(_arcs[e.id].source); } 108 Node target(Arc e) const { return Node(_arcs[e.id].target); } 109 109 110 110 111 111 void first(Node& node) const { … … 113 113 } 114 114 115 115 void next(Node& node) const { 116 node.id = nodes[node.id].next;116 node.id = _nodes[node.id].next; 117 117 } 118 118 119 119 120 120 void first(Arc& arc) const { 121 121 int n; 122 122 for(n = first_node; 123 n != -1 && nodes[n].first_out == -1;124 n = nodes[n].next) {}125 arc.id = (n == -1) ? -1 : nodes[n].first_out;123 n != -1 && _nodes[n].first_out == -1; 124 n = _nodes[n].next) {} 125 arc.id = (n == -1) ? -1 : _nodes[n].first_out; 126 126 } 127 127 128 128 void next(Arc& arc) const { 129 if ( arcs[arc.id].next_out != -1) {130 arc.id = arcs[arc.id].next_out;129 if (_arcs[arc.id].next_out != -1) { 130 arc.id = _arcs[arc.id].next_out; 131 131 } else { 132 132 int n; 133 for(n = nodes[arcs[arc.id].source].next;134 n != -1 && nodes[n].first_out == -1;135 n = nodes[n].next) {}136 arc.id = (n == -1) ? -1 : nodes[n].first_out;133 for(n = _nodes[_arcs[arc.id].source].next; 134 n != -1 && _nodes[n].first_out == -1; 135 n = _nodes[n].next) {} 136 arc.id = (n == -1) ? -1 : _nodes[n].first_out; 137 137 } 138 138 } 139 139 140 140 void firstOut(Arc &e, const Node& v) const { 141 e.id = nodes[v.id].first_out;141 e.id = _nodes[v.id].first_out; 142 142 } 143 143 void nextOut(Arc &e) const { 144 e.id= arcs[e.id].next_out;144 e.id=_arcs[e.id].next_out; 145 145 } 146 146 147 147 void firstIn(Arc &e, const Node& v) const { 148 e.id = nodes[v.id].first_in;148 e.id = _nodes[v.id].first_in; 149 149 } 150 150 void nextIn(Arc &e) const { 151 e.id= arcs[e.id].next_in;151 e.id=_arcs[e.id].next_in; 152 152 } 153 153 154 154 … … 159 159 static Arc arcFromId(int id) { return Arc(id);} 160 160 161 161 bool valid(Node n) const { 162 return n.id >= 0 && n.id < static_cast<int>( nodes.size()) &&163 nodes[n.id].prev != -2;162 return n.id >= 0 && n.id < static_cast<int>(_nodes.size()) && 163 _nodes[n.id].prev != -2; 164 164 } 165 165 166 166 bool valid(Arc a) const { 167 return a.id >= 0 && a.id < static_cast<int>( arcs.size()) &&168 arcs[a.id].prev_in != -2;167 return a.id >= 0 && a.id < static_cast<int>(_arcs.size()) && 168 _arcs[a.id].prev_in != -2; 169 169 } 170 170 171 171 Node addNode() { 172 172 int n; 173 173 174 174 if(first_free_node==-1) { 175 n = nodes.size();176 nodes.push_back(NodeT());175 n = _nodes.size(); 176 _nodes.push_back(NodeT()); 177 177 } else { 178 178 n = first_free_node; 179 first_free_node = nodes[n].next;179 first_free_node = _nodes[n].next; 180 180 } 181 181 182 nodes[n].next = first_node;183 if(first_node != -1) nodes[first_node].prev = n;182 _nodes[n].next = first_node; 183 if(first_node != -1) _nodes[first_node].prev = n; 184 184 first_node = n; 185 nodes[n].prev = -1;186 187 nodes[n].first_in =nodes[n].first_out = -1;185 _nodes[n].prev = -1; 186 187 _nodes[n].first_in = _nodes[n].first_out = -1; 188 188 189 189 return Node(n); 190 190 } … … 193 193 int n; 194 194 195 195 if (first_free_arc == -1) { 196 n = arcs.size();197 arcs.push_back(ArcT());196 n = _arcs.size(); 197 _arcs.push_back(ArcT()); 198 198 } else { 199 199 n = first_free_arc; 200 first_free_arc = arcs[n].next_in;200 first_free_arc = _arcs[n].next_in; 201 201 } 202 202 203 arcs[n].source = u.id;204 arcs[n].target = v.id;205 206 arcs[n].next_out =nodes[u.id].first_out;207 if( nodes[u.id].first_out != -1) {208 arcs[nodes[u.id].first_out].prev_out = n;203 _arcs[n].source = u.id; 204 _arcs[n].target = v.id; 205 206 _arcs[n].next_out = _nodes[u.id].first_out; 207 if(_nodes[u.id].first_out != -1) { 208 _arcs[_nodes[u.id].first_out].prev_out = n; 209 209 } 210 210 211 arcs[n].next_in =nodes[v.id].first_in;212 if( nodes[v.id].first_in != -1) {213 arcs[nodes[v.id].first_in].prev_in = n;211 _arcs[n].next_in = _nodes[v.id].first_in; 212 if(_nodes[v.id].first_in != -1) { 213 _arcs[_nodes[v.id].first_in].prev_in = n; 214 214 } 215 215 216 arcs[n].prev_in =arcs[n].prev_out = -1;217 218 nodes[u.id].first_out =nodes[v.id].first_in = n;216 _arcs[n].prev_in = _arcs[n].prev_out = -1; 217 218 _nodes[u.id].first_out = _nodes[v.id].first_in = n; 219 219 220 220 return Arc(n); 221 221 } … … 223 223 void erase(const Node& node) { 224 224 int n = node.id; 225 225 226 if( nodes[n].next != -1) {227 nodes[nodes[n].next].prev =nodes[n].prev;226 if(_nodes[n].next != -1) { 227 _nodes[_nodes[n].next].prev = _nodes[n].prev; 228 228 } 229 229 230 if( nodes[n].prev != -1) {231 nodes[nodes[n].prev].next =nodes[n].next;230 if(_nodes[n].prev != -1) { 231 _nodes[_nodes[n].prev].next = _nodes[n].next; 232 232 } else { 233 first_node = nodes[n].next;233 first_node = _nodes[n].next; 234 234 } 235 235 236 nodes[n].next = first_free_node;236 _nodes[n].next = first_free_node; 237 237 first_free_node = n; 238 nodes[n].prev = -2;238 _nodes[n].prev = -2; 239 239 240 240 } 241 241 242 242 void erase(const Arc& arc) { 243 243 int n = arc.id; 244 244 245 if( arcs[n].next_in!=-1) {246 arcs[arcs[n].next_in].prev_in =arcs[n].prev_in;245 if(_arcs[n].next_in!=-1) { 246 _arcs[_arcs[n].next_in].prev_in = _arcs[n].prev_in; 247 247 } 248 248 249 if( arcs[n].prev_in!=-1) {250 arcs[arcs[n].prev_in].next_in =arcs[n].next_in;249 if(_arcs[n].prev_in!=-1) { 250 _arcs[_arcs[n].prev_in].next_in = _arcs[n].next_in; 251 251 } else { 252 nodes[arcs[n].target].first_in =arcs[n].next_in;252 _nodes[_arcs[n].target].first_in = _arcs[n].next_in; 253 253 } 254 254 255 255 256 if( arcs[n].next_out!=-1) {257 arcs[arcs[n].next_out].prev_out =arcs[n].prev_out;256 if(_arcs[n].next_out!=-1) { 257 _arcs[_arcs[n].next_out].prev_out = _arcs[n].prev_out; 258 258 } 259 259 260 if( arcs[n].prev_out!=-1) {261 arcs[arcs[n].prev_out].next_out =arcs[n].next_out;260 if(_arcs[n].prev_out!=-1) { 261 _arcs[_arcs[n].prev_out].next_out = _arcs[n].next_out; 262 262 } else { 263 nodes[arcs[n].source].first_out =arcs[n].next_out;263 _nodes[_arcs[n].source].first_out = _arcs[n].next_out; 264 264 } 265 265 266 arcs[n].next_in = first_free_arc;266 _arcs[n].next_in = first_free_arc; 267 267 first_free_arc = n; 268 arcs[n].prev_in = -2;268 _arcs[n].prev_in = -2; 269 269 } 270 270 271 271 void clear() { 272 arcs.clear();273 nodes.clear();272 _arcs.clear(); 273 _nodes.clear(); 274 274 first_node = first_free_node = first_free_arc = -1; 275 275 } 276 276 277 277 protected: 278 278 void changeTarget(Arc e, Node n) 279 279 { 280 if( arcs[e.id].next_in != -1)281 arcs[arcs[e.id].next_in].prev_in =arcs[e.id].prev_in;282 if( arcs[e.id].prev_in != -1)283 arcs[arcs[e.id].prev_in].next_in =arcs[e.id].next_in;284 else nodes[arcs[e.id].target].first_in =arcs[e.id].next_in;285 if ( nodes[n.id].first_in != -1) {286 arcs[nodes[n.id].first_in].prev_in = e.id;280 if(_arcs[e.id].next_in != -1) 281 _arcs[_arcs[e.id].next_in].prev_in = _arcs[e.id].prev_in; 282 if(_arcs[e.id].prev_in != -1) 283 _arcs[_arcs[e.id].prev_in].next_in = _arcs[e.id].next_in; 284 else _nodes[_arcs[e.id].target].first_in = _arcs[e.id].next_in; 285 if (_nodes[n.id].first_in != -1) { 286 _arcs[_nodes[n.id].first_in].prev_in = e.id; 287 287 } 288 arcs[e.id].target = n.id;289 arcs[e.id].prev_in = -1;290 arcs[e.id].next_in =nodes[n.id].first_in;291 nodes[n.id].first_in = e.id;288 _arcs[e.id].target = n.id; 289 _arcs[e.id].prev_in = -1; 290 _arcs[e.id].next_in = _nodes[n.id].first_in; 291 _nodes[n.id].first_in = e.id; 292 292 } 293 293 void changeSource(Arc e, Node n) 294 294 { 295 if( arcs[e.id].next_out != -1)296 arcs[arcs[e.id].next_out].prev_out =arcs[e.id].prev_out;297 if( arcs[e.id].prev_out != -1)298 arcs[arcs[e.id].prev_out].next_out =arcs[e.id].next_out;299 else nodes[arcs[e.id].source].first_out =arcs[e.id].next_out;300 if ( nodes[n.id].first_out != -1) {301 arcs[nodes[n.id].first_out].prev_out = e.id;295 if(_arcs[e.id].next_out != -1) 296 _arcs[_arcs[e.id].next_out].prev_out = _arcs[e.id].prev_out; 297 if(_arcs[e.id].prev_out != -1) 298 _arcs[_arcs[e.id].prev_out].next_out = _arcs[e.id].next_out; 299 else _nodes[_arcs[e.id].source].first_out = _arcs[e.id].next_out; 300 if (_nodes[n.id].first_out != -1) { 301 _arcs[_nodes[n.id].first_out].prev_out = e.id; 302 302 } 303 arcs[e.id].source = n.id;304 arcs[e.id].prev_out = -1;305 arcs[e.id].next_out =nodes[n.id].first_out;306 nodes[n.id].first_out = e.id;303 _arcs[e.id].source = n.id; 304 _arcs[e.id].prev_out = -1; 305 _arcs[e.id].next_out = _nodes[n.id].first_out; 306 _nodes[n.id].first_out = e.id; 307 307 } 308 308 309 309 }; … … 486 486 ///Snapshot feature. 487 487 Node split(Node n, bool connect = true) { 488 488 Node b = addNode(); 489 nodes[b.id].first_out=nodes[n.id].first_out;490 nodes[n.id].first_out=-1;491 for(int i= nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {492 arcs[i].source=b.id;489 _nodes[b.id].first_out=_nodes[n.id].first_out; 490 _nodes[n.id].first_out=-1; 491 for(int i=_nodes[b.id].first_out; i!=-1; i=_arcs[i].next_out) { 492 _arcs[i].source=b.id; 493 493 } 494 494 if (connect) addArc(n,b); 495 495 return b; … … 532 532 /// then it is worth reserving space for this amount before starting 533 533 /// to build the digraph. 534 534 /// \sa reserveArc() 535 void reserveNode(int n) { nodes.reserve(n); };535 void reserveNode(int n) { _nodes.reserve(n); }; 536 536 537 537 /// Reserve memory for arcs. 538 538 … … 542 542 /// then it is worth reserving space for this amount before starting 543 543 /// to build the digraph. 544 544 /// \sa reserveNode() 545 void reserveArc(int m) { arcs.reserve(m); };545 void reserveArc(int m) { _arcs.reserve(m); }; 546 546 547 547 /// \brief Class to make a snapshot of the digraph and restore 548 548 /// it later. … … 803 803 int prev_out, next_out; 804 804 }; 805 805 806 std::vector<NodeT> nodes;806 std::vector<NodeT> _nodes; 807 807 808 808 int first_node; 809 809 810 810 int first_free_node; 811 811 812 std::vector<ArcT> arcs;812 std::vector<ArcT> _arcs; 813 813 814 814 int first_free_arc; 815 815 … … 867 867 }; 868 868 869 869 ListGraphBase() 870 : nodes(), first_node(-1),871 first_free_node(-1), arcs(), first_free_arc(-1) {}872 873 874 int maxNodeId() const { return nodes.size()-1; }875 int maxEdgeId() const { return arcs.size() / 2 - 1; }876 int maxArcId() const { return arcs.size()-1; }877 878 Node source(Arc e) const { return Node( arcs[e.id ^ 1].target); }879 Node target(Arc e) const { return Node( arcs[e.id].target); }880 881 Node u(Edge e) const { return Node( arcs[2 * e.id].target); }882 Node v(Edge e) const { return Node( arcs[2 * e.id + 1].target); }870 : _nodes(), first_node(-1), 871 first_free_node(-1), _arcs(), first_free_arc(-1) {} 872 873 874 int maxNodeId() const { return _nodes.size()-1; } 875 int maxEdgeId() const { return _arcs.size() / 2 - 1; } 876 int maxArcId() const { return _arcs.size()-1; } 877 878 Node source(Arc e) const { return Node(_arcs[e.id ^ 1].target); } 879 Node target(Arc e) const { return Node(_arcs[e.id].target); } 880 881 Node u(Edge e) const { return Node(_arcs[2 * e.id].target); } 882 Node v(Edge e) const { return Node(_arcs[2 * e.id + 1].target); } 883 883 884 884 static bool direction(Arc e) { 885 885 return (e.id & 1) == 1; … … 894 894 } 895 895 896 896 void next(Node& node) const { 897 node.id = nodes[node.id].next;897 node.id = _nodes[node.id].next; 898 898 } 899 899 900 900 void first(Arc& e) const { 901 901 int n = first_node; 902 while (n != -1 && nodes[n].first_out == -1) {903 n = nodes[n].next;902 while (n != -1 && _nodes[n].first_out == -1) { 903 n = _nodes[n].next; 904 904 } 905 e.id = (n == -1) ? -1 : nodes[n].first_out;905 e.id = (n == -1) ? -1 : _nodes[n].first_out; 906 906 } 907 907 908 908 void next(Arc& e) const { 909 if ( arcs[e.id].next_out != -1) {910 e.id = arcs[e.id].next_out;909 if (_arcs[e.id].next_out != -1) { 910 e.id = _arcs[e.id].next_out; 911 911 } else { 912 int n = nodes[arcs[e.id ^ 1].target].next;913 while(n != -1 && nodes[n].first_out == -1) {914 n = nodes[n].next;912 int n = _nodes[_arcs[e.id ^ 1].target].next; 913 while(n != -1 && _nodes[n].first_out == -1) { 914 n = _nodes[n].next; 915 915 } 916 e.id = (n == -1) ? -1 : nodes[n].first_out;916 e.id = (n == -1) ? -1 : _nodes[n].first_out; 917 917 } 918 918 } 919 919 920 920 void first(Edge& e) const { 921 921 int n = first_node; 922 922 while (n != -1) { 923 e.id = nodes[n].first_out;923 e.id = _nodes[n].first_out; 924 924 while ((e.id & 1) != 1) { 925 e.id = arcs[e.id].next_out;925 e.id = _arcs[e.id].next_out; 926 926 } 927 927 if (e.id != -1) { 928 928 e.id /= 2; 929 929 return; 930 930 } 931 n = nodes[n].next;931 n = _nodes[n].next; 932 932 } 933 933 e.id = -1; 934 934 } 935 935 936 936 void next(Edge& e) const { 937 int n = arcs[e.id * 2].target;938 e.id = arcs[(e.id * 2) | 1].next_out;937 int n = _arcs[e.id * 2].target; 938 e.id = _arcs[(e.id * 2) | 1].next_out; 939 939 while ((e.id & 1) != 1) { 940 e.id = arcs[e.id].next_out;940 e.id = _arcs[e.id].next_out; 941 941 } 942 942 if (e.id != -1) { 943 943 e.id /= 2; 944 944 return; 945 945 } 946 n = nodes[n].next;946 n = _nodes[n].next; 947 947 while (n != -1) { 948 e.id = nodes[n].first_out;948 e.id = _nodes[n].first_out; 949 949 while ((e.id & 1) != 1) { 950 e.id = arcs[e.id].next_out;950 e.id = _arcs[e.id].next_out; 951 951 } 952 952 if (e.id != -1) { 953 953 e.id /= 2; 954 954 return; 955 955 } 956 n = nodes[n].next;956 n = _nodes[n].next; 957 957 } 958 958 e.id = -1; 959 959 } 960 960 961 961 void firstOut(Arc &e, const Node& v) const { 962 e.id = nodes[v.id].first_out;962 e.id = _nodes[v.id].first_out; 963 963 } 964 964 void nextOut(Arc &e) const { 965 e.id = arcs[e.id].next_out;965 e.id = _arcs[e.id].next_out; 966 966 } 967 967 968 968 void firstIn(Arc &e, const Node& v) const { 969 e.id = (( nodes[v.id].first_out) ^ 1);969 e.id = ((_nodes[v.id].first_out) ^ 1); 970 970 if (e.id == -2) e.id = -1; 971 971 } 972 972 void nextIn(Arc &e) const { 973 e.id = (( arcs[e.id ^ 1].next_out) ^ 1);973 e.id = ((_arcs[e.id ^ 1].next_out) ^ 1); 974 974 if (e.id == -2) e.id = -1; 975 975 } 976 976 977 977 void firstInc(Edge &e, bool& d, const Node& v) const { 978 int a = nodes[v.id].first_out;978 int a = _nodes[v.id].first_out; 979 979 if (a != -1 ) { 980 980 e.id = a / 2; 981 981 d = ((a & 1) == 1); … … 985 985 } 986 986 } 987 987 void nextInc(Edge &e, bool& d) const { 988 int a = ( arcs[(e.id * 2) | (d ? 1 : 0)].next_out);988 int a = (_arcs[(e.id * 2) | (d ? 1 : 0)].next_out); 989 989 if (a != -1 ) { 990 990 e.id = a / 2; 991 991 d = ((a & 1) == 1); … … 1004 1004 static Edge edgeFromId(int id) { return Edge(id);} 1005 1005 1006 1006 bool valid(Node n) const { 1007 return n.id >= 0 && n.id < static_cast<int>( nodes.size()) &&1008 nodes[n.id].prev != -2;1007 return n.id >= 0 && n.id < static_cast<int>(_nodes.size()) && 1008 _nodes[n.id].prev != -2; 1009 1009 } 1010 1010 1011 1011 bool valid(Arc a) const { 1012 return a.id >= 0 && a.id < static_cast<int>( arcs.size()) &&1013 arcs[a.id].prev_out != -2;1012 return a.id >= 0 && a.id < static_cast<int>(_arcs.size()) && 1013 _arcs[a.id].prev_out != -2; 1014 1014 } 1015 1015 1016 1016 bool valid(Edge e) const { 1017 return e.id >= 0 && 2 * e.id < static_cast<int>( arcs.size()) &&1018 arcs[2 * e.id].prev_out != -2;1017 return e.id >= 0 && 2 * e.id < static_cast<int>(_arcs.size()) && 1018 _arcs[2 * e.id].prev_out != -2; 1019 1019 } 1020 1020 1021 1021 Node addNode() { 1022 1022 int n; 1023 1023 1024 1024 if(first_free_node==-1) { 1025 n = nodes.size();1026 nodes.push_back(NodeT());1025 n = _nodes.size(); 1026 _nodes.push_back(NodeT()); 1027 1027 } else { 1028 1028 n = first_free_node; 1029 first_free_node = nodes[n].next;1029 first_free_node = _nodes[n].next; 1030 1030 } 1031 1031 1032 nodes[n].next = first_node;1033 if (first_node != -1) nodes[first_node].prev = n;1032 _nodes[n].next = first_node; 1033 if (first_node != -1) _nodes[first_node].prev = n; 1034 1034 first_node = n; 1035 nodes[n].prev = -1;1036 1037 nodes[n].first_out = -1;1035 _nodes[n].prev = -1; 1036 1037 _nodes[n].first_out = -1; 1038 1038 1039 1039 return Node(n); 1040 1040 } … … 1043 1043 int n; 1044 1044 1045 1045 if (first_free_arc == -1) { 1046 n = arcs.size();1047 arcs.push_back(ArcT());1048 arcs.push_back(ArcT());1046 n = _arcs.size(); 1047 _arcs.push_back(ArcT()); 1048 _arcs.push_back(ArcT()); 1049 1049 } else { 1050 1050 n = first_free_arc; 1051 first_free_arc = arcs[n].next_out;1051 first_free_arc = _arcs[n].next_out; 1052 1052 } 1053 1053 1054 arcs[n].target = u.id;1055 arcs[n | 1].target = v.id;1056 1057 arcs[n].next_out =nodes[v.id].first_out;1058 if ( nodes[v.id].first_out != -1) {1059 arcs[nodes[v.id].first_out].prev_out = n;1054 _arcs[n].target = u.id; 1055 _arcs[n | 1].target = v.id; 1056 1057 _arcs[n].next_out = _nodes[v.id].first_out; 1058 if (_nodes[v.id].first_out != -1) { 1059 _arcs[_nodes[v.id].first_out].prev_out = n; 1060 1060 } 1061 arcs[n].prev_out = -1;1062 nodes[v.id].first_out = n;1063 1064 arcs[n | 1].next_out =nodes[u.id].first_out;1065 if ( nodes[u.id].first_out != -1) {1066 arcs[nodes[u.id].first_out].prev_out = (n | 1);1061 _arcs[n].prev_out = -1; 1062 _nodes[v.id].first_out = n; 1063 1064 _arcs[n | 1].next_out = _nodes[u.id].first_out; 1065 if (_nodes[u.id].first_out != -1) { 1066 _arcs[_nodes[u.id].first_out].prev_out = (n | 1); 1067 1067 } 1068 arcs[n | 1].prev_out = -1;1069 nodes[u.id].first_out = (n | 1);1068 _arcs[n | 1].prev_out = -1; 1069 _nodes[u.id].first_out = (n | 1); 1070 1070 1071 1071 return Edge(n / 2); 1072 1072 } … … 1074 1074 void erase(const Node& node) { 1075 1075 int n = node.id; 1076 1076 1077 if( nodes[n].next != -1) {1078 nodes[nodes[n].next].prev =nodes[n].prev;1077 if(_nodes[n].next != -1) { 1078 _nodes[_nodes[n].next].prev = _nodes[n].prev; 1079 1079 } 1080 1080 1081 if( nodes[n].prev != -1) {1082 nodes[nodes[n].prev].next =nodes[n].next;1081 if(_nodes[n].prev != -1) { 1082 _nodes[_nodes[n].prev].next = _nodes[n].next; 1083 1083 } else { 1084 first_node = nodes[n].next;1084 first_node = _nodes[n].next; 1085 1085 } 1086 1086 1087 nodes[n].next = first_free_node;1087 _nodes[n].next = first_free_node; 1088 1088 first_free_node = n; 1089 nodes[n].prev = -2;1089 _nodes[n].prev = -2; 1090 1090 } 1091 1091 1092 1092 void erase(const Edge& edge) { 1093 1093 int n = edge.id * 2; 1094 1094 1095 if ( arcs[n].next_out != -1) {1096 arcs[arcs[n].next_out].prev_out =arcs[n].prev_out;1095 if (_arcs[n].next_out != -1) { 1096 _arcs[_arcs[n].next_out].prev_out = _arcs[n].prev_out; 1097 1097 } 1098 1098 1099 if ( arcs[n].prev_out != -1) {1100 arcs[arcs[n].prev_out].next_out =arcs[n].next_out;1099 if (_arcs[n].prev_out != -1) { 1100 _arcs[_arcs[n].prev_out].next_out = _arcs[n].next_out; 1101 1101 } else { 1102 nodes[arcs[n | 1].target].first_out =arcs[n].next_out;1102 _nodes[_arcs[n | 1].target].first_out = _arcs[n].next_out; 1103 1103 } 1104 1104 1105 if ( arcs[n | 1].next_out != -1) {1106 arcs[arcs[n | 1].next_out].prev_out =arcs[n | 1].prev_out;1105 if (_arcs[n | 1].next_out != -1) { 1106 _arcs[_arcs[n | 1].next_out].prev_out = _arcs[n | 1].prev_out; 1107 1107 } 1108 1108 1109 if ( arcs[n | 1].prev_out != -1) {1110 arcs[arcs[n | 1].prev_out].next_out =arcs[n | 1].next_out;1109 if (_arcs[n | 1].prev_out != -1) { 1110 _arcs[_arcs[n | 1].prev_out].next_out = _arcs[n | 1].next_out; 1111 1111 } else { 1112 nodes[arcs[n].target].first_out =arcs[n | 1].next_out;1112 _nodes[_arcs[n].target].first_out = _arcs[n | 1].next_out; 1113 1113 } 1114 1114 1115 arcs[n].next_out = first_free_arc;1115 _arcs[n].next_out = first_free_arc; 1116 1116 first_free_arc = n; 1117 arcs[n].prev_out = -2;1118 arcs[n | 1].prev_out = -2;1117 _arcs[n].prev_out = -2; 1118 _arcs[n | 1].prev_out = -2; 1119 1119 1120 1120 } 1121 1121 1122 1122 void clear() { 1123 arcs.clear();1124 nodes.clear();1123 _arcs.clear(); 1124 _nodes.clear(); 1125 1125 first_node = first_free_node = first_free_arc = -1; 1126 1126 } 1127 1127 1128 1128 protected: 1129 1129 1130 1130 void changeV(Edge e, Node n) { 1131 if( arcs[2 * e.id].next_out != -1) {1132 arcs[arcs[2 * e.id].next_out].prev_out =arcs[2 * e.id].prev_out;1131 if(_arcs[2 * e.id].next_out != -1) { 1132 _arcs[_arcs[2 * e.id].next_out].prev_out = _arcs[2 * e.id].prev_out; 1133 1133 } 1134 if( arcs[2 * e.id].prev_out != -1) {1135 arcs[arcs[2 * e.id].prev_out].next_out =1136 arcs[2 * e.id].next_out;1134 if(_arcs[2 * e.id].prev_out != -1) { 1135 _arcs[_arcs[2 * e.id].prev_out].next_out = 1136 _arcs[2 * e.id].next_out; 1137 1137 } else { 1138 nodes[arcs[(2 * e.id) | 1].target].first_out =1139 arcs[2 * e.id].next_out;1138 _nodes[_arcs[(2 * e.id) | 1].target].first_out = 1139 _arcs[2 * e.id].next_out; 1140 1140 } 1141 1141 1142 if ( nodes[n.id].first_out != -1) {1143 arcs[nodes[n.id].first_out].prev_out = 2 * e.id;1142 if (_nodes[n.id].first_out != -1) { 1143 _arcs[_nodes[n.id].first_out].prev_out = 2 * e.id; 1144 1144 } 1145 arcs[(2 * e.id) | 1].target = n.id;1146 arcs[2 * e.id].prev_out = -1;1147 arcs[2 * e.id].next_out =nodes[n.id].first_out;1148 nodes[n.id].first_out = 2 * e.id;1145 _arcs[(2 * e.id) | 1].target = n.id; 1146 _arcs[2 * e.id].prev_out = -1; 1147 _arcs[2 * e.id].next_out = _nodes[n.id].first_out; 1148 _nodes[n.id].first_out = 2 * e.id; 1149 1149 } 1150 1150 1151 1151 void changeU(Edge e, Node n) { 1152 if( arcs[(2 * e.id) | 1].next_out != -1) {1153 arcs[arcs[(2 * e.id) | 1].next_out].prev_out =1154 arcs[(2 * e.id) | 1].prev_out;1152 if(_arcs[(2 * e.id) | 1].next_out != -1) { 1153 _arcs[_arcs[(2 * e.id) | 1].next_out].prev_out = 1154 _arcs[(2 * e.id) | 1].prev_out; 1155 1155 } 1156 if( arcs[(2 * e.id) | 1].prev_out != -1) {1157 arcs[arcs[(2 * e.id) | 1].prev_out].next_out =1158 arcs[(2 * e.id) | 1].next_out;1156 if(_arcs[(2 * e.id) | 1].prev_out != -1) { 1157 _arcs[_arcs[(2 * e.id) | 1].prev_out].next_out = 1158 _arcs[(2 * e.id) | 1].next_out; 1159 1159 } else { 1160 nodes[arcs[2 * e.id].target].first_out =1161 arcs[(2 * e.id) | 1].next_out;1160 _nodes[_arcs[2 * e.id].target].first_out = 1161 _arcs[(2 * e.id) | 1].next_out; 1162 1162 } 1163 1163 1164 if ( nodes[n.id].first_out != -1) {1165 arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);1164 if (_nodes[n.id].first_out != -1) { 1165 _arcs[_nodes[n.id].first_out].prev_out = ((2 * e.id) | 1); 1166 1166 } 1167 arcs[2 * e.id].target = n.id;1168 arcs[(2 * e.id) | 1].prev_out = -1;1169 arcs[(2 * e.id) | 1].next_out =nodes[n.id].first_out;1170 nodes[n.id].first_out = ((2 * e.id) | 1);1167 _arcs[2 * e.id].target = n.id; 1168 _arcs[(2 * e.id) | 1].prev_out = -1; 1169 _arcs[(2 * e.id) | 1].next_out = _nodes[n.id].first_out; 1170 _nodes[n.id].first_out = ((2 * e.id) | 1); 1171 1171 } 1172 1172 1173 1173 }; … … 1344 1344 /// then it is worth reserving space for this amount before starting 1345 1345 /// to build the graph. 1346 1346 /// \sa reserveEdge() 1347 void reserveNode(int n) { nodes.reserve(n); };1347 void reserveNode(int n) { _nodes.reserve(n); }; 1348 1348 1349 1349 /// Reserve memory for edges. 1350 1350 … … 1354 1354 /// then it is worth reserving space for this amount before starting 1355 1355 /// to build the graph. 1356 1356 /// \sa reserveNode() 1357 void reserveEdge(int m) { arcs.reserve(2 * m); };1357 void reserveEdge(int m) { _arcs.reserve(2 * m); }; 1358 1358 1359 1359 /// \brief Class to make a snapshot of the graph and restore 1360 1360 /// it later. -
lemon/smart_graph.h
diff --git a/lemon/smart_graph.h b/lemon/smart_graph.h
a b 47 47 ArcT() {} 48 48 }; 49 49 50 std::vector<NodeT> nodes;51 std::vector<ArcT> arcs;50 std::vector<NodeT> _nodes; 51 std::vector<ArcT> _arcs; 52 52 53 53 public: 54 54 … … 59 59 60 60 public: 61 61 62 SmartDigraphBase() : nodes(),arcs() { }62 SmartDigraphBase() : _nodes(), _arcs() { } 63 63 SmartDigraphBase(const SmartDigraphBase &_g) 64 : nodes(_g.nodes), arcs(_g.arcs) { }64 : _nodes(_g._nodes), _arcs(_g._arcs) { } 65 65 66 66 typedef True NodeNumTag; 67 67 typedef True ArcNumTag; 68 68 69 int nodeNum() const { return nodes.size(); }70 int arcNum() const { return arcs.size(); }69 int nodeNum() const { return _nodes.size(); } 70 int arcNum() const { return _arcs.size(); } 71 71 72 int maxNodeId() const { return nodes.size()-1; }73 int maxArcId() const { return arcs.size()-1; }72 int maxNodeId() const { return _nodes.size()-1; } 73 int maxArcId() const { return _arcs.size()-1; } 74 74 75 75 Node addNode() { 76 int n = nodes.size();77 nodes.push_back(NodeT());78 nodes[n].first_in = -1;79 nodes[n].first_out = -1;76 int n = _nodes.size(); 77 _nodes.push_back(NodeT()); 78 _nodes[n].first_in = -1; 79 _nodes[n].first_out = -1; 80 80 return Node(n); 81 81 } 82 82 83 83 Arc addArc(Node u, Node v) { 84 int n = arcs.size();85 arcs.push_back(ArcT());86 arcs[n].source = u._id;87 arcs[n].target = v._id;88 arcs[n].next_out =nodes[u._id].first_out;89 arcs[n].next_in =nodes[v._id].first_in;90 nodes[u._id].first_out =nodes[v._id].first_in = n;84 int n = _arcs.size(); 85 _arcs.push_back(ArcT()); 86 _arcs[n].source = u._id; 87 _arcs[n].target = v._id; 88 _arcs[n].next_out = _nodes[u._id].first_out; 89 _arcs[n].next_in = _nodes[v._id].first_in; 90 _nodes[u._id].first_out = _nodes[v._id].first_in = n; 91 91 92 92 return Arc(n); 93 93 } 94 94 95 95 void clear() { 96 arcs.clear();97 nodes.clear();96 _arcs.clear(); 97 _nodes.clear(); 98 98 } 99 99 100 Node source(Arc a) const { return Node( arcs[a._id].source); }101 Node target(Arc a) const { return Node( arcs[a._id].target); }100 Node source(Arc a) const { return Node(_arcs[a._id].source); } 101 Node target(Arc a) const { return Node(_arcs[a._id].target); } 102 102 103 103 static int id(Node v) { return v._id; } 104 104 static int id(Arc a) { return a._id; } … … 107 107 static Arc arcFromId(int id) { return Arc(id);} 108 108 109 109 bool valid(Node n) const { 110 return n._id >= 0 && n._id < static_cast<int>( nodes.size());110 return n._id >= 0 && n._id < static_cast<int>(_nodes.size()); 111 111 } 112 112 bool valid(Arc a) const { 113 return a._id >= 0 && a._id < static_cast<int>( arcs.size());113 return a._id >= 0 && a._id < static_cast<int>(_arcs.size()); 114 114 } 115 115 116 116 class Node { … … 145 145 }; 146 146 147 147 void first(Node& node) const { 148 node._id = nodes.size() - 1;148 node._id = _nodes.size() - 1; 149 149 } 150 150 151 151 static void next(Node& node) { … … 153 153 } 154 154 155 155 void first(Arc& arc) const { 156 arc._id = arcs.size() - 1;156 arc._id = _arcs.size() - 1; 157 157 } 158 158 159 159 static void next(Arc& arc) { … … 161 161 } 162 162 163 163 void firstOut(Arc& arc, const Node& node) const { 164 arc._id = nodes[node._id].first_out;164 arc._id = _nodes[node._id].first_out; 165 165 } 166 166 167 167 void nextOut(Arc& arc) const { 168 arc._id = arcs[arc._id].next_out;168 arc._id = _arcs[arc._id].next_out; 169 169 } 170 170 171 171 void firstIn(Arc& arc, const Node& node) const { 172 arc._id = nodes[node._id].first_in;172 arc._id = _nodes[node._id].first_in; 173 173 } 174 174 175 175 void nextIn(Arc& arc) const { 176 arc._id = arcs[arc._id].next_in;176 arc._id = _arcs[arc._id].next_in; 177 177 } 178 178 179 179 }; … … 266 266 Node split(Node n, bool connect = true) 267 267 { 268 268 Node b = addNode(); 269 nodes[b._id].first_out=nodes[n._id].first_out;270 nodes[n._id].first_out=-1;271 for(int i= nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {272 arcs[i].source=b._id;269 _nodes[b._id].first_out=_nodes[n._id].first_out; 270 _nodes[n._id].first_out=-1; 271 for(int i=_nodes[b._id].first_out; i!=-1; i=_arcs[i].next_out) { 272 _arcs[i].source=b._id; 273 273 } 274 274 if(connect) addArc(n,b); 275 275 return b; … … 291 291 /// then it is worth reserving space for this amount before starting 292 292 /// to build the digraph. 293 293 /// \sa reserveArc() 294 void reserveNode(int n) { nodes.reserve(n); };294 void reserveNode(int n) { _nodes.reserve(n); }; 295 295 296 296 /// Reserve memory for arcs. 297 297 … … 301 301 /// then it is worth reserving space for this amount before starting 302 302 /// to build the digraph. 303 303 /// \sa reserveNode() 304 void reserveArc(int m) { arcs.reserve(m); };304 void reserveArc(int m) { _arcs.reserve(m); }; 305 305 306 306 public: 307 307 … … 311 311 312 312 void restoreSnapshot(const Snapshot &s) 313 313 { 314 while(s.arc_num< arcs.size()) {315 Arc arc = arcFromId( arcs.size()-1);314 while(s.arc_num<_arcs.size()) { 315 Arc arc = arcFromId(_arcs.size()-1); 316 316 Parent::notifier(Arc()).erase(arc); 317 nodes[arcs.back().source].first_out=arcs.back().next_out;318 nodes[arcs.back().target].first_in=arcs.back().next_in;319 arcs.pop_back();317 _nodes[_arcs.back().source].first_out=_arcs.back().next_out; 318 _nodes[_arcs.back().target].first_in=_arcs.back().next_in; 319 _arcs.pop_back(); 320 320 } 321 while(s.node_num< nodes.size()) {322 Node node = nodeFromId( nodes.size()-1);321 while(s.node_num<_nodes.size()) { 322 Node node = nodeFromId(_nodes.size()-1); 323 323 Parent::notifier(Node()).erase(node); 324 nodes.pop_back();324 _nodes.pop_back(); 325 325 } 326 326 } 327 327 … … 362 362 ///This constructor immediately makes a snapshot of the given digraph. 363 363 /// 364 364 Snapshot(SmartDigraph &gr) : _graph(&gr) { 365 node_num=_graph-> nodes.size();366 arc_num=_graph-> arcs.size();365 node_num=_graph->_nodes.size(); 366 arc_num=_graph->_arcs.size(); 367 367 } 368 368 369 369 ///Make a snapshot. … … 373 373 ///call, the previous snapshot gets lost. 374 374 void save(SmartDigraph &gr) { 375 375 _graph=&gr; 376 node_num=_graph-> nodes.size();377 arc_num=_graph-> arcs.size();376 node_num=_graph->_nodes.size(); 377 arc_num=_graph->_arcs.size(); 378 378 } 379 379 380 380 ///Undo the changes until a snapshot. … … 402 402 int next_out; 403 403 }; 404 404 405 std::vector<NodeT> nodes;406 std::vector<ArcT> arcs;405 std::vector<NodeT> _nodes; 406 std::vector<ArcT> _arcs; 407 407 408 408 public: 409 409 … … 465 465 466 466 467 467 SmartGraphBase() 468 : nodes(),arcs() {}468 : _nodes(), _arcs() {} 469 469 470 470 typedef True NodeNumTag; 471 471 typedef True EdgeNumTag; 472 472 typedef True ArcNumTag; 473 473 474 int nodeNum() const { return nodes.size(); }475 int edgeNum() const { return arcs.size() / 2; }476 int arcNum() const { return arcs.size(); }474 int nodeNum() const { return _nodes.size(); } 475 int edgeNum() const { return _arcs.size() / 2; } 476 int arcNum() const { return _arcs.size(); } 477 477 478 int maxNodeId() const { return nodes.size()-1; }479 int maxEdgeId() const { return arcs.size() / 2 - 1; }480 int maxArcId() const { return arcs.size()-1; }478 int maxNodeId() const { return _nodes.size()-1; } 479 int maxEdgeId() const { return _arcs.size() / 2 - 1; } 480 int maxArcId() const { return _arcs.size()-1; } 481 481 482 Node source(Arc e) const { return Node( arcs[e._id ^ 1].target); }483 Node target(Arc e) const { return Node( arcs[e._id].target); }482 Node source(Arc e) const { return Node(_arcs[e._id ^ 1].target); } 483 Node target(Arc e) const { return Node(_arcs[e._id].target); } 484 484 485 Node u(Edge e) const { return Node( arcs[2 * e._id].target); }486 Node v(Edge e) const { return Node( arcs[2 * e._id + 1].target); }485 Node u(Edge e) const { return Node(_arcs[2 * e._id].target); } 486 Node v(Edge e) const { return Node(_arcs[2 * e._id + 1].target); } 487 487 488 488 static bool direction(Arc e) { 489 489 return (e._id & 1) == 1; … … 494 494 } 495 495 496 496 void first(Node& node) const { 497 node._id = nodes.size() - 1;497 node._id = _nodes.size() - 1; 498 498 } 499 499 500 500 static void next(Node& node) { … … 502 502 } 503 503 504 504 void first(Arc& arc) const { 505 arc._id = arcs.size() - 1;505 arc._id = _arcs.size() - 1; 506 506 } 507 507 508 508 static void next(Arc& arc) { … … 510 510 } 511 511 512 512 void first(Edge& arc) const { 513 arc._id = arcs.size() / 2 - 1;513 arc._id = _arcs.size() / 2 - 1; 514 514 } 515 515 516 516 static void next(Edge& arc) { … … 518 518 } 519 519 520 520 void firstOut(Arc &arc, const Node& v) const { 521 arc._id = nodes[v._id].first_out;521 arc._id = _nodes[v._id].first_out; 522 522 } 523 523 void nextOut(Arc &arc) const { 524 arc._id = arcs[arc._id].next_out;524 arc._id = _arcs[arc._id].next_out; 525 525 } 526 526 527 527 void firstIn(Arc &arc, const Node& v) const { 528 arc._id = (( nodes[v._id].first_out) ^ 1);528 arc._id = ((_nodes[v._id].first_out) ^ 1); 529 529 if (arc._id == -2) arc._id = -1; 530 530 } 531 531 void nextIn(Arc &arc) const { 532 arc._id = (( arcs[arc._id ^ 1].next_out) ^ 1);532 arc._id = ((_arcs[arc._id ^ 1].next_out) ^ 1); 533 533 if (arc._id == -2) arc._id = -1; 534 534 } 535 535 536 536 void firstInc(Edge &arc, bool& d, const Node& v) const { 537 int de = nodes[v._id].first_out;537 int de = _nodes[v._id].first_out; 538 538 if (de != -1) { 539 539 arc._id = de / 2; 540 540 d = ((de & 1) == 1); … … 544 544 } 545 545 } 546 546 void nextInc(Edge &arc, bool& d) const { 547 int de = ( arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);547 int de = (_arcs[(arc._id * 2) | (d ? 1 : 0)].next_out); 548 548 if (de != -1) { 549 549 arc._id = de / 2; 550 550 d = ((de & 1) == 1); … … 563 563 static Edge edgeFromId(int id) { return Edge(id);} 564 564 565 565 bool valid(Node n) const { 566 return n._id >= 0 && n._id < static_cast<int>( nodes.size());566 return n._id >= 0 && n._id < static_cast<int>(_nodes.size()); 567 567 } 568 568 bool valid(Arc a) const { 569 return a._id >= 0 && a._id < static_cast<int>( arcs.size());569 return a._id >= 0 && a._id < static_cast<int>(_arcs.size()); 570 570 } 571 571 bool valid(Edge e) const { 572 return e._id >= 0 && 2 * e._id < static_cast<int>( arcs.size());572 return e._id >= 0 && 2 * e._id < static_cast<int>(_arcs.size()); 573 573 } 574 574 575 575 Node addNode() { 576 int n = nodes.size();577 nodes.push_back(NodeT());578 nodes[n].first_out = -1;576 int n = _nodes.size(); 577 _nodes.push_back(NodeT()); 578 _nodes[n].first_out = -1; 579 579 580 580 return Node(n); 581 581 } 582 582 583 583 Edge addEdge(Node u, Node v) { 584 int n = arcs.size();585 arcs.push_back(ArcT());586 arcs.push_back(ArcT());584 int n = _arcs.size(); 585 _arcs.push_back(ArcT()); 586 _arcs.push_back(ArcT()); 587 587 588 arcs[n].target = u._id;589 arcs[n | 1].target = v._id;588 _arcs[n].target = u._id; 589 _arcs[n | 1].target = v._id; 590 590 591 arcs[n].next_out =nodes[v._id].first_out;592 nodes[v._id].first_out = n;591 _arcs[n].next_out = _nodes[v._id].first_out; 592 _nodes[v._id].first_out = n; 593 593 594 arcs[n | 1].next_out =nodes[u._id].first_out;595 nodes[u._id].first_out = (n | 1);594 _arcs[n | 1].next_out = _nodes[u._id].first_out; 595 _nodes[u._id].first_out = (n | 1); 596 596 597 597 return Edge(n / 2); 598 598 } 599 599 600 600 void clear() { 601 arcs.clear();602 nodes.clear();601 _arcs.clear(); 602 _nodes.clear(); 603 603 } 604 604 605 605 }; … … 701 701 /// then it is worth reserving space for this amount before starting 702 702 /// to build the graph. 703 703 /// \sa reserveEdge() 704 void reserveNode(int n) { nodes.reserve(n); };704 void reserveNode(int n) { _nodes.reserve(n); }; 705 705 706 706 /// Reserve memory for edges. 707 707 … … 711 711 /// then it is worth reserving space for this amount before starting 712 712 /// to build the graph. 713 713 /// \sa reserveNode() 714 void reserveEdge(int m) { arcs.reserve(2 * m); };714 void reserveEdge(int m) { _arcs.reserve(2 * m); }; 715 715 716 716 public: 717 717 … … 722 722 void saveSnapshot(Snapshot &s) 723 723 { 724 724 s._graph = this; 725 s.node_num = nodes.size();726 s.arc_num = arcs.size();725 s.node_num = _nodes.size(); 726 s.arc_num = _arcs.size(); 727 727 } 728 728 729 729 void restoreSnapshot(const Snapshot &s) 730 730 { 731 while(s.arc_num< arcs.size()) {732 int n= arcs.size()-1;731 while(s.arc_num<_arcs.size()) { 732 int n=_arcs.size()-1; 733 733 Edge arc=edgeFromId(n/2); 734 734 Parent::notifier(Edge()).erase(arc); 735 735 std::vector<Arc> dir; 736 736 dir.push_back(arcFromId(n)); 737 737 dir.push_back(arcFromId(n-1)); 738 738 Parent::notifier(Arc()).erase(dir); 739 nodes[arcs[n-1].target].first_out=arcs[n].next_out;740 nodes[arcs[n].target].first_out=arcs[n-1].next_out;741 arcs.pop_back();742 arcs.pop_back();739 _nodes[_arcs[n-1].target].first_out=_arcs[n].next_out; 740 _nodes[_arcs[n].target].first_out=_arcs[n-1].next_out; 741 _arcs.pop_back(); 742 _arcs.pop_back(); 743 743 } 744 while(s.node_num< nodes.size()) {745 int n= nodes.size()-1;744 while(s.node_num<_nodes.size()) { 745 int n=_nodes.size()-1; 746 746 Node node = nodeFromId(n); 747 747 Parent::notifier(Node()).erase(node); 748 nodes.pop_back();748 _nodes.pop_back(); 749 749 } 750 750 } 751 751