graph_bind.cc 7.35 KB
Newer Older
Tiago Peixoto's avatar
Tiago Peixoto committed
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>
Tiago Peixoto's avatar
Tiago Peixoto committed
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
Tiago Peixoto's avatar
Tiago Peixoto committed
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
17
// along with this program. If not, see <http://www.gnu.org/licenses/>.

Tiago Peixoto's avatar
Tiago Peixoto committed
18
#include "graph.hh"
19
#include "graph_python_interface.hh"
Tiago Peixoto's avatar
Tiago Peixoto committed
20

21
22
23
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

Tiago Peixoto's avatar
Tiago Peixoto committed
24
25
26
27
28
using namespace std;
using namespace graph_tool;
using namespace boost;
using namespace boost::python;

29
struct LibInfo
Tiago Peixoto's avatar
Tiago Peixoto committed
30
{
31
32
33
34
35
36
37
38
39
    string GetName()      const {return PACKAGE_NAME;}
    string GetAuthor()    const {return AUTHOR;}
    string GetCopyright() const {return COPYRIGHT;}
    string GetVersion()   const {return VERSION " (commit " GIT_COMMIT
                                        ", " GIT_COMMIT_DATE ")";}
    string GetLicense()   const {return "GPL version 3 or above";}
    string GetCXXFLAGS()  const {return CXXFLAGS;}
    string GetInstallPrefix() const {return INSTALL_PREFIX;}
    string GetPythonDir() const {return PYTHON_DIR;}
Tiago Peixoto's avatar
Tiago Peixoto committed
40
41
};

42
43
template <class ValueType>
struct vector_from_list
Tiago Peixoto's avatar
Tiago Peixoto committed
44
{
45
    vector_from_list()
Tiago Peixoto's avatar
Tiago Peixoto committed
46
    {
47
        converter::registry::push_back
48
            (&convertible, &construct,
49
             boost::python::type_id<vector<ValueType> >());
Tiago Peixoto's avatar
Tiago Peixoto committed
50
51
52
53
    }

    static void* convertible(PyObject* obj_ptr)
    {
54
55
        handle<> x(borrowed(obj_ptr));
        object o(x);
56
57
58
59
60
61
62
        size_t N = len(o);
        for (size_t i = 0; i < N; ++i)
        {
            extract<ValueType> elem(o[i]);
            if (!elem.check())
                return 0;
        }
63
        return obj_ptr;
Tiago Peixoto's avatar
Tiago Peixoto committed
64
65
    }

66
    static void construct(PyObject* obj_ptr,
67
                          converter::rvalue_from_python_stage1_data* data)
68
    {
69
70
        handle<> x(borrowed(obj_ptr));
        object o(x);
71
72
73
74
        vector<ValueType> value;
        size_t N = len(o);
        for (size_t i = 0; i < N; ++i)
            value.push_back(extract<ValueType>(o[i]));
75
        void* storage =
76
            ( (boost::python::converter::rvalue_from_python_storage
77
78
               <vector<ValueType> >*) data)->storage.bytes;
        new (storage) vector<ValueType>(value);
79
        data->convertible = storage;
Tiago Peixoto's avatar
Tiago Peixoto committed
80
81
82
    }
};

83
struct export_vector_types
Tiago Peixoto's avatar
Tiago Peixoto committed
84
{
85
86
    template <class ValueType>
    void operator()(ValueType) const
Tiago Peixoto's avatar
Tiago Peixoto committed
87
    {
88
89
90
91
92
93
94
        string type_name = get_type_name<>()(typeid(ValueType));
        if (type_name == "long double")
            type_name = "long_double";
        string name = "Vector_" + type_name;
        class_<vector<ValueType> >(name.c_str())
            .def(vector_indexing_suite<vector<ValueType> >());
        vector_from_list<ValueType>();
Tiago Peixoto's avatar
Tiago Peixoto committed
95
    }
96
};
Tiago Peixoto's avatar
Tiago Peixoto committed
97

98
99
100
101
// exception translation
static PyObject* pyex =
    PyErr_NewException((char *) "libgraph_tool_core.GraphError",
                       PyExc_Exception, NULL);
Tiago Peixoto's avatar
Tiago Peixoto committed
102

103
104
105
106
107
108
void graph_exception_translator(const GraphException& e)
{
    PyObject* message = PyString_FromString(e.what());
    PyObject_SetAttrString(pyex, "message", message);
    PyErr_SetString(pyex, e.what());
}
Tiago Peixoto's avatar
Tiago Peixoto committed
109

110
111
112
113
114
template <class Exception>
void translate(const Exception& e)
{
    PyErr_SetString(PyExc_RuntimeError, e.what());
}
Tiago Peixoto's avatar
Tiago Peixoto committed
115

116
117
118
119
void raise_error(const string& msg)
{
    throw GraphException(msg);
}
Tiago Peixoto's avatar
Tiago Peixoto committed
120

121
122
template <class T1, class T2>
struct pair_to_tuple
Tiago Peixoto's avatar
Tiago Peixoto committed
123
{
124
    static PyObject* convert(const pair<T1,T2>& p)
Tiago Peixoto's avatar
Tiago Peixoto committed
125
    {
126
127
        boost::python::tuple t = boost::python::make_tuple(p.first,p.second);
        return incref(t.ptr());
Tiago Peixoto's avatar
Tiago Peixoto committed
128
129
130
    }
};

131
BOOST_PYTHON_MODULE(libgraph_tool_core)
Tiago Peixoto's avatar
Tiago Peixoto committed
132
{
133
    GraphInterface().ExportPythonInterface();
Tiago Peixoto's avatar
Tiago Peixoto committed
134

135
136
    PyModule_AddObject(python::detail::current_scope, "GraphError", pyex);
    register_exception_translator<GraphException>(graph_exception_translator);
Tiago Peixoto's avatar
Tiago Peixoto committed
137

138
    def("raise_error", &raise_error);
139

140
141
142
143
    mpl::for_each<mpl::push_back<scalar_types,string>::type>(export_vector_types());

    class_<GraphInterface>("GraphInterface", init<>())
        .def(init<GraphInterface>())
144
145
146
147
148
149
150
151
        .def("GetNumberOfVertices", &GraphInterface::GetNumberOfVertices)
        .def("GetNumberOfEdges", &GraphInterface::GetNumberOfEdges)
        .def("SetDirected", &GraphInterface::SetDirected)
        .def("GetDirected", &GraphInterface::GetDirected)
        .def("SetReversed", &GraphInterface::SetReversed)
        .def("GetReversed", &GraphInterface::GetReversed)
        .def("SetVertexFilterProperty",
             &GraphInterface::SetVertexFilterProperty)
152
153
        .def("GetVertexFilterProperty",
             &GraphInterface::GetVertexFilterProperty)
154
        .def("IsVertexFilterActive", &GraphInterface::IsVertexFilterActive)
155
        .def("SetEdgeFilterProperty",
156
             &GraphInterface::SetEdgeFilterProperty)
157
158
        .def("GetEdgeFilterProperty",
             &GraphInterface::GetEdgeFilterProperty)
159
        .def("IsEdgeFilterActive", &GraphInterface::IsEdgeFilterActive)
160
161
162
        .def("AddEdgeProperty",  &GraphInterface::AddEdgeProperty)
        .def("AddVertexProperty",  &GraphInterface::AddVertexProperty)
        .def("AddGraphProperty",  &GraphInterface::AddGraphProperty)
163
164
165
166
167
        .def("RemoveEdgeProperty",  &GraphInterface::RemoveEdgeProperty)
        .def("RemoveVertexProperty",  &GraphInterface::RemoveVertexProperty)
        .def("RemoveGraphProperty",  &GraphInterface::RemoveGraphProperty)
        .def("PurgeVertices",  &GraphInterface::PurgeVertices)
        .def("PurgeEdges",  &GraphInterface::PurgeEdges)
168
        .def("ReIndexEdges",  &GraphInterface::ReIndexEdges)
169
170
171
172
        .def("InsertEdgeIndexProperty",
             &GraphInterface::InsertEdgeIndexProperty)
        .def("InsertVertexIndexProperty",
             &GraphInterface::InsertVertexIndexProperty)
173
174
        .def("WriteToFile", &GraphInterface::WriteToFile)
        .def("ReadFromFile",&GraphInterface::ReadFromFile)
175
        .def("Vertices", &GraphInterface::Vertices)
176
        .def("Vertex", &GraphInterface::Vertex)
177
178
179
180
181
        .def("Edges", &GraphInterface::Edges)
        .def("AddVertex", &GraphInterface::AddVertex)
        .def("AddEdge", &GraphInterface::AddEdge)
        .def("RemoveVertex", &GraphInterface::RemoveVertex)
        .def("RemoveEdge", &GraphInterface::RemoveEdge)
182
        .def("Clear", &GraphInterface::Clear)
183
184
185
        .def("GetVertexProperties", &GraphInterface::GetVertexProperties)
        .def("GetEdgeProperties", &GraphInterface::GetEdgeProperties)
        .def("GetGraphProperties", &GraphInterface::GetGraphProperties)
186
187
        .def("InitSignalHandling", &GraphInterface::InitSignalHandling);

188
    to_python_converter<pair<string,bool>, pair_to_tuple<string,bool> >();
Tiago Peixoto's avatar
Tiago Peixoto committed
189
190

    class_<LibInfo>("mod_info")
191
192
193
        .add_property("name", &LibInfo::GetName)
        .add_property("author", &LibInfo::GetAuthor)
        .add_property("copyright", &LibInfo::GetCopyright)
194
        .add_property("version", &LibInfo::GetVersion)
195
196
197
198
        .add_property("license", &LibInfo::GetLicense)
        .add_property("cxxflags", &LibInfo::GetCXXFLAGS)
        .add_property("install_prefix", &LibInfo::GetInstallPrefix)
        .add_property("python_dir", &LibInfo::GetPythonDir);
Tiago Peixoto's avatar
Tiago Peixoto committed
199
}