%Module Frac %HeaderCode #include typedef Fraction* (*binary_fraction_op_t) (Fraction*, Fraction*); PyObject* BinaryOp(PyObject* sipArgs, binary_fraction_op_t op); Fraction* plus (Fraction* x, Fraction* y); Fraction* minus (Fraction* x, Fraction* y); Fraction* mult (Fraction* x, Fraction* y); Fraction* div (Fraction* x, Fraction* y); %End %C++Code Fraction* plus (Fraction* x, Fraction* y) { return new Fraction(*x + *y); } Fraction* minus (Fraction* x, Fraction* y) { return new Fraction(*x - *y); } Fraction* mult (Fraction* x, Fraction* y) { return new Fraction(*x * *y); } Fraction* div (Fraction* x, Fraction* y) { return new Fraction(*x / *y); } /** Binary operations use essentialy the same code. So instead of repeating ourselves, we write the checking code, and delegate the operation itself to a callback */ PyObject* BinaryOp(PyObject* sipArgs, binary_fraction_op_t op) { Fraction *ptr1, *ptr2; PyObject* res; int sipArgsParsed = 0; /** Extract operands and make sure that they are "really" fractions */ if (sipParseArgs(&sipArgsParsed,sipArgs,"J1J1", sipClass_Fraction, &ptr1, sipClass_Fraction, &ptr2 ) ) { /* ptr1 and ptr2 point to fractions */ return sipNewCppToSelf ( op(ptr1, ptr2), sipClass_Fraction, SIP_SIMPLE | SIP_PY_OWNED ); } return NULL; } %End class Fraction { public: Fraction(int , int=1 ); Fraction(const Fraction&); int numerator() const; int denominator() const; void __add__() /NonLazy/; %MemberCode return BinaryOp (sipArgs,plus); %End void __sub__ () /NonLazy/; %MemberCode return BinaryOp (sipArgs,minus); %End void __mul__() /NonLazy/; %MemberCode return BinaryOp (sipArgs,mult); %End void __div__() /NonLazy/; %MemberCode return BinaryOp (sipArgs,div); %End void __float__() /NonLazy/; %MemberCode Fraction* ptr; if (sipParseArgs( &sipArgsParsed,sipArgs,"J1",sipClass_Fraction,&ptr )) { double x = (double)ptr->numerator() / ptr->denominator(); return Py_BuildValue ( "d", x ); } %End void __coerce__() /NonLazy/; %MemberCode Fraction* ptr; long i; bool success = false; PyObject *a0, *a1; a0 = PyTuple_GetItem ( sipArgs,0 ); a1 = PyTuple_GetItem ( sipArgs,1 ); if (!sipIsSubClassInstance(a0, sipClass_Fraction)) return NULL; // this should not happen if (sipIsSubClassInstance(a1, sipClass_Fraction)) { return Py_BuildValue("(OO)",a0,a1); } if ( PyLong_Check(a1) ) { success = true; i = PyLong_AsLong (a1); } else if ( PyInt_Check(a1) ) { success = true; i = PyInt_AsLong (a1); } if (success) { return Py_BuildValue("(Oi)",a0, i ); } else { return NULL; } %End void __str__() /NonLazy/; %MemberCode Fraction* ptr; std::string res; if (sipParseArgs(&sipArgsParsed,sipArgs,"J1",sipClass_Fraction,&ptr)) { res = ptr->toString(); return PyString_FromString(res.c_str()); } %End }; int gcd(int, int);