aboutsummaryrefslogtreecommitdiffhomepage
path: root/python/google/protobuf/pyext/scoped_pyobject_ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'python/google/protobuf/pyext/scoped_pyobject_ptr.h')
-rw-r--r--python/google/protobuf/pyext/scoped_pyobject_ptr.h59
1 files changed, 34 insertions, 25 deletions
diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
index a128cd4c..a2afa7f1 100644
--- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h
+++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h
@@ -36,61 +36,70 @@
#include <google/protobuf/stubs/common.h>
#include <Python.h>
-
namespace google {
-class ScopedPyObjectPtr {
+namespace protobuf {
+namespace python {
+
+// Owns a python object and decrements the reference count on destruction.
+// This class is not threadsafe.
+template <typename PyObjectStruct>
+class ScopedPythonPtr {
public:
- // Constructor. Defaults to initializing with NULL.
- // There is no way to create an uninitialized ScopedPyObjectPtr.
- explicit ScopedPyObjectPtr(PyObject* p = NULL) : ptr_(p) { }
+ // Takes the ownership of the specified object to ScopedPythonPtr.
+ // The reference count of the specified py_object is not incremented.
+ explicit ScopedPythonPtr(PyObjectStruct* py_object = NULL)
+ : ptr_(py_object) {}
- // Destructor. If there is a PyObject object, delete it.
- ~ScopedPyObjectPtr() {
- Py_XDECREF(ptr_);
- }
+ // If a PyObject is owned, decrement its reference count.
+ ~ScopedPythonPtr() { Py_XDECREF(ptr_); }
- // Reset. Deletes the current owned object, if any.
- // Then takes ownership of a new object, if given.
+ // Deletes the current owned object, if any.
+ // Then takes ownership of a new object without incrementing the reference
+ // count.
// This function must be called with a reference that you own.
// this->reset(this->get()) is wrong!
// this->reset(this->release()) is OK.
- PyObject* reset(PyObject* p = NULL) {
+ PyObjectStruct* reset(PyObjectStruct* p = NULL) {
Py_XDECREF(ptr_);
ptr_ = p;
return ptr_;
}
- // Releases ownership of the object.
+ // Releases ownership of the object without decrementing the reference count.
// The caller now owns the returned reference.
- PyObject* release() {
+ PyObjectStruct* release() {
PyObject* p = ptr_;
ptr_ = NULL;
return p;
}
- PyObject* operator->() const {
+ PyObjectStruct* operator->() const {
assert(ptr_ != NULL);
return ptr_;
}
- PyObject* get() const { return ptr_; }
+ PyObjectStruct* get() const { return ptr_; }
- Py_ssize_t refcnt() const { return Py_REFCNT(ptr_); }
+ PyObject* as_pyobject() const { return reinterpret_cast<PyObject*>(ptr_); }
+ // Increments the reference count fo the current object.
+ // Should not be called when no object is held.
void inc() const { Py_INCREF(ptr_); }
- // Comparison operators.
- // These return whether a ScopedPyObjectPtr and a raw pointer
- // refer to the same object, not just to two different but equal
- // objects.
- bool operator==(const PyObject* p) const { return ptr_ == p; }
- bool operator!=(const PyObject* p) const { return ptr_ != p; }
+ // True when a ScopedPyObjectPtr and a raw pointer refer to the same object.
+ // Comparison operators are non reflexive.
+ bool operator==(const PyObjectStruct* p) const { return ptr_ == p; }
+ bool operator!=(const PyObjectStruct* p) const { return ptr_ != p; }
private:
- PyObject* ptr_;
+ PyObjectStruct* ptr_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPyObjectPtr);
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPythonPtr);
};
+typedef ScopedPythonPtr<PyObject> ScopedPyObjectPtr;
+
+} // namespace python
+} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__