src/work/marci/merge_node_graph_wrapper.h
changeset 1011 5bd6c7671c9e
parent 1008 3fef334f5f37
child 1013 b3bdd856faf4
equal deleted inserted replaced
5:676a7aa3bc13 6:9744318aa587
    36 
    36 
    37   template <class _Graph2>
    37   template <class _Graph2>
    38   class P2 : public GraphWrapperBase<_Graph2> {
    38   class P2 : public GraphWrapperBase<_Graph2> {
    39   };
    39   };
    40 
    40 
       
    41   /*! A base class for merging the node-set of two node-disjoint graphs 
       
    42     into the node-set of one graph.
       
    43    */
    41   template <typename _Graph1, typename _Graph2, typename Enable=void>
    44   template <typename _Graph1, typename _Graph2, typename Enable=void>
    42   class MergeNodeGraphWrapperBase : 
    45   class MergeNodeGraphWrapperBase : 
    43     public P1<_Graph1>, public P2<_Graph2> {
    46     public P1<_Graph1>, public P2<_Graph2> {
    44   public:
    47   public:
    45     void print() const { std::cout << "generic" << std::endl; }
    48     void printNode() const { std::cout << "generic" << std::endl; }
    46     typedef _Graph1 Graph1;
    49     typedef _Graph1 Graph1;
    47     typedef _Graph2 Graph2;
    50     typedef _Graph2 Graph2;
    48     typedef P1<_Graph1> Parent1;
    51     typedef P1<_Graph1> Parent1;
    49     typedef P2<_Graph2> Parent2;
    52     typedef P2<_Graph2> Parent2;
    50     typedef typename Parent1::Node Graph1Node;
    53     typedef typename Parent1::Node Graph1Node;
   137 	if (!n.backward) 
   140 	if (!n.backward) 
   138 	  ParentMap1::set(n, value);
   141 	  ParentMap1::set(n, value);
   139 	else 
   142 	else 
   140 	  ParentMap2::set(n, value);
   143 	  ParentMap2::set(n, value);
   141       }
   144       }
   142       using ParentMap1::operator[];
   145 //       using ParentMap1::operator[];
   143       using ParentMap2::operator[];
   146 //       using ParentMap2::operator[];
   144     };
   147     };
   145 
   148 
   146   };
   149   };
   147 
   150 
   148   //not yet working
   151   //not yet working
   150   class MergeNodeGraphWrapperBase<
   153   class MergeNodeGraphWrapperBase<
   151     _Graph1, _Graph2, typename boost::enable_if<
   154     _Graph1, _Graph2, typename boost::enable_if<
   152     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   155     boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   153     public P1<_Graph1>, public P2<_Graph2> {
   156     public P1<_Graph1>, public P2<_Graph2> {
   154   public :
   157   public :
   155     void print() const { std::cout << "same" << std::endl; }
   158     void printNode() const { std::cout << "same" << std::endl; }
   156     typedef _Graph1 Graph1;
   159     typedef _Graph1 Graph1;
   157     typedef _Graph2 Graph2;
   160     typedef _Graph2 Graph2;
   158     typedef P1<_Graph1> Parent1;
   161     typedef P1<_Graph1> Parent1;
   159     typedef P2<_Graph2> Parent2;
   162     typedef P2<_Graph2> Parent2;
   160     typedef typename Parent1::Node Graph1Node;
   163     typedef typename Parent1::Node Graph1Node;
   173   class MergeNodeGraphWrapperBase<
   176   class MergeNodeGraphWrapperBase<
   174     _Graph1, _Graph2, typename boost::enable_if<
   177     _Graph1, _Graph2, typename boost::enable_if<
   175     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   178     boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
   176     public P1<_Graph1>, public P2<_Graph2> {
   179     public P1<_Graph1>, public P2<_Graph2> {
   177   public :
   180   public :
   178     void print() const { std::cout << "2. nagyobb" << std::endl; }
   181     void printNode() const { std::cout << "2. nagyobb" << std::endl; }
   179     typedef _Graph1 Graph1;
   182     typedef _Graph1 Graph1;
   180     typedef _Graph2 Graph2;
   183     typedef _Graph2 Graph2;
   181     typedef P1<_Graph1> Parent1;
   184     typedef P1<_Graph1> Parent1;
   182     typedef P2<_Graph2> Parent2;
   185     typedef P2<_Graph2> Parent2;
   183     typedef typename Parent1::Node Graph1Node;
   186     typedef typename Parent1::Node Graph1Node;
   196   class MergeNodeGraphWrapperBase<
   199   class MergeNodeGraphWrapperBase<
   197     _Graph1, _Graph2, typename boost::enable_if<
   200     _Graph1, _Graph2, typename boost::enable_if<
   198     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   201     boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
   199     public P1<_Graph1>, public P2<_Graph2> {
   202     public P1<_Graph1>, public P2<_Graph2> {
   200   public :
   203   public :
   201     void print() const { std::cout << "1. nagyobb" << std::endl; }
   204     void printNode() const { std::cout << "1. nagyobb" << std::endl; }
   202     typedef _Graph1 Graph1;
   205     typedef _Graph1 Graph1;
   203     typedef _Graph2 Graph2;
   206     typedef _Graph2 Graph2;
   204     typedef P1<_Graph1> Parent1;
   207     typedef P1<_Graph1> Parent1;
   205     typedef P2<_Graph2> Parent2;
   208     typedef P2<_Graph2> Parent2;
   206     typedef typename Parent1::Node Graph1Node;
   209     typedef typename Parent1::Node Graph1Node;
   213     void first() const;
   216     void first() const;
   214     void next() const;
   217     void next() const;
   215   };
   218   };
   216 
   219 
   217 
   220 
       
   221   template <typename _Graph1, typename _Graph2>
       
   222   class MergeNodeGraphWrapper : public 
       
   223   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
       
   224   public:
       
   225     typedef _Graph1 Graph1;
       
   226     typedef _Graph2 Graph2;
       
   227     typedef IterableGraphExtender<
       
   228       MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
       
   229   protected:
       
   230     MergeNodeGraphWrapper() { }
       
   231   public:
       
   232     MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
       
   233       Parent::Parent1::setGraph(_graph1);
       
   234       Parent::Parent2::setGraph(_graph2);
       
   235     }
       
   236   };
       
   237 
       
   238 
       
   239   /*! A base class for merging the node-sets and edge-sets of 
       
   240     two node-disjoint graphs 
       
   241     into one graph.
       
   242    */
   218   template <typename _Graph1, typename _Graph2, typename Enable=void>
   243   template <typename _Graph1, typename _Graph2, typename Enable=void>
   219   class MergeNodeGraphWrapper : public 
   244   class MergeEdgeGraphWrapperBase : 
   220   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > {
   245     public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
       
   246   public:
       
   247     void printEdge() const { std::cout << "generic" << std::endl; }
       
   248     typedef _Graph1 Graph1;
       
   249     typedef _Graph2 Graph2;
       
   250     typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
       
   251     typedef typename Parent::Parent1 Parent1;
       
   252     typedef typename Parent::Parent2 Parent2;
       
   253 //     typedef P1<_Graph1> Parent1;
       
   254 //     typedef P2<_Graph2> Parent2;
       
   255     typedef typename Parent1::Edge Graph1Edge;
       
   256     typedef typename Parent2::Edge Graph2Edge;
       
   257   protected:
       
   258     MergeEdgeGraphWrapperBase() { }
       
   259   public:
       
   260     template <typename _Value> class EdgeMap;
       
   261 
       
   262     typedef typename Parent::Node Node;
       
   263 
       
   264     class Edge : public Graph1Edge, public Graph2Edge {
       
   265       friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
       
   266       template <typename Value> friend class EdgeMap;
       
   267     protected:
       
   268       bool backward; //true, iff backward
       
   269     public:
       
   270       Edge() { }
       
   271       /// \todo =false is needed, or causes problems?
       
   272       /// If \c _backward is false, then we get an edge corresponding to the 
       
   273       /// original one, otherwise its oppositely directed pair is obtained.
       
   274       Edge(const Graph1Edge& n1, 
       
   275 	   const Graph2Edge& n2, bool _backward) : 
       
   276 	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
       
   277       Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
       
   278       bool operator==(const Edge& v) const { 
       
   279 	return (this->backward==v.backward && 
       
   280 		static_cast<Graph1Edge>(*this)==
       
   281 		static_cast<Graph1Edge>(v) && 
       
   282 		static_cast<Graph2Edge>(*this)==
       
   283 		static_cast<Graph2Edge>(v));
       
   284       } 
       
   285       bool operator!=(const Edge& v) const { 
       
   286 	return (this->backward!=v.backward || 
       
   287 		static_cast<Graph1Edge>(*this)!=
       
   288 		static_cast<Graph1Edge>(v) || 
       
   289 		static_cast<Graph2Edge>(*this)!=
       
   290 		static_cast<Graph2Edge>(v));
       
   291       }
       
   292     };
       
   293 
       
   294     using Parent::first;
       
   295     void first(Edge& i) const {
       
   296       Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
       
   297       i.backward=false;
       
   298       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   299 	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   300 	i.backward=true;
       
   301       }
       
   302     }
       
   303     void firstIn(Edge& i, const Node& n) const {
       
   304       Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
       
   305       i.backward=false;
       
   306       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   307 	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
       
   308 	i.backward=true;
       
   309       }
       
   310     }
       
   311     void firstOut(Edge& i, const Node& n) const {
       
   312       Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
       
   313       i.backward=false;
       
   314       if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   315 	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
       
   316 	i.backward=true;
       
   317       }
       
   318     }
       
   319 
       
   320     using Parent::next;
       
   321     void next(Edge& i) const {
       
   322       if (!(i.backward)) {
       
   323 	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
       
   324 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   325 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   326 	  i.backward=true;
       
   327 	}
       
   328       } else {
       
   329 	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
       
   330       }
       
   331     }
       
   332     void nextIn(Edge& i) const {
       
   333       if (!(i.backward)) {
       
   334 	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
       
   335 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   336 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   337 	  i.backward=true;
       
   338 	}
       
   339       } else {
       
   340 	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
       
   341       }
       
   342     }
       
   343     void nextOut(Edge& i) const {
       
   344       if (!(i.backward)) {
       
   345 	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
       
   346 	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
       
   347 	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
       
   348 	  i.backward=true;
       
   349 	}
       
   350       } else {
       
   351 	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
       
   352       }
       
   353     }
       
   354 
       
   355     Node source(const Edge& i) const {
       
   356       if (!(i.backward)) {
       
   357 	return 
       
   358 	  Node(Parent1::graph->source(i), INVALID, false);
       
   359       } else {
       
   360 	return 
       
   361 	  Node(INVALID, Parent2::graph->source(i), true);
       
   362       }
       
   363     }
       
   364 
       
   365     Node target(const Edge& i) const {
       
   366       if (!(i.backward)) {
       
   367 	return 
       
   368 	  Node(Parent1::graph->target(i), INVALID, false);
       
   369       } else {
       
   370 	return 
       
   371 	  Node(INVALID, Parent2::graph->target(i), true);
       
   372       }
       
   373     }
       
   374 
       
   375     using Parent::id;
       
   376     int id(const Edge& n) const { 
       
   377       if (!n.backward) 
       
   378 	return this->Parent1::graph->id(n);
       
   379       else
       
   380 	return this->Parent2::graph->id(n);
       
   381     }
       
   382 
       
   383     template <typename _Value> 
       
   384     class EdgeMap : public Parent1::template EdgeMap<_Value>, 
       
   385 		    public Parent2::template EdgeMap<_Value> { 
       
   386       typedef typename Parent1::template EdgeMap<_Value> ParentMap1;
       
   387       typedef typename Parent2::template EdgeMap<_Value> ParentMap2;
       
   388     public:
       
   389       typedef _Value Value;
       
   390       typedef Edge Key;
       
   391       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
       
   392 	ParentMap1(gw), ParentMap2(gw) { }
       
   393       EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
       
   394 	      const _Value& value) : 
       
   395 	ParentMap1(gw, value), ParentMap2(gw, value) { }
       
   396       _Value operator[](const Edge& n) const {
       
   397 	if (!n.backward) 
       
   398 	  return ParentMap1::operator[](n);
       
   399 	else 
       
   400 	  return ParentMap2::operator[](n);
       
   401       }
       
   402       void set(const Edge& n, const _Value& value) {
       
   403 	if (!n.backward) 
       
   404 	  ParentMap1::set(n, value);
       
   405 	else 
       
   406 	  ParentMap2::set(n, value);
       
   407       }
       
   408 //       using ParentMap1::operator[];
       
   409 //       using ParentMap2::operator[];
       
   410     };
       
   411 
       
   412   };
       
   413 
       
   414 
       
   415   template <typename _Graph1, typename _Graph2>
       
   416   class MergeEdgeGraphWrapper : public 
       
   417   IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
   221   public:
   418   public:
   222     typedef _Graph1 Graph1;
   419     typedef _Graph1 Graph1;
   223     typedef _Graph2 Graph2;
   420     typedef _Graph2 Graph2;
   224     typedef IterableGraphExtender<
   421     typedef IterableGraphExtender<
   225       MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent;
   422       MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
   226   protected:
   423   protected:
   227     MergeNodeGraphWrapper() { }
   424     MergeEdgeGraphWrapper() { }
   228   public:
   425   public:
   229     MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
   426     MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
   230       Parent::Parent1::setGraph(_graph1);
   427       Parent::Parent1::setGraph(_graph1);
   231       Parent::Parent2::setGraph(_graph2);
   428       Parent::Parent2::setGraph(_graph2);
   232     }
   429     }
   233   };
   430   };
   234 
   431