Search code examples
c++wrapperiostreamcythonfriend

Cython wrapping operator<< from multiple namespaces


How can I wrap the operator >> overload in Cython?

//LIB.h
namespace LIB
{
    class Point
    {
        friend std::istream &operator >> (std::istream &in, Point &pt)
        bool operator == (const Point &pos) const
        ...
    }
}

There is already a namespace declared namespace "LIB":, so how do I deal with the std:: namespace?

#LIB.pxd
cdef extern from "LIB.h" namespace "LIB":
    cdef cppclass Point:
        #friend std::istream &operator >> (std::istream &in, Point &pt)
        bint operator == (const Point &pos) const
        ...

Here it explains that multiple cdef extern blocks are possible, but I don't see how that will work since I cannot redefine the class.


Solution

  • I think the easiest solution is to pretend to Cython that operator<< is a method of std::istream forgetting about the friend stuff. The C++ compiler will then sort out the pieces. So here is what seems to be a working solution (it compiles but I didn't went all the way to test it):

    Here is my LIB.h wrapped file:

    #include <iostream>
    namespace LIB {
        class Point {
            friend std::istream &operator << (std::istream &in, Point);
        };
    }
    

    And the Cython wrapper should be as follows:

    cdef extern from "LIB.h" namespace "LIB":
        cdef cppclass Point:
            pass
    
    cdef extern from "<iostream>" namespace "std":
        cdef cppclass istream:
            istream &operator << (Point)
    
        istream cin
    

    Then the following file is accepted by the compiler:

    cimport lib
    
    def foo():
        cdef lib.Point bla
    
        lib.cin << bla
    

    FYI, I compiled with:

    cython --cplus bla.pyx                  
    g++ `python-config --cflags` bla.cpp -c