Logo ROOT  
Reference Guide
DispatchPtr.h
Go to the documentation of this file.
1#ifndef CPYCPPYY_DISPATCHPTR_H
2#define CPYCPPYY_DISPATCHPTR_H
3
4//////////////////////////////////////////////////////////////////////////////
5// //
6// DispatchPtr //
7// //
8// Smart pointer for reference management and C++ instance tracking when //
9// cross-inheriting. The carried pointer is always expected to be derived //
10// from CPPInstance, and the DispatchPtr to be embedded in the C++ instance //
11// derived dispatcher to which it points (ownership is two-way; life-times //
12// are equal). The C++ dispatcher then uses the DispatchPtr to call Python //
13// functions for virtual methods. //
14// //
15//////////////////////////////////////////////////////////////////////////////
16
17// Bindings
18#include "CPyCppyy/CommonDefs.h"
19
20
21namespace CPyCppyy {
22
24public:
25// Default constructor: only ever created from C++, as by definition, creation
26// from the Python side makes the relevant Python instance available. Calls to
27// the default ctor happen eg. in STL containers. It is expected that the
28// pointer to the Python object is filled in later, eg. through assign().
29 DispatchPtr() : fPyHardRef(nullptr), fPyWeakRef(nullptr) {}
30
31// Conversion constructor: called with C++ object construction when the PyObject
32// is known (eg. when instantiating from Python), with pyobj the Python-side
33// representation of the C++ object.
34 explicit DispatchPtr(PyObject* pyobj);
35
36// Copy constructor: only ever called from C++. The Python object needs to be
37// copied, in case it has added state, and rebound to the new C++ instance.
38 DispatchPtr(const DispatchPtr& other, void* cppinst);
39
40// Assignment: only ever called from C++. Similarly to the copy constructor, the
41// Pythonb object needs to be copied and rebound.
42 DispatchPtr& assign(const DispatchPtr& other, void* cppinst);
43
44// Do not otherwise allow straight copies/assignment.
47 DispatchPtr& operator=(const DispatchPtr& other) = delete;
48
49// lifetime is directly bound to the lifetime of the dispatcher object
51 Py_XDECREF(fPyWeakRef);
52 Py_XDECREF(fPyHardRef);
53 }
54
55// either C++ owns the Python object through a reference count (on fPyHardRef) or
56// Python owns the C++ object and we only have a weak reference (through fPyWeakRef)
57 void PythonOwns();
58 void CppOwns();
59
60// access to underlying object: cast and dereferencing
61 operator PyObject*() const {
62 return Get();
63 }
64
66 return Get();
67 }
68
69private:
70 PyObject* Get() const;
71
72private:
75};
76
77} // namespace CPyCppyy
78
79#endif // !CPYCPPYY_DISPATCHPTR_H
_object PyObject
Definition: PyMethodBase.h:41
#define CPYCPPYY_CLASS_EXTERN
Definition: CommonDefs.h:29
PyObject * fPyWeakRef
Definition: DispatchPtr.h:74
PyObject * operator->() const
Definition: DispatchPtr.h:65
DispatchPtr(DispatchPtr &)=delete
PyObject * fPyHardRef
Definition: DispatchPtr.h:73
DispatchPtr(DispatchPtr &&)=delete
DispatchPtr & operator=(const DispatchPtr &other)=delete