Templated internal typedef

34 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Nathann Cohen

ungelesen,
04.06.2015, 05:11:2104.06.15
an cython...@googlegroups.com
Hello everybody,

I am trying to call Boost code [1] from Cython, and I would like to import a
type definition without without creating an intermediate .cc file.

My problem is that the type is declared inside of a templated struct (i.e. first
lines of [2]):

namespace boost {
template <typename G>
struct graph_traits {
typedef typename G::vertex_descriptor vertex_descriptor;
}
}

My latest (unfortunate) attempt is:

cdef extern from "boost/graph/graph_traits.hpp" namespace "boost":
cdef cppclass graph_traits[UndirectedGraph]:
pass
ctypedef graph_traits[UndirectedGraph].edge_descriptor edge_descriptor

result: 'graph_traits[UndirectedGraph].edge_descriptor' is not a type
identifier.

Thank you very much for any help you could provide on the matter ^^;

Nathann

PS: I googled it at first and saw several persons asking the same questions on
other forums (e.g. stackoverflow). But I found none to be very conclusive.

[1] http://www.boost.org/
[2] http://www.boost.org/doc/libs/1_46_0/boost/graph/graph_traits.hpp

ques...@sky.com

ungelesen,
05.06.2015, 10:23:0305.06.15
an cython...@googlegroups.com


On Thursday, June 4, 2015 at 10:11:21 AM UTC+1, Nathann Cohen wrote:
Hello everybody,

I am trying to call Boost code [1] from Cython, and I would like to import a
type definition without without creating an intermediate .cc file.

My problem is that the type is declared inside of a templated struct (i.e. first
lines of [2]):

    namespace boost {
        template <typename G>
        struct graph_traits {
            typedef typename G::vertex_descriptor     vertex_descriptor;
        }
    }


This is how I did it 
cdef extern from "<boost/graph/graph_traits.hpp>" namespace "boost":
   
## WARNING:  Cython does not know that the type that the traits class might return
## a built-in type, so it creates a destructor for an instantiation.
## If one of these types has to be instanitated then cython seems to cope ok if a
## an opaque struct for the name is defined.

    cdef cppclass graph_traits
[Graph]:

        cppclass vertex_descriptor
:
            bint
operator==(vertex_descriptor) nogil
            bint
operator!=(vertex_descriptor) nogil


        cppclass edge_descriptor
:
            bint
operator==(edge_descriptor) nogil
            bint
operator!=(edge_descriptor) nogil

        cppclass vertices_size_type
:
           
pass

        cppclass edges_size_type
:
           
pass

        cppclass degree_size_type
:
           
pass

        cppclass vertex_iterator
:
            vertex_descriptor
& operator*() nogil
            vertex_iterator
operator++() nogil
           
#vertex_iterator operator--() nogil
            bint
operator==(vertex_iterator) nogil
            bint
operator!=(vertex_iterator) nogil

        cppclass adjacency_iterator
:
            vertex_descriptor
& operator*() nogil
            adjacency_iterator
operator++() nogil
            adjacency_iterator
operator--() nogil
            bint
operator==(adjacency_iterator) nogil
            bint
operator!=(adjacency_iterator) nogil
           
        cppclass edge_iterator
:
            edge_descriptor
& operator*() nogil
            edge_iterator
operator++() nogil
            edge_iterator
operator--() nogil
            bint
operator==(edge_iterator) nogil
            bint
operator!=(edge_iterator) nogil

        cppclass in_edge_iterator
:
            edge_descriptor
& operator*() nogil
            in_edge_iterator
operator++() nogil
            in_edge_iterator
operator--() nogil
            bint
operator==(in_edge_iterator) nogil
            bint
operator!=(in_edge_iterator) nogil
       
        cppclass out_edge_iterator
:
            edge_descriptor
& operator*() nogil
            out_edge_iterator
operator++() nogil
            out_edge_iterator
operator--() nogil
            bint
operator==(out_edge_iterator) nogil
            bint
operator!=(out_edge_iterator) nogil
       
        vertex_descriptor null_vertex
()
       
    cdef bint is_directed
[Graph](Graph&)

    cdef cppclass vertex_bundle_type
[Graph]:
        cppclass type
:
           
pass
   
    cdef cppclass edge_bundle_type
[Graph]:
        cppclass type
:
           
pass
   
    cdef cppclass graph_bundle_type
[Graph]:
        cppclass type
:
           
pass
 
I then use it as follows.  This is incomplete and depends on some c++ implementation code to run but should give you the approach: 
def extern from "<boost/graph/adjacency_list.hpp>" namespace "boost":
    cdef cppclass  
BGLDirectedGraph"boost::adjacency_list<boost::multisetS, boost::listS, boost::bidirectionalS, sage::VertexP, sage::EdgeP, sage::GraphP, boost::listS>":
       
BGLDirectedGraph(const GraphP&)
       
BGLDirectedGraph()
#        BGLDirectedGraph(graph_traits[BGLDirectedGraph].vertices_size_type, const GraphP&)
       
BGLDirectedGraph(graph_traits[BGLDirectedGraph].vertices_size_type)
       
       
VertexP& operator[](graph_traits[BGLDirectedGraph].vertex_descriptor) nogil
       
EdgeP&   operator[](graph_traits[BGLDirectedGraph].edge_descriptor) nogil
       
GraphP&  operator[](graph_bundle_t) nogil

       
void added_vertex(graph_traits[BGLDirectedGraph].vertex_descriptor)
       
void removing_vertex(graph_traits[BGLDirectedGraph].vertex_descriptor v, stable_tag tag)

ctypedef
BGLDirectedGraph GraphT  #Convenience typedef

cdef
extern from "<boost/graph/graph_traits.hpp>":
    cdef graph_traits
[GraphT].vertex_descriptor null_vertex "boost::graph_traits<boost::adjacency_list<boost::multisetS, boost::listS, boost::bidirectionalS, sage::VertexP, sage::EdgeP, sage::GraphP, boost::listS>>::null_vertex"()

#from sage.graphs.bgl_base.libboost.adjacency_list cimport *

#Define the types to use:
ctypedef graph_traits
[GraphT].vertex_descriptor vertex_descriptor
ctypedef graph_traits
[GraphT].edge_descriptor edge_descriptor
ctypedef graph_traits
[GraphT].vertices_size_type vertices_size_type
ctypedef graph_traits
[GraphT].edges_size_type edges_size_type

I have implemented a sage graph backend that uses BGL if that is of any interest to you.  still lots to do though.  I created a CGraph style underlying class to

Nathann Cohen

ungelesen,
07.06.2015, 07:10:2707.06.15
an cython...@googlegroups.com
Helloooooooooooo !

> I have implemented a sage graph backend that uses BGL if that is of any
> interest to you. still lots to do though. I created a CGraph style
> underlying class to

Thank you very much for your help ! I was trying to simplify a bit
some Sage interface with Boost proposed by Michele Borassi [1]

It would be very cool if you felt like working with us on this kind of
code, for there are probably many things defined in Boost that could
be useful in Sage. I'll send you a private email in a second :-)

Have fuuuuuuuun,

Nathann

[1] http://trac.sagemath.org/ticket/18564
Allen antworten
Antwort an Autor
Weiterleiten
0 neue Nachrichten