oli
oli

Reputation: 768

Cython importing C++ operators: "Overloading operator '+=' not yet supported."

I'm trying to use the MPFR C++ library, because I'd like to have simple operators (e.g. "+=" or even just "+") for the MPFR numbers.

My simple example is the following

cdef extern from "mpreal.h" namespace "mpfr":
    cdef cppclass mpreal:
        mpreal() except +
        mpreal(const double) except +
        mpreal& operator+=(const mpreal& v) except +

However, Cython complains

Error compiling Cython file:
------------------------------------------------------------
...

cdef extern from "mpreal.h" namespace "mpfr":
    cdef cppclass mpreal:
        mpreal() except +
        mpreal(const double) except +
        mpreal& operator+=(const mpreal& v) except +
                         ^
------------------------------------------------------------

test_000.pyx:6:26: Overloading operator '+=' not yet supported.

Some operators are mentioned on https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html to have slightly different syntax, but the "+=" operator isn't mentioned anywhere on the internet, and fairly simple and common at the same time, so I'm confused.

My question is fairly stupid: Have I made a mistake somewhere, or is the error message correct in the sense that the "+=" operator is just not yet supported by Cython? Other operators like "=" (seem to) work.

EDIT: User ead pointed out something in the src of Cython (https://github.com/cython/cython/blob/5a8c984403ce73ac29f9e8b7c78ee5f0f4c608a3/Cython/Compiler/Parsing.py#L2834) which I understand as "+=" is just not supported.

But looking at https://github.com/cython/cython/blob/5a8c984403ce73ac29f9e8b7c78ee5f0f4c608a3/Cython/Compiler/Parsing.py#L2909 I'm wondering if this could be easily extended and the code comments actually suggest that? Maybe I can figure it out myself and make a contribution, but if anyone knows what's going on I would be happy to hear about it.

        elif s.sy == '=':
            op += s.sy    # +=, -=, ...
            s.next()
        if op not in supported_overloaded_operators:
            s.error("Overloading operator '%s' not yet supported." % op,
                    fatal=False)

IMPORTANT EDIT: The discussion is on https://github.com/cython/cython/issues/3696 as well, and as it looks right now ead's suggestion will be added/fixed in Cython.

Upvotes: 1

Views: 232

Answers (1)

ead
ead

Reputation: 34367

To me it looks as if operator += was just forgotten: += (and also -=, *=, /=) are no different than the normal assignment operator =.

When I change this line in Cython-code, which enumerates supported operators, to

supported_overloaded_operators = cython.declare(set, set([
    '+', '-', '*', '/', '%',
    '++', '--', '~', '|', '&', '^', '<<', '>>', ',',
    '==', '!=', '>=', '>', '<=', '<',
    '[]', '()', '!', '=',
    'bool', '+=',            #`+=` added!
]))

I can successfully build and use the following minimalistic reproducer:

%%cython -+ -c=-std=c++11

cdef extern from *:
    """
    struct A{
    int x=42;
    A& operator+=(const A&o){
        x+=o.x;
      }
    };
    """
    cdef cppclass A:
        int x
        A& operator+=(const A& v)
        
def doit():
    cdef A a;
    a+=a;
    print(a.x)

And now:

doit()  # prints 84

does the job.

Upvotes: 1

Related Questions