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