graph_python_interface.hh 4.68 KB
Newer Older
1
2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2007  Tiago de Paula Peixoto <tiago@forked.de>
4
5
6
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
Tiago Peixoto's avatar
Tiago Peixoto committed
7
// as published by the Free Software Foundation; either version 3
8
9
10
11
12
13
14
15
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18
19
20

#ifndef PYTHON_FILTERING_HH
#define PYTHON_FILTERING_HH

21
#include <boost/python.hpp>
22
23
#include <boost/graph/graph_traits.hpp>
#include <boost/mpl/logical.hpp>
24
#include <boost/functional/hash.hpp>
25
#include <boost/iterator/iterator_facade.hpp>
26

27
#include "graph_selectors.hh"
28

29
// this file includes a simple python interface for the internally kept
30
31
32
33
// graph. It defines a PythonVertex, PythonEdge and PythonIterator template
// classes, which contain the proper member functions for graph traversal. These
// types are then specialized for each version of the adapted graph (directed,
// undirected, filtered, reversed).
34

35
36
37
38
namespace graph_tool
{
using namespace boost;

39
40
41
42
// generic iterator adaptor which can be used to iterate vertices, edges,
// out_edges and in_edges through python
template <class Graph, class Descriptor, class Iterator>
class PythonIterator
43
{
44
public:
45
46
47
    PythonIterator(const Graph& g, std::pair<Iterator,Iterator> e)
        : _g(g), _e(e) {}
    Descriptor Next()
48
    {
49
50
51
52
53
        if (_e.first == _e.second)
            python::objects::stop_iteration_error();
        Descriptor e(_g, *_e.first);
        ++_e.first;
        return e;
54
55
    }
private:
56
57
    const Graph& _g;
    std::pair<Iterator,Iterator> _e;
Tiago Peixoto's avatar
Tiago Peixoto committed
58
59
60
};


61
// forward declaration of PythonEdge
62
63
template <class Graph>
class PythonEdge;
64

65
// below are classes related to the PythonVertex type
66
template <class Graph>
67
    class PythonVertex
68
69
70
71
{
public:
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
    typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
72

73
74
    PythonVertex(const Graph& g, vertex_descriptor v):
        _g(g), _v(v) {}
75

76
    PythonVertex(const PythonVertex& v): _g(v._g)
77
    {
78
        _v = v._v;
79
    }
80

81
    size_t GetInDegree() const
82
    {
83
        return in_degreeS()(_v, _g);
84
    }
85

86
    size_t GetOutDegree() const
87
    {
88
        return out_degreeS()(_v, _g);
Tiago Peixoto's avatar
Tiago Peixoto committed
89
90
    }

91
    // provide iterator support for out_edges
Tiago Peixoto's avatar
Tiago Peixoto committed
92
93

    typedef typename graph_traits<Graph>::out_edge_iterator out_edge_iterator;
94
95
    PythonIterator<Graph,PythonEdge<Graph>,out_edge_iterator>
    OutEdges() const
Tiago Peixoto's avatar
Tiago Peixoto committed
96
    {
97
98
        return PythonIterator<Graph,PythonEdge<Graph>,out_edge_iterator>
            (_g, out_edges(_v, _g));
99
    }
100

101
102
103
    typedef typename in_edge_iteratorS<Graph>::type in_edge_iterator;
    PythonIterator<Graph,PythonEdge<Graph>, in_edge_iterator>
    InEdges() const
104
    {
105
106
        return PythonIterator<Graph,PythonEdge<Graph>,in_edge_iterator>
            (_g, in_edge_iteratorS<Graph>::in_edges(_v, _g));
Tiago Peixoto's avatar
Tiago Peixoto committed
107
108
    }

109
    size_t GetHash() const
110
    {
111
        return hash<vertex_descriptor>()(_v);
112
113
    }

114
    bool operator==(const PythonVertex& other) const
115
    {
116
        return other._v == _v;
117
    }
118

119
    bool operator!=(const PythonVertex& other) const
120
    {
121
        return other._v != _v;
122
123
    }

124
private:
125
126
    const Graph& _g;
    vertex_descriptor _v;
127
};
128

129
// below are classes related to the PythonEdge type
130

131
132
133
134
template <class Graph>
class PythonEdge
{
public:
Tiago Peixoto's avatar
Tiago Peixoto committed
135
136
137
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
    typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;

138
139
    PythonEdge(const Graph& g, edge_descriptor e): _g(g), _e(e) {}
    PythonEdge(const PythonEdge& e): _g(e._g)
Tiago Peixoto's avatar
Tiago Peixoto committed
140
    {
141
        _e = e._e;
Tiago Peixoto's avatar
Tiago Peixoto committed
142
143
    }

144
    PythonVertex<Graph> GetSource() const
Tiago Peixoto's avatar
Tiago Peixoto committed
145
    {
146
        return PythonVertex<Graph>(_g, source(_e, _g));
Tiago Peixoto's avatar
Tiago Peixoto committed
147
148
    }

149
    PythonVertex<Graph> GetTarget() const
Tiago Peixoto's avatar
Tiago Peixoto committed
150
    {
151
        return PythonVertex<Graph>(_g, target(_e, _g));
Tiago Peixoto's avatar
Tiago Peixoto committed
152
153
    }

154
    size_t GetHash() const
Tiago Peixoto's avatar
Tiago Peixoto committed
155
    {
156
157
158
159
160
        vertex_descriptor s,t;
        s = source(_e, _g);
        t = target(_e, _g);
        return hash<std::pair<vertex_descriptor, vertex_descriptor> >()
            (make_pair(s,t));
Tiago Peixoto's avatar
Tiago Peixoto committed
161
162
    }

163
    bool operator==(const PythonEdge& other) const
Tiago Peixoto's avatar
Tiago Peixoto committed
164
    {
165
        return other._e == _e;
Tiago Peixoto's avatar
Tiago Peixoto committed
166
    }
167

168
    bool operator!=(const PythonEdge& other) const
169
    {
170
        return other._e != _e;
171
172
173
    }

private:
174
175
    const Graph& _g;
    edge_descriptor _e;
176
177
};

178
179
180
} //graph_tool namespace

#endif