graph_python_interface_export.cc 9.52 KB
Newer Older
1 2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// 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
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "graph_filtering.hh"
#include "graph.hh"
#include "graph_python_interface.hh"
21
#include "demangle.hh"
22 23 24

#include <boost/python.hpp>
#include <boost/lambda/bind.hpp>
25
#include <functional>
26 27 28 29 30 31 32

using namespace std;
using namespace boost;
using namespace graph_tool;

// this will register the property maps types and all its possible access
// functions to python
33
struct export_vertex_property_map
34
{
35 36 37 38 39
    template <class PropertyMap>
    void operator()(PropertyMap) const
    {
        typedef PythonPropertyMap<PropertyMap> pmap_t;

40
        string type_name;
Tiago Peixoto's avatar
Tiago Peixoto committed
41 42 43
        if (std::is_same<typename boost::mpl::find<value_types,
                                                   typename pmap_t::value_type>::type,
                         typename boost::mpl::end<value_types>::type>::value)
44
            type_name =
45
                name_demangle(typeid(typename pmap_t::value_type).name());
46 47
        else
            type_name =
Tiago Peixoto's avatar
Tiago Peixoto committed
48
                type_names[boost::mpl::find<value_types,typename pmap_t::value_type>
49
                           ::type::pos::value];
50
        string class_name = "VertexPropertyMap<" + type_name + ">";
51

Tiago Peixoto's avatar
Tiago Peixoto committed
52
        typedef typename boost::mpl::if_<
53
            typename return_reference::apply<typename pmap_t::value_type>::type,
Tiago Peixoto's avatar
Tiago Peixoto committed
54 55
            boost::python::return_internal_reference<>,
            boost::python::return_value_policy<boost::python::return_by_value> >
56 57
            ::type return_policy;

Tiago Peixoto's avatar
Tiago Peixoto committed
58
        boost::python::class_<pmap_t> pclass(class_name.c_str(),
59
                                             boost::python::no_init);
60
        pclass.def("__hash__", &pmap_t::get_hash)
61 62 63 64
            .def("value_type", &pmap_t::get_type)
            .def("get_map", &pmap_t::get_map)
            .def("get_dynamic_map", &pmap_t::get_dynamic_map)
            .def("get_array", &pmap_t::get_array)
65 66 67
            .def("is_writable", &pmap_t::is_writable)
            .def("reserve", &pmap_t::reserve)
            .def("resize", &pmap_t::resize)
68
            .def("shrink_to_fit", &pmap_t::shrink_to_fit)
Tiago Peixoto's avatar
Tiago Peixoto committed
69
            .def("swap", &pmap_t::swap)
70
            .def("data_ptr", &pmap_t::data_ptr);
71

72
        typedef boost::mpl::transform<graph_tool::all_graph_views,
73
                                      boost::mpl::quote1<std::add_const> >::type const_graph_views;
74
        typedef boost::mpl::transform<graph_tool::all_graph_views,
75 76 77 78 79 80 81 82
                                      boost::mpl::quote1<std::add_pointer> >::type all_graph_views;
        typedef boost::mpl::transform<const_graph_views,
                                      boost::mpl::quote1<std::add_pointer> >::type all_const_graph_views;
        typedef boost::mpl::joint_view<all_graph_views, all_const_graph_views>::type graph_views;

        boost::mpl::for_each<graph_views>(std::bind(dispatch_access<PropertyMap>(),
                                                    std::placeholders::_1,
                                                    std::ref(pclass), return_policy()));
83
    }
84 85 86 87 88 89 90 91 92 93

    template <class PropertyMap>
    struct dispatch_access
    {
        typedef PythonPropertyMap<PropertyMap> pmap_t;

        template <class Graph, class PClass, class ReturnPolicy>
        void operator()(Graph*, PClass& pclass, ReturnPolicy return_policy) const
        {
            pclass
94
                .def("__getitem__", &pmap_t::template get_value<PythonVertex<Graph>>,
95
                     return_policy)
96
                .def("__setitem__", &pmap_t::template set_value<PythonVertex<Graph>>);
97 98
        }
    };
99 100 101 102 103
};

struct export_edge_property_map
{
    template <class PropertyMap>
104
    struct dispatch_access
105
    {
106
        typedef PythonPropertyMap<PropertyMap> pmap_t;
107 108
        template <class Graph, class PClass, class ReturnPolicy>
        void operator()(Graph*, PClass& pclass, ReturnPolicy return_policy) const
109
        {
110
            pclass
111
                .def("__getitem__",
112
                     &pmap_t::template get_value<PythonEdge<Graph> >,
113
                     return_policy)
114
                .def("__setitem__",
115
                     &pmap_t::template set_value<PythonEdge<Graph> >);
116 117 118
        }
    };

119 120
    template <class PropertyMap>
    void operator()(PropertyMap) const
121
    {
122 123
        typedef PythonPropertyMap<PropertyMap> pmap_t;

124
        string type_name;
Tiago Peixoto's avatar
Tiago Peixoto committed
125 126 127
        if (std::is_same<typename boost::mpl::find<value_types,
                                                   typename pmap_t::value_type>::type,
                         typename boost::mpl::end<value_types>::type>::value)
128
            type_name =
129
                name_demangle(typeid(typename pmap_t::value_type).name());
130 131
        else
            type_name =
Tiago Peixoto's avatar
Tiago Peixoto committed
132
                type_names[boost::mpl::find<value_types,typename pmap_t::value_type>
133
                           ::type::pos::value];
134
        string class_name = "EdgePropertyMap<" + type_name + ">";
135

136 137 138 139 140 141
        typedef typename boost::mpl::if_<
            typename return_reference::apply<typename pmap_t::value_type>::type,
            boost::python::return_internal_reference<>,
            boost::python::return_value_policy<boost::python::return_by_value> >
            ::type return_policy;

Tiago Peixoto's avatar
Tiago Peixoto committed
142 143
        boost::python::class_<pmap_t> pclass(class_name.c_str(),
                                             boost::python::no_init);
144 145 146 147 148
        pclass.def("__hash__", &pmap_t::get_hash)
            .def("value_type", &pmap_t::get_type)
            .def("get_map", &pmap_t::get_map)
            .def("get_dynamic_map", &pmap_t::get_dynamic_map)
            .def("get_array", &pmap_t::get_array)
149 150 151
            .def("is_writable", &pmap_t::is_writable)
            .def("reserve", &pmap_t::reserve)
            .def("resize", &pmap_t::resize)
152
            .def("shrink_to_fit", &pmap_t::shrink_to_fit)
Tiago Peixoto's avatar
Tiago Peixoto committed
153
            .def("swap", &pmap_t::swap)
154
            .def("data_ptr", &pmap_t::data_ptr);
155

156

157
        typedef boost::mpl::transform<graph_tool::all_graph_views,
158
                                      boost::mpl::quote1<std::add_const> >::type const_graph_views;
159
        typedef boost::mpl::transform<graph_tool::all_graph_views,
160 161 162 163 164 165 166 167
                                      boost::mpl::quote1<std::add_pointer> >::type all_graph_views;
        typedef boost::mpl::transform<const_graph_views,
                                      boost::mpl::quote1<std::add_pointer> >::type all_const_graph_views;
        typedef boost::mpl::joint_view<all_graph_views, all_const_graph_views>::type graph_views;

        boost::mpl::for_each<graph_views>(std::bind(dispatch_access<PropertyMap>(),
                                                    std::placeholders::_1,
                                                    std::ref(pclass), return_policy()));
168 169 170 171 172 173 174 175 176 177 178
    }
};

struct export_graph_property_map
{
    template <class PropertyMap>
    void operator()(PropertyMap) const
    {
        typedef PythonPropertyMap<PropertyMap> pmap_t;

        string type_name =
Tiago Peixoto's avatar
Tiago Peixoto committed
179
            type_names[boost::mpl::find<value_types,
180
                       typename pmap_t::value_type>::type::pos::value];
181
        string class_name = "GraphPropertyMap<" + type_name + ">";
182

Tiago Peixoto's avatar
Tiago Peixoto committed
183
        typedef typename boost::mpl::if_<
184
            typename return_reference::apply<typename pmap_t::value_type>::type,
Tiago Peixoto's avatar
Tiago Peixoto committed
185 186
            boost::python::return_internal_reference<>,
            boost::python::return_value_policy<boost::python::return_by_value> >
187 188
            ::type return_policy;

Tiago Peixoto's avatar
Tiago Peixoto committed
189 190
        boost::python::class_<pmap_t> pclass(class_name.c_str(),
                                             boost::python::no_init);
191 192 193
        pclass.def("__hash__", &pmap_t::get_hash)
            .def("value_type", &pmap_t::get_type)
            .def("__getitem__", &pmap_t::template get_value<GraphInterface>,
194
                 return_policy())
195 196 197 198
            .def("__setitem__", &pmap_t::template set_value<GraphInterface>)
            .def("get_map", &pmap_t::get_map)
            .def("get_dynamic_map", &pmap_t::get_dynamic_map)
            .def("get_array", &pmap_t::get_array)
199 200 201 202
            .def("is_writable", &pmap_t::is_writable)
            .def("reserve", &pmap_t::reserve)
            .def("resize", &pmap_t::resize)
            .def("shrink_to_fit", &pmap_t::shrink_to_fit);
203 204 205
    }
};

206
void export_python_properties()
207
{
208
    typedef property_map_types::apply<
209 210
            value_types,
            GraphInterface::vertex_index_map_t,
Tiago Peixoto's avatar
Tiago Peixoto committed
211
            boost::mpl::bool_<true>
212 213
        >::type vertex_property_maps;
    typedef property_map_types::apply<
214 215
            value_types,
            GraphInterface::edge_index_map_t,
Tiago Peixoto's avatar
Tiago Peixoto committed
216
            boost::mpl::bool_<true>
217 218
        >::type edge_property_maps;
    typedef property_map_types::apply<
219 220
            value_types,
            ConstantPropertyMap<size_t,graph_property_tag>,
Tiago Peixoto's avatar
Tiago Peixoto committed
221
            boost::mpl::bool_<false>
222
        >::type graph_property_maps;
223

Tiago Peixoto's avatar
Tiago Peixoto committed
224 225 226
    boost::mpl::for_each<vertex_property_maps>(export_vertex_property_map());
    boost::mpl::for_each<edge_property_maps>(export_edge_property_map());
    boost::mpl::for_each<graph_property_maps>(export_graph_property_map());
227
}