src/work/marci/merge_node_graph_wrapper.h
author marci
Wed, 17 Nov 2004 19:37:54 +0000
changeset 1002 ea3ecb3c9846
parent 921 818510fa3d99
child 1007 a7d5fe18d8f9
permissions -rw-r--r--
MergeNodeGraphWrapper with factory
     1 /* -*- C++ -*-
     2  * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H
    18 #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H
    19 
    20 #include <lemon/invalid.h>
    21 #include <lemon/maps.h>
    22 #include <lemon/map_defines.h>
    23 #include <lemon/graph_wrapper.h>
    24 #include <iostream>
    25 
    26 namespace lemon {
    27 
    28   template <typename _Graph1, typename _Graph2, typename Enable=void>
    29   class MergeNodeGraphWrapperBase : 
    30     public GraphWrapperBase<_Graph1>, public GraphWrapperBase<_Graph2> {
    31   public:
    32     typedef _Graph1 Graph1;
    33     typedef _Graph2 Graph2;
    34     typedef GraphWrapperBase<_Graph1> Parent1;
    35     typedef GraphWrapperBase<_Graph2> Parent2;
    36     typedef typename Parent1::Node Graph1Node;
    37     typedef typename Parent2::Node Graph2Node;
    38   protected:
    39     MergeNodeGraphWrapperBase() { }
    40   public:
    41     template <typename _Value> class NodeMap;
    42 
    43     class Node : public Graph1Node, public Graph2Node {
    44       friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
    45       template <typename Value> friend class NodeMap;
    46     protected:
    47       bool backward; //true, iff backward
    48     public:
    49       Node() { }
    50       /// \todo =false is needed, or causes problems?
    51       /// If \c _backward is false, then we get an edge corresponding to the 
    52       /// original one, otherwise its oppositely directed pair is obtained.
    53       Node(const Graph1Node& n1, 
    54 	   const Graph2Node& n2, bool _backward) : 
    55 	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
    56       Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
    57       bool operator==(const Node& v) const { 
    58 	return (this->backward==v.backward && 
    59 		static_cast<Graph1Node>(*this)==
    60 		static_cast<Graph1Node>(v) && 
    61 		static_cast<Graph2Node>(*this)==
    62 		static_cast<Graph2Node>(v));
    63       } 
    64       bool operator!=(const Node& v) const { 
    65 	return (this->backward!=v.backward || 
    66 		static_cast<Graph1Node>(*this)!=
    67 		static_cast<Graph1Node>(v) || 
    68 		static_cast<Graph2Node>(*this)!=
    69 		static_cast<Graph2Node>(v));
    70       }
    71     };
    72 
    73     //typedef void Edge;
    74     class Edge { };
    75     
    76     void first(Node& i) const {
    77       Parent1::graph->first(*static_cast<Graph1Node*>(&i));
    78       i.backward=false;
    79       if (*static_cast<Graph1Node*>(&i)==INVALID) {
    80 	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
    81 	i.backward=true;
    82       }
    83     }
    84     void next(Node& i) const {
    85       if (!(i.backward)) {
    86 	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
    87 	if (*static_cast<Graph1Node*>(&i)==INVALID) {
    88 	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
    89 	  i.backward=true;
    90 	}
    91       } else {
    92 	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
    93       }
    94     }
    95 
    96     int id(const Node& n) const { 
    97       if (!n.backward) 
    98 	return this->Parent1::graph->id(n);
    99       else
   100 	return this->Parent2::graph->id(n);
   101     }
   102 
   103     template <typename _Value> 
   104     class NodeMap : public Parent1::template NodeMap<_Value>, 
   105 		    public Parent2::template NodeMap<_Value> { 
   106       typedef typename Parent1::template NodeMap<_Value> ParentMap1;
   107       typedef typename Parent2::template NodeMap<_Value> ParentMap2;
   108     public:
   109       typedef _Value Value;
   110       typedef Node Key;
   111       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
   112 	ParentMap1(gw), ParentMap2(gw) { }
   113       NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
   114 	      const _Value& value) : 
   115 	ParentMap1(gw, value), ParentMap2(gw, value) { }
   116 //       NodeMap(const NodeMap& copy)
   117 // 	: ParentMap1(copy), 
   118 // 	  ParentMap2(copy) { }
   119 //       template <typename TT>
   120 //       NodeMap(const NodeMap<TT>& copy)
   121 // 	: ParentMap1(copy),
   122 // 	  ParentMap2(copy) { }
   123 //       NodeMap& operator=(const NodeMap& copy) {
   124 // 	ParentMap1::operator=(copy);
   125 // 	ParentMap2::operator=(copy);
   126 // 	return *this;
   127 //       }
   128 //       template <typename TT>
   129 //       NodeMap& operator=(const NodeMap<TT>& copy) {
   130 // 	ParentMap1::operator=(copy);
   131 // 	ParentMap2::operator=(copy);
   132 // 	return *this;
   133 //       }
   134       _Value operator[](const Node& n) const {
   135 	if (!n.backward) 
   136 	  return ParentMap1::operator[](n);
   137 	else 
   138 	  return ParentMap2::operator[](n);
   139       }
   140       void set(const Node& n, const _Value& value) {
   141 	if (!n.backward) 
   142 	  ParentMap1::set(n, value);
   143 	else 
   144 	  ParentMap2::set(n, value);
   145       }
   146       using ParentMap1::operator[];
   147       using ParentMap2::operator[];
   148     };
   149 
   150   };
   151 
   152 
   153   template <typename _Graph1, typename _Graph2, typename Enable=void>
   154   class MergeNodeGraphWrapper : public 
   155   IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > {
   156   public:
   157     typedef _Graph1 Graph1;
   158     typedef _Graph2 Graph2;
   159     typedef IterableGraphExtender<
   160       MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent;
   161   protected:
   162     MergeNodeGraphWrapper() { }
   163   public:
   164     MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
   165       Parent::Parent1::setGraph(_graph1);
   166       Parent::Parent2::setGraph(_graph2);
   167     }
   168   };
   169 
   170 } //namespace lemon
   171 
   172 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H