Stefan Behnel wrote:
> Hi,
> 
> Robert Bradshaw wrote:
>> On Jun 26, 2009, at 10:42 PM, Stefan Behnel wrote:
>>> Somebody snipped wrote:
>>>> Also, objects declared inside a C++ class are taken as C types  
>>>> (Python objects not allowed)
>>> Why not? They'd map to a PyObject*, which Cython code would ref- 
>>> count its
>>> access to. If you change it from C++ code, you'd just be on your  
>>> own, as
>>> usual. Same for the C++ destructor, which Cython won't generate for  
>>> you. Call it an advanced feature.
>> It is unclear what the semantics of an object member 
>> would be. Would it there be a guarantee that it is set to a non-NULL  
>> increfed value on construction? Does the dectructor have a contract  
>> to decref it? It's probably better to require a specific cast here to  
>> signal from this point on refcounting has to be done manually (either  
>> by the user, or by the C++ library author).
> 
> Good points. Let's forbid that for the time being.

I don't disagree with forbidding it at first, but I actually think that 
getting this right is very easy by using some C++.

It would be very nice to allow e.g.

cdef cpp.vector[object] x

(I.e. std::vector<PyObject*>). Of course, that means that all the
methods on x etc. would take "object". This can be implemented correctly 
(and guaranteed to be correct) by mapping object (in a cppclass context) 
to __Pyx_SmartPtr, which is implemented thusly:

class __Pyx_SmartPtr {
private:
     PyObject* m_ptr;
public:
     __Pyx_SmartPtr(PyObject* ptr) : m_ptr(ptr) {
         if (!ptr) throw new std::exception("NULL not allowed")
         Py_INCREF(ptr);
     }
     ~__Pyx_SmartPtr() {
         Py_DECREF(m_ptr);
     }
     PyObject* rawptr() const { return m_ptr; }
     PyObject* operator*() const { return m_ptr; }
     PyObject* operator->() const { return m_ptr; }
     const __Pyx_SmartPtr& operator=(const __Pyx_SmartPtr& other) const {
         Py_INCREF(other.m_ptr);
         Py_DECREF(m_ptr);
         m_ptr = other.m_ptr;
     }
};

(This kind of thing actually makes me fond of C++ -- it's just the 
thought that a __Pyx_SmartPtr has the same size and run-time storage 
format as a PyObject*, yet refcounting happens correctly).

(For non-template classes the author would need to know about 
__Pyx_SmartPtr from a header; which might not be far from object being 
disallowed -- I think this is ok.)

Extending on this concept, using a C++ template, one could add
type-checking as well, so that we can further correctly implement:

cdef cpp.vector<MyCdefClass> x

-- 
Dag Sverre

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to