COIN-OR::LEMON - Graph Library

Changeset 1026:bd7ea1a718e2 in lemon-0.x


Ignore:
Timestamp:
12/01/04 15:08:37 (19 years ago)
Author:
marci
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1416
Message:

More rational structure of classes in MergeGraphWrappers?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/work/marci/merge_node_graph_wrapper.h

    r1025 r1026  
    361361   */
    362362  template <typename _Graph1, typename _Graph2, typename Enable=void>
    363   class MergeEdgeGraphWrapperBase :
     363  class MergeEdgeGraphWrapperBaseBase :
    364364    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
    365365  public:
     
    375375    typedef typename Parent2::Edge Graph2Edge;
    376376  protected:
    377     MergeEdgeGraphWrapperBase() { }
    378   public:
    379     template <typename _Value> class EdgeMap;
    380 
    381     typedef typename Parent::Node Node;
     377    MergeEdgeGraphWrapperBaseBase() { }
     378  public:
    382379
    383380    class Edge : public Graph1Edge, public Graph2Edge {
    384       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
    385       template <typename _Value> friend class EdgeMap;
     381      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
    386382    protected:
    387383      bool backward; //true, iff backward
     
    410406    using Parent::forward;
    411407    using Parent::backward;
    412     bool forward(const Edge& e) const { return !e.backward; }
    413     bool backward(const Edge& e) const { return e.backward; }
    414 
    415     using Parent::first;
    416     void first(Edge& i) const {
    417       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
    418       i.backward=false;
    419       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    420         Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
    421         i.backward=true;
    422       }
    423     }
    424     void firstIn(Edge& i, const Node& n) const {
    425       if (!backward(n)) {
    426         Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
    427         if (*static_cast<Graph1Edge*>(&i)==INVALID)
    428           i=INVALID;
    429         else
    430           i.backward=false;
    431       } else {
    432         Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
    433         i.backward=true;
    434       }
    435     }
    436     void firstOut(Edge& i, const Node& n) const {
    437       if (!backward(n)) {
    438         Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
    439         if (*static_cast<Graph1Edge*>(&i)==INVALID)
    440           i=INVALID;
    441         else
    442           i.backward=false;
    443       } else {
    444         Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
    445         i.backward=true;
    446       }
    447     }
    448 
    449     using Parent::next;
    450     void next(Edge& i) const {
    451       if (!(i.backward)) {
    452         Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
    453         if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    454           Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
    455           i.backward=true;
    456         }
    457       } else {
    458         Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
    459       }
    460     }
    461     void nextIn(Edge& i) const {
    462       if (!(i.backward)) {
    463         Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
    464         if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    465       } else {
    466         Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
    467       }
    468     }
    469     void nextOut(Edge& i) const {
    470       if (!(i.backward)) {
    471         Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
    472         if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    473       } else {
    474         Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
    475       }
    476     }
    477 
    478     Node source(const Edge& i) const {
    479       if (!(i.backward)) {
    480         return
    481           Node(Parent1::graph->source(i), INVALID, false);
    482       } else {
    483         return
    484           Node(INVALID, Parent2::graph->source(i), true);
    485       }
    486     }
    487 
    488     Node target(const Edge& i) const {
    489       if (!(i.backward)) {
    490         return
    491           Node(Parent1::graph->target(i), INVALID, false);
    492       } else {
    493         return
    494           Node(INVALID, Parent2::graph->target(i), true);
    495       }
    496     }
    497 
    498     using Parent::id;
    499     int id(const Edge& n) const {
    500       if (!n.backward)
    501         return this->Parent1::graph->id(n);
    502       else
    503         return this->Parent2::graph->id(n);
    504     }
    505 
    506     template <typename _Value>
    507     class EdgeMap {
    508     protected:
    509       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
    510       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
    511       ParentMap1 forward_map;
    512       ParentMap2 backward_map;
    513     public:
    514       typedef _Value Value;
    515       typedef Edge Key;
    516       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
    517         forward_map(*(gw.Parent1::graph)),
    518         backward_map(*(gw.Parent2::graph)) { }
    519       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
    520               const _Value& value) :
    521         forward_map(*(gw.Parent1::graph), value),
    522         backward_map(*(gw.Parent2::graph), value) { }
    523       _Value operator[](const Edge& n) const {
    524         if (!n.backward)
    525           return forward_map[n];
    526         else
    527           return backward_map[n];
    528       }
    529       void set(const Edge& n, const _Value& value) {
    530         if (!n.backward)
    531           forward_map.set(n, value);
    532         else
    533           backward_map.set(n, value);
    534       }
    535 //       using ParentMap1::operator[];
    536 //       using ParentMap2::operator[];
    537     };
    538 
    539   };
     408    using Parent::setForward;
     409    using Parent::setBackward;
     410    static bool forward(const Edge& e) { return !e.backward; }
     411    static bool backward(const Edge& e) { return e.backward; }
     412    static void setForward(Edge& e) { e.backward=false; }
     413    static void setBackward(Edge& e) { e.backward=true; }
     414  };
     415
    540416
    541417
     
    548424   */
    549425  template <typename _Graph1, typename _Graph2>
    550   class MergeEdgeGraphWrapperBase<
     426  class MergeEdgeGraphWrapperBaseBase<
    551427    _Graph1, _Graph2, typename boost::enable_if<
    552428    boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> :
     
    564440    typedef typename Parent2::Edge Graph2Edge;
    565441  protected:
    566     MergeEdgeGraphWrapperBase() { }
    567   public:
    568     template <typename _Value> class EdgeMap;
    569 
    570     typedef typename Parent::Node Node;
     442    MergeEdgeGraphWrapperBaseBase() { }
     443  public:
    571444
    572445    class Edge : public Graph1Edge {
    573       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
    574       template <typename _Value> friend class EdgeMap;
     446      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
    575447    protected:
    576448      bool backward; //true, iff backward
     
    595467    using Parent::forward;
    596468    using Parent::backward;
    597     bool forward(const Edge& e) const { return !e.backward; }
    598     bool backward(const Edge& e) const { return e.backward; }
     469    using Parent::setForward;
     470    using Parent::setBackward;
     471    static bool forward(const Edge& e) { return !e.backward; }
     472    static bool backward(const Edge& e) { return e.backward; }
     473    static void setForward(Edge& e) { e.backward=false; }
     474    static void setBackward(Edge& e) { e.backward=true; }
     475  };
     476
     477
     478  /*! A grah wrapper base class
     479    for merging the node-sets and edge-sets of
     480    two node-disjoint graphs
     481    into one graph.
     482    Specialized implementation for the case
     483    when _Graph1::Edge is a base class and _Graph2::Edge
     484    is derived from it.
     485   */
     486  template <typename _Graph1, typename _Graph2>
     487  class MergeEdgeGraphWrapperBaseBase<
     488    _Graph1, _Graph2, typename boost::enable_if<
     489    boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> :
     490    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
     491  public:
     492    static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
     493    typedef _Graph1 Graph1;
     494    typedef _Graph2 Graph2;
     495    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
     496    typedef typename Parent::Parent1 Parent1;
     497    typedef typename Parent::Parent2 Parent2;
     498//     typedef P1<_Graph1> Parent1;
     499//     typedef P2<_Graph2> Parent2;
     500    typedef typename Parent1::Edge Graph1Edge;
     501    typedef typename Parent2::Edge Graph2Edge;
     502  protected:
     503    MergeEdgeGraphWrapperBaseBase() { }
     504  public:
     505
     506    class Edge : public Graph2Edge {
     507      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
     508    protected:
     509      bool backward; //true, iff backward
     510    public:
     511      Edge() { }
     512      /// \todo =false is needed, or causes problems?
     513      /// If \c _backward is false, then we get an edge corresponding to the
     514      /// original one, otherwise its oppositely directed pair is obtained.
     515      Edge(const Graph1Edge& n1,
     516           const Graph2Edge& n2, bool _backward) :
     517        Graph2Edge(n2), backward(_backward) {
     518        if (!backward) *this=n1;
     519      }
     520      Edge(Invalid i) : Graph2Edge(i), backward(true) { }
     521      bool operator==(const Edge& v) const {
     522        if (backward)
     523          return (v.backward &&
     524                  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
     525        else
     526          return (!v.backward &&
     527                  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
     528      }
     529      bool operator!=(const Edge& v) const {
     530        return !(*this==v);
     531      }
     532    };
     533
     534    using Parent::forward;
     535    using Parent::backward;
     536    using Parent::setForward;
     537    using Parent::setBackward;
     538    static bool forward(const Edge& e) { return !e.backward; }
     539    static bool backward(const Edge& e) { return e.backward; }
     540    static void setForward(Edge& e) { e.backward=false; }
     541    static void setBackward(Edge& e) { e.backward=true; }
     542  };
     543
     544
     545  /*! A grah wrapper base class
     546    for merging the node-sets and edge-sets of
     547    two node-disjoint graphs
     548    into one graph.
     549    Specialized implementation for the case
     550    when _Graph1::Edge is derived from _Graph2::Edge.
     551   */
     552  template <typename _Graph1, typename _Graph2>
     553  class MergeEdgeGraphWrapperBaseBase<
     554    _Graph1, _Graph2, typename boost::enable_if<
     555    boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> :
     556    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
     557  public:
     558    static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
     559    typedef _Graph1 Graph1;
     560    typedef _Graph2 Graph2;
     561    typedef MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
     562    typedef typename Parent::Parent1 Parent1;
     563    typedef typename Parent::Parent2 Parent2;
     564//     typedef P1<_Graph1> Parent1;
     565//     typedef P2<_Graph2> Parent2;
     566    typedef typename Parent1::Edge Graph1Edge;
     567    typedef typename Parent2::Edge Graph2Edge;
     568  protected:
     569    MergeEdgeGraphWrapperBaseBase() { }
     570  public:
     571
     572    class Edge : public Graph1Edge {
     573      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
     574    protected:
     575      bool backward; //true, iff backward
     576    public:
     577      Edge() { }
     578      /// \todo =false is needed, or causes problems?
     579      /// If \c _backward is false, then we get an edge corresponding to the
     580      /// original one, otherwise its oppositely directed pair is obtained.
     581      Edge(const Graph1Edge& n1,
     582           const Graph2Edge& n2, bool _backward) :
     583        Graph1Edge(n1), backward(_backward) {
     584        if (backward) *this=n2;
     585      }
     586      Edge(Invalid i) : Graph1Edge(i), backward(true) { }
     587      bool operator==(const Edge& v) const {
     588        if (backward)
     589          return (v.backward &&
     590                  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
     591        else
     592          return (!v.backward &&
     593                  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
     594      }
     595      bool operator!=(const Edge& v) const {
     596        return !(*this==v);
     597      }
     598    };
     599
     600    using Parent::forward;
     601    using Parent::backward;
     602    using Parent::setForward;
     603    using Parent::setBackward;
     604    static bool forward(const Edge& e) { return !e.backward; }
     605    static bool backward(const Edge& e) { return e.backward; }
     606    static void setForward(Edge& e) { e.backward=false; }
     607    static void setBackward(Edge& e) { e.backward=true; }
     608  };
     609
     610
     611  template <typename _Graph1, typename _Graph2>
     612  class MergeEdgeGraphWrapperBase :
     613    public MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2> {
     614  public:
     615    typedef MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
     616    typedef _Graph1 Graph1;
     617    typedef _Graph2 Graph2;
     618    typedef typename Parent::Parent1 Parent1;
     619    typedef typename Parent::Parent2 Parent2;
     620    typedef typename Parent1::Node Graph1Node;
     621    typedef typename Parent2::Node Graph2Node;
     622    typedef typename Parent1::Edge Graph1Edge;
     623    typedef typename Parent2::Edge Graph2Edge;
     624
     625    typedef typename Parent::Node Node;
     626    typedef typename Parent::Edge Edge;
    599627
    600628    using Parent::first;
    601629    void first(Edge& i) const {
    602630      Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
    603       i.backward=false;
     631      this->setForward(i);
    604632      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    605         Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
    606         i.backward=true;
     633        Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
     634        this->setBackward(i);
    607635      }
    608636    }
    609637    void firstIn(Edge& i, const Node& n) const {
    610       if (!backward(n)) {
     638      if (forward(n)) {
    611639        Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
    612640        if (*static_cast<Graph1Edge*>(&i)==INVALID)
    613641          i=INVALID;
    614642        else
    615           i.backward=false;
    616       } else {
    617         Parent2::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
    618         i.backward=true;
     643          this->setForward(i);
     644      } else {
     645        Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
     646        this->setBackward(i);
    619647      }
    620648    }
    621649    void firstOut(Edge& i, const Node& n) const {
    622       if (!backward(n)) {
     650      if (forward(n)) {
    623651        Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
    624652        if (*static_cast<Graph1Edge*>(&i)==INVALID)
    625653          i=INVALID;
    626654        else
    627           i.backward=false;
    628       } else {
    629         Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
    630         i.backward=true;
     655          this->setForward(i);
     656      } else {
     657        Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
     658        this->setBackward(i);
    631659      }
    632660    }
     
    634662    using Parent::next;
    635663    void next(Edge& i) const {
    636       if (!(i.backward)) {
     664      if (forward(i)) {
    637665        Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
    638666        if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    639           Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
    640           i.backward=true;
     667          Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
     668          this->setBackward(i);
    641669        }
    642670      } else {
    643         Parent2::graph->next(*static_cast<Graph1Edge*>(&i));
     671        Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
    644672      }
    645673    }
    646674    void nextIn(Edge& i) const {
    647       if (!(i.backward)) {
     675      if (forward(i)) {
    648676        Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
    649677        if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    650678      } else {
    651         Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
     679        Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
    652680      }
    653681    }
    654682    void nextOut(Edge& i) const {
    655       if (!(i.backward)) {
     683      if (Parent::forward(i)) {
    656684        Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
    657685        if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    658686      } else {
    659         Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&i));
     687        Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
    660688      }
    661689    }
    662690
    663691    Node source(const Edge& i) const {
    664       if (!(i.backward)) {
     692      if (forward(i)) {
    665693        return
    666694          Node(Parent1::graph->source(i), INVALID, false);
     
    672700
    673701    Node target(const Edge& i) const {
    674       if (!(i.backward)) {
     702      if (forward(i)) {
    675703        return
    676704          Node(Parent1::graph->target(i), INVALID, false);
     
    683711    using Parent::id;
    684712    int id(const Edge& n) const {
    685       if (!n.backward)
     713      if (forward(n))
    686714        return this->Parent1::graph->id(n);
    687715      else
     
    707735        backward_map(*(gw.Parent2::graph), value) { }
    708736      _Value operator[](const Edge& n) const {
    709         if (!n.backward)
     737        if (Parent::forward(n))
    710738          return forward_map[n];
    711739        else
     
    713741      }
    714742      void set(const Edge& n, const _Value& value) {
    715         if (!n.backward)
     743        if (Parent::forward(n))
    716744          forward_map.set(n, value);
    717745        else
     
    725753
    726754
    727   /*! A grah wrapper base class
    728     for merging the node-sets and edge-sets of
    729     two node-disjoint graphs
     755
     756  /*! A graph wrapper class
     757    for merging two node-disjoint graphs
    730758    into one graph.
    731     Specialized implementation for the case
    732     when _Graph1::Edge is a base class and _Graph2::Edge
    733     is derived from it.
    734    */
    735   template <typename _Graph1, typename _Graph2>
    736   class MergeEdgeGraphWrapperBase<
    737     _Graph1, _Graph2, typename boost::enable_if<
    738     boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> :
    739     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
    740   public:
    741     static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
    742     typedef _Graph1 Graph1;
    743     typedef _Graph2 Graph2;
    744     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
    745     typedef typename Parent::Parent1 Parent1;
    746     typedef typename Parent::Parent2 Parent2;
    747 //     typedef P1<_Graph1> Parent1;
    748 //     typedef P2<_Graph2> Parent2;
    749     typedef typename Parent1::Edge Graph1Edge;
    750     typedef typename Parent2::Edge Graph2Edge;
    751   protected:
    752     MergeEdgeGraphWrapperBase() { }
    753   public:
    754     template <typename _Value> class EdgeMap;
    755 
    756     typedef typename Parent::Node Node;
    757 
    758     class Edge : public Graph2Edge {
    759       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
    760       template <typename _Value> friend class EdgeMap;
    761     protected:
    762       bool backward; //true, iff backward
    763     public:
    764       Edge() { }
    765       /// \todo =false is needed, or causes problems?
    766       /// If \c _backward is false, then we get an edge corresponding to the
    767       /// original one, otherwise its oppositely directed pair is obtained.
    768       Edge(const Graph1Edge& n1,
    769            const Graph2Edge& n2, bool _backward) :
    770         Graph2Edge(n2), backward(_backward) {
    771         if (!backward) *this=n1;
    772       }
    773       Edge(Invalid i) : Graph2Edge(i), backward(true) { }
    774       bool operator==(const Edge& v) const {
    775         if (backward)
    776           return (v.backward &&
    777                   static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
    778         else
    779           return (!v.backward &&
    780                   static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
    781       }
    782       bool operator!=(const Edge& v) const {
    783         return !(*this==v);
    784       }
    785     };
    786 
    787     using Parent::forward;
    788     using Parent::backward;
    789     bool forward(const Edge& e) const { return !e.backward; }
    790     bool backward(const Edge& e) const { return e.backward; }
    791 
    792     using Parent::first;
    793     void first(Edge& i) const {
    794       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
    795       i.backward=false;
    796       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    797         Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
    798         i.backward=true;
    799       }
    800     }
    801     void firstIn(Edge& i, const Node& n) const {
    802       if (!backward(n)) {
    803         Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
    804         if (*static_cast<Graph1Edge*>(&i)==INVALID)
    805           i=INVALID;
    806         else
    807           i.backward=false;
    808       } else {
    809         Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
    810         i.backward=true;
    811       }
    812     }
    813     void firstOut(Edge& i, const Node& n) const {
    814       if (!backward(n)) {
    815         Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
    816         if (*static_cast<Graph1Edge*>(&i)==INVALID)
    817           i=INVALID;
    818         else   
    819           i.backward=false;
    820       } else {
    821         Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
    822         i.backward=true;
    823       }
    824     }
    825 
    826     using Parent::next;
    827     void next(Edge& i) const {
    828       if (!(i.backward)) {
    829         Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
    830         if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    831           Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
    832           i.backward=true;
    833         }
    834       } else {
    835         Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
    836       }
    837     }
    838     void nextIn(Edge& i) const {
    839       if (!(i.backward)) {
    840         Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
    841         if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    842       } else {
    843         Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
    844       }
    845     }
    846     void nextOut(Edge& i) const {
    847       if (!(i.backward)) {
    848         Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
    849         if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    850       } else {
    851         Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
    852       }
    853     }
    854 
    855     Node source(const Edge& i) const {
    856       if (!(i.backward)) {
    857         return
    858           Node(Parent1::graph->source(i), INVALID, false);
    859       } else {
    860         return
    861           Node(INVALID, Parent2::graph->source(i), true);
    862       }
    863     }
    864 
    865     Node target(const Edge& i) const {
    866       if (!(i.backward)) {
    867         return
    868           Node(Parent1::graph->target(i), INVALID, false);
    869       } else {
    870         return
    871           Node(INVALID, Parent2::graph->target(i), true);
    872       }
    873     }
    874 
    875     using Parent::id;
    876     int id(const Edge& n) const {
    877       if (!n.backward)
    878         return this->Parent1::graph->id(n);
    879       else
    880         return this->Parent2::graph->id(n);
    881     }
    882 
    883     template <typename _Value>
    884     class EdgeMap {
    885     protected:
    886       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
    887       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
    888       ParentMap1 forward_map;
    889       ParentMap2 backward_map;
    890     public:
    891       typedef _Value Value;
    892       typedef Edge Key;
    893       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
    894         forward_map(*(gw.Parent1::graph)),
    895         backward_map(*(gw.Parent2::graph)) { }
    896       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
    897               const _Value& value) :
    898         forward_map(*(gw.Parent1::graph), value),
    899         backward_map(*(gw.Parent2::graph), value) { }
    900       _Value operator[](const Edge& n) const {
    901         if (!n.backward)
    902           return forward_map[n];
    903         else
    904           return backward_map[n];
    905       }
    906       void set(const Edge& n, const _Value& value) {
    907         if (!n.backward)
    908           forward_map.set(n, value);
    909         else
    910           backward_map.set(n, value);
    911       }
    912 //       using ParentMap1::operator[];
    913 //       using ParentMap2::operator[];
    914     };
    915 
    916   };
    917 
    918 
    919   /*! A grah wrapper base class
    920     for merging the node-sets and edge-sets of
    921     two node-disjoint graphs
    922     into one graph.
    923     Specialized implementation for the case
    924     when _Graph1::Edge is derived from _Graph2::Edge.
    925    */
    926   template <typename _Graph1, typename _Graph2>
    927   class MergeEdgeGraphWrapperBase<
    928     _Graph1, _Graph2, typename boost::enable_if<
    929     boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> :
    930     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
    931   public:
    932     static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
    933     typedef _Graph1 Graph1;
    934     typedef _Graph2 Graph2;
    935     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
    936     typedef typename Parent::Parent1 Parent1;
    937     typedef typename Parent::Parent2 Parent2;
    938 //     typedef P1<_Graph1> Parent1;
    939 //     typedef P2<_Graph2> Parent2;
    940     typedef typename Parent1::Edge Graph1Edge;
    941     typedef typename Parent2::Edge Graph2Edge;
    942   protected:
    943     MergeEdgeGraphWrapperBase() { }
    944   public:
    945     template <typename _Value> class EdgeMap;
    946 
    947     typedef typename Parent::Node Node;
    948 
    949     class Edge : public Graph1Edge {
    950       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
    951       template <typename _Value> friend class EdgeMap;
    952     protected:
    953       bool backward; //true, iff backward
    954     public:
    955       Edge() { }
    956       /// \todo =false is needed, or causes problems?
    957       /// If \c _backward is false, then we get an edge corresponding to the
    958       /// original one, otherwise its oppositely directed pair is obtained.
    959       Edge(const Graph1Edge& n1,
    960            const Graph2Edge& n2, bool _backward) :
    961         Graph1Edge(n1), backward(_backward) {
    962         if (backward) *this=n2;
    963       }
    964       Edge(Invalid i) : Graph1Edge(i), backward(true) { }
    965       bool operator==(const Edge& v) const {
    966         if (backward)
    967           return (v.backward &&
    968                   static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
    969         else
    970           return (!v.backward &&
    971                   static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
    972       }
    973       bool operator!=(const Edge& v) const {
    974         return !(*this==v);
    975       }
    976     };
    977 
    978     using Parent::forward;
    979     using Parent::backward;
    980     bool forward(const Edge& e) const { return !e.backward; }
    981     bool backward(const Edge& e) const { return e.backward; }
    982 
    983     using Parent::first;
    984     void first(Edge& i) const {
    985       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
    986       i.backward=false;
    987       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    988         Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
    989         i.backward=true;
    990       }
    991     }
    992     void firstIn(Edge& i, const Node& n) const {
    993       if (!backward(n)) {
    994         Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
    995         if (*static_cast<Graph1Edge*>(&i)==INVALID)
    996           i=INVALID;
    997         else
    998           i.backward=false;
    999       } else {
    1000         Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
    1001         i.backward=true;
    1002       }
    1003     }
    1004     void firstOut(Edge& i, const Node& n) const {
    1005       if (!backward(n)) {
    1006         Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
    1007         if (*static_cast<Graph1Edge*>(&i)==INVALID)
    1008           i=INVALID;
    1009         else   
    1010           i.backward=false;
    1011       } else {
    1012         Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
    1013         i.backward=true;
    1014       }
    1015     }
    1016 
    1017     using Parent::next;
    1018     void next(Edge& i) const {
    1019       if (!(i.backward)) {
    1020         Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
    1021         if (*static_cast<Graph1Edge*>(&i)==INVALID) {
    1022           Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
    1023           i.backward=true;
    1024         }
    1025       } else {
    1026         Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
    1027       }
    1028     }
    1029     void nextIn(Edge& i) const {
    1030       if (!(i.backward)) {
    1031         Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
    1032         if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    1033       } else {
    1034         Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
    1035       }
    1036     }
    1037     void nextOut(Edge& i) const {
    1038       if (!(i.backward)) {
    1039         Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
    1040         if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
    1041       } else {
    1042         Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
    1043       }
    1044     }
    1045 
    1046     Node source(const Edge& i) const {
    1047       if (!(i.backward)) {
    1048         return
    1049           Node(Parent1::graph->source(i), INVALID, false);
    1050       } else {
    1051         return
    1052           Node(INVALID, Parent2::graph->source(i), true);
    1053       }
    1054     }
    1055 
    1056     Node target(const Edge& i) const {
    1057       if (!(i.backward)) {
    1058         return
    1059           Node(Parent1::graph->target(i), INVALID, false);
    1060       } else {
    1061         return
    1062           Node(INVALID, Parent2::graph->target(i), true);
    1063       }
    1064     }
    1065 
    1066     using Parent::id;
    1067     int id(const Edge& n) const {
    1068       if (!n.backward)
    1069         return this->Parent1::graph->id(n);
    1070       else
    1071         return this->Parent2::graph->id(n);
    1072     }
    1073 
    1074     template <typename _Value>
    1075     class EdgeMap {
    1076     protected:
    1077       typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
    1078       typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
    1079       ParentMap1 forward_map;
    1080       ParentMap2 backward_map;
    1081     public:
    1082       typedef _Value Value;
    1083       typedef Edge Key;
    1084       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
    1085         forward_map(*(gw.Parent1::graph)),
    1086         backward_map(*(gw.Parent2::graph)) { }
    1087       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
    1088               const _Value& value) :
    1089         forward_map(*(gw.Parent1::graph), value),
    1090         backward_map(*(gw.Parent2::graph), value) { }
    1091       _Value operator[](const Edge& n) const {
    1092         if (!n.backward)
    1093           return forward_map[n];
    1094         else
    1095           return backward_map[n];
    1096       }
    1097       void set(const Edge& n, const _Value& value) {
    1098         if (!n.backward)
    1099           forward_map.set(n, value);
    1100         else
    1101           backward_map.set(n, value);
    1102       }
    1103 //       using ParentMap1::operator[];
    1104 //       using ParentMap2::operator[];
    1105     };
    1106 
    1107   };
    1108 
    1109 
    1110   /*! A graph wrapper class
    1111     for merging the node-sets and edge-sets of
    1112     two node-disjoint graphs
    1113     into one graph.
    1114    */
     759    Different implementations are according to the relation of
     760    _Graph1::Edge and _Graph2::Edge.
     761    If _Graph1::Edge and _Graph2::Edge are unrelated, then
     762    MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge
     763    is derived from both.
     764    If _Graph1::Edge and _Graph2::Edge are the same type, then
     765    MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge
     766    is derived from _Graph1::Edge.
     767    If one of _Graph1::Edge and _Graph2::Edge
     768    is derived from the other one, then
     769    MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge
     770    is derived from the derived type.
     771    It does not satisfy
     772  */
    1115773  template <typename _Graph1, typename _Graph2>
    1116774  class MergeEdgeGraphWrapper : public
Note: See TracChangeset for help on using the changeset viewer.