COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/merge_node_graph_wrapper.h @ 1007:a7d5fe18d8f9

Last change on this file since 1007:a7d5fe18d8f9 was 1007:a7d5fe18d8f9, checked in by marci, 16 years ago

MergeNodeGraphWrapper?

File size: 7.7 KB
Line 
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#include <boost/type_traits.hpp>
27#include <boost/utility/enable_if.hpp>
28
29namespace lemon {
30
31  template <class _Graph1>
32  class P1 : public GraphWrapperBase<_Graph1> {
33  };
34
35  template <class _Graph2>
36  class P2 : public GraphWrapperBase<_Graph2> {
37  };
38
39  template <typename _Graph1, typename _Graph2, typename Enable=void>
40  class MergeNodeGraphWrapperBase :
41    public P1<_Graph1>, public P2<_Graph2> {
42  public:
43    void print() const { std::cout << "generic" << std::endl; }
44    typedef _Graph1 Graph1;
45    typedef _Graph2 Graph2;
46    typedef P1<_Graph1> Parent1;
47    typedef P2<_Graph2> Parent2;
48    typedef typename Parent1::Node Graph1Node;
49    typedef typename Parent2::Node Graph2Node;
50  protected:
51    MergeNodeGraphWrapperBase() { }
52  public:
53    template <typename _Value> class NodeMap;
54
55    class Node : public Graph1Node, public Graph2Node {
56      friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
57      template <typename Value> friend class NodeMap;
58    protected:
59      bool backward; //true, iff backward
60    public:
61      Node() { }
62      /// \todo =false is needed, or causes problems?
63      /// If \c _backward is false, then we get an edge corresponding to the
64      /// original one, otherwise its oppositely directed pair is obtained.
65      Node(const Graph1Node& n1,
66           const Graph2Node& n2, bool _backward) :
67        Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
68      Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
69      bool operator==(const Node& v) const {
70        return (this->backward==v.backward &&
71                static_cast<Graph1Node>(*this)==
72                static_cast<Graph1Node>(v) &&
73                static_cast<Graph2Node>(*this)==
74                static_cast<Graph2Node>(v));
75      }
76      bool operator!=(const Node& v) const {
77        return (this->backward!=v.backward ||
78                static_cast<Graph1Node>(*this)!=
79                static_cast<Graph1Node>(v) ||
80                static_cast<Graph2Node>(*this)!=
81                static_cast<Graph2Node>(v));
82      }
83    };
84
85    //typedef void Edge;
86    class Edge { };
87   
88    void first(Node& i) const {
89      Parent1::graph->first(*static_cast<Graph1Node*>(&i));
90      i.backward=false;
91      if (*static_cast<Graph1Node*>(&i)==INVALID) {
92        Parent2::graph->first(*static_cast<Graph2Node*>(&i));
93        i.backward=true;
94      }
95    }
96    void next(Node& i) const {
97      if (!(i.backward)) {
98        Parent1::graph->next(*static_cast<Graph1Node*>(&i));
99        if (*static_cast<Graph1Node*>(&i)==INVALID) {
100          Parent2::graph->first(*static_cast<Graph2Node*>(&i));
101          i.backward=true;
102        }
103      } else {
104        Parent2::graph->next(*static_cast<Graph2Node*>(&i));
105      }
106    }
107
108    int id(const Node& n) const {
109      if (!n.backward)
110        return this->Parent1::graph->id(n);
111      else
112        return this->Parent2::graph->id(n);
113    }
114
115    template <typename _Value>
116    class NodeMap : public Parent1::template NodeMap<_Value>,
117                    public Parent2::template NodeMap<_Value> {
118      typedef typename Parent1::template NodeMap<_Value> ParentMap1;
119      typedef typename Parent2::template NodeMap<_Value> ParentMap2;
120    public:
121      typedef _Value Value;
122      typedef Node Key;
123      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
124        ParentMap1(gw), ParentMap2(gw) { }
125      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
126              const _Value& value) :
127        ParentMap1(gw, value), ParentMap2(gw, value) { }
128//       NodeMap(const NodeMap& copy)
129//      : ParentMap1(copy),
130//        ParentMap2(copy) { }
131//       template <typename TT>
132//       NodeMap(const NodeMap<TT>& copy)
133//      : ParentMap1(copy),
134//        ParentMap2(copy) { }
135//       NodeMap& operator=(const NodeMap& copy) {
136//      ParentMap1::operator=(copy);
137//      ParentMap2::operator=(copy);
138//      return *this;
139//       }
140//       template <typename TT>
141//       NodeMap& operator=(const NodeMap<TT>& copy) {
142//      ParentMap1::operator=(copy);
143//      ParentMap2::operator=(copy);
144//      return *this;
145//       }
146      _Value operator[](const Node& n) const {
147        if (!n.backward)
148          return ParentMap1::operator[](n);
149        else
150          return ParentMap2::operator[](n);
151      }
152      void set(const Node& n, const _Value& value) {
153        if (!n.backward)
154          ParentMap1::set(n, value);
155        else
156          ParentMap2::set(n, value);
157      }
158      using ParentMap1::operator[];
159      using ParentMap2::operator[];
160    };
161
162  };
163
164  template <typename _Graph1, typename _Graph2>
165  class MergeNodeGraphWrapperBase<
166    _Graph1, _Graph2, typename boost::enable_if<
167    boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> :
168    public P1<_Graph1>, public P2<_Graph2> {
169  public :
170    void print() const { std::cout << "same" << std::endl; }
171    typedef _Graph1 Graph1;
172    typedef _Graph2 Graph2;
173    typedef P1<_Graph1> Parent1;
174    typedef P2<_Graph2> Parent2;
175    typedef typename Parent1::Node Graph1Node;
176    typedef typename Parent2::Node Graph2Node;
177  protected:
178    MergeNodeGraphWrapperBase() { }
179  public:
180    class Node { };
181    class Edge { };
182    void first() const;
183    void next() const;
184  };
185
186  template <typename _Graph1, typename _Graph2>
187  class MergeNodeGraphWrapperBase<
188    _Graph1, _Graph2, typename boost::enable_if<
189    boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> :
190    public P1<_Graph1>, public P2<_Graph2> {
191  public :
192    void print() const { std::cout << "2. nagyobb" << std::endl; }
193    typedef _Graph1 Graph1;
194    typedef _Graph2 Graph2;
195    typedef P1<_Graph1> Parent1;
196    typedef P2<_Graph2> Parent2;
197    typedef typename Parent1::Node Graph1Node;
198    typedef typename Parent2::Node Graph2Node;
199  protected:
200    MergeNodeGraphWrapperBase() { }
201  public:
202    class Node { };
203    class Edge { };
204    void first() const;
205    void next() const;
206  };
207
208  template <typename _Graph1, typename _Graph2>
209  class MergeNodeGraphWrapperBase<
210    _Graph1, _Graph2, typename boost::enable_if<
211    boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> :
212    public P1<_Graph1>, public P2<_Graph2> {
213  public :
214    void print() const { std::cout << "1. nagyobb" << std::endl; }
215    typedef _Graph1 Graph1;
216    typedef _Graph2 Graph2;
217    typedef P1<_Graph1> Parent1;
218    typedef P2<_Graph2> Parent2;
219    typedef typename Parent1::Node Graph1Node;
220    typedef typename Parent2::Node Graph2Node;
221  protected:
222    MergeNodeGraphWrapperBase() { }
223  public:
224    class Node { };
225    class Edge { };
226    void first() const;
227    void next() const;
228  };
229
230
231  template <typename _Graph1, typename _Graph2, typename Enable=void>
232  class MergeNodeGraphWrapper : public
233  IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > {
234  public:
235    typedef _Graph1 Graph1;
236    typedef _Graph2 Graph2;
237    typedef IterableGraphExtender<
238      MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent;
239  protected:
240    MergeNodeGraphWrapper() { }
241  public:
242    MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
243      Parent::Parent1::setGraph(_graph1);
244      Parent::Parent2::setGraph(_graph2);
245    }
246  };
247
248} //namespace lemon
249
250#endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H
Note: See TracBrowser for help on using the repository browser.