Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CPPInstance.h
Go to the documentation of this file.
1#ifndef CPYRT_CPPINSTANCE_H
2#define CPYRT_CPPINSTANCE_H
3
4//////////////////////////////////////////////////////////////////////////////
5// //
6// cppjit::cpyrt::CPPInstance //
7// //
8// Python-side proxy, encapsulaties a C++ object. //
9// //
10//////////////////////////////////////////////////////////////////////////////
11
12// Bindings
13#ifndef Py_LIMITED_API
14#include "CPPScope.h"
15#endif
16#include "CallContext.h" // for Parameter
17#include "CommonDefs.h"
18#include "cppjit_interop.h"
19
20// Standard
21#include <utility>
22#include <vector>
23
24namespace cppjit::cpyrt {
25
26typedef std::vector<std::pair<ptrdiff_t, PyObject*>> CI_DatamemberCache_t;
27
29public:
30 enum EFlags {
31 kDefault = 0x0000,
32 kNoWrapConv = 0x0001, // use type as-is (eg. no smart ptr wrap)
33 kIsOwner = 0x0002, // Python instance owns C++ object/memory
34 kIsExtended = 0x0004, // has extended data
35 kIsValue = 0x0008, // was created from a by-value return
36 kIsReference = 0x0010, // represents one indirection
37 kIsArray = 0x0020, // represents an array of objects
38 kIsSmartPtr = 0x0040, // is or embeds a smart pointer
39 kIsPtrPtr = 0x0080, // represents two indirections
40 kIsRValue = 0x0100, // can be used as an r-value
41 kIsLValue = 0x0200, // can be used as an l-value
42 kNoMemReg = 0x0400, // do not register with memory regulator
43 kIsRegulated = 0x0800, // is registered with memory regulator
44 kIsActual = 0x1000, // has been downcasted to actual type
45 kHasLifeLine = 0x2000, // has a life line set
46 };
47
48public: // public, as the python C-API works with C structs
49 PyObject_HEAD void* fObject;
50 uint32_t fFlags;
51
52public:
53 // construction (never done directly)
54 CPPInstance() = delete;
55
56 void Set(void* address, EFlags flags = kDefault);
57 CPPInstance* Copy(void* cppinst, PyTypeObject* target = nullptr);
58
59 // state checking
60 bool IsExtended() const { return fFlags & kIsExtended; }
61 bool IsSmart() const { return fFlags & kIsSmartPtr; }
62
63 // access to C++ pointer and type
64 void* GetObject();
65 void*& GetObjectRaw() { return IsExtended() ? *(void**)fObject : fObject; }
66 interop::TCppScope_t ObjectIsA(bool check_smart = true) const;
67
68 // memory management: ownership of the underlying C++ object
69 void PythonOwns();
70 void CppOwns();
71
72 // data member cache
74
75 // smart pointer management
76 void SetSmart(PyObject* smart_type);
77 void* GetSmartObject() { return GetObjectRaw(); }
80
81 // cross-inheritance dispatch
82 void SetDispatchPtr(void*);
83
84 // redefine pointer to object as fixed-size array
85 void CastToArray(Py_ssize_t sz);
86 Py_ssize_t ArrayLength();
87
88 // implementation of the __reduce__ method: doesn't wrap any function by
89 // default but can be re-assigned by libraries that add C++ object
90 // serialization support, like ROOT
91 static PyCFunction& ReduceMethod();
92
93private:
94 void CreateExtension();
95 void* GetExtendedObject();
96};
97
98//- public methods -----------------------------------------------------------
99inline void CPPInstance::Set(void* address, EFlags flags) {
100 // Initialize the proxy with the pointer value 'address.'
101 if (flags != kDefault)
102 fFlags = flags;
103 GetObjectRaw() = address;
104}
105
106//----------------------------------------------------------------------------
108 // Retrieve a pointer to the held C++ object.
109 if (!IsExtended()) {
110 if (fObject && (fFlags & kIsReference))
111 return *(reinterpret_cast<void**>(fObject));
112 else
113 return fObject; // may be null
114 } else
115 return GetExtendedObject();
116}
117
118#ifndef Py_LIMITED_API
119//----------------------------------------------------------------------------
120inline interop::TCppScope_t CPPInstance::ObjectIsA(bool check_smart) const {
121 // Retrieve the C++ type identifier (or raw type if smart).
122 if (check_smart || !IsSmart())
123 return ((CPPClass*)Py_TYPE(this))->fCppType;
124 return GetSmartIsA();
125}
126#endif
127
128//- object proxy type and type verification ----------------------------------
129CPYRT_IMPORT PyTypeObject CPPInstance_Type;
130
131#ifndef Py_LIMITED_API
132template <typename T> inline bool CPPInstance_Check(T* object) {
133 // Short-circuit the type check by checking tp_new which all generated
134 // subclasses of CPPInstance inherit.
135 return object && (Py_TYPE(object)->tp_new == CPPInstance_Type.tp_new ||
136 PyObject_TypeCheck(object, &CPPInstance_Type));
137}
138#endif
139
140template <typename T> inline bool CPPInstance_CheckExact(T* object) {
141 return object && Py_TYPE(object) == &CPPInstance_Type;
142}
143
144//- helper for memory regulation (no PyTypeObject equiv. member in p2.2) -----
145void op_dealloc_nofree(CPPInstance*);
146
147} // namespace cppjit::cpyrt
148
149#endif // !CPYRT_CPPINSTANCE_H
_object PyObject
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
#define CPYRT_IMPORT
Definition CommonDefs.h:26
interop::TCppScope_t GetSmartIsA() const
void CastToArray(Py_ssize_t sz)
interop::TCppScope_t GetSmartUnderlyingType() const
PyObject_HEAD void * fObject
Definition CPPInstance.h:49
CPPInstance * Copy(void *cppinst, PyTypeObject *target=nullptr)
static PyCFunction & ReduceMethod()
void SetSmart(PyObject *smart_type)
interop::TCppScope_t ObjectIsA(bool check_smart=true) const
void Set(void *address, EFlags flags=kDefault)
Definition CPPInstance.h:99
CI_DatamemberCache_t & GetDatamemberCache()
PyTypeObject CPPInstance_Type
void op_dealloc_nofree(CPPInstance *)
bool CPPInstance_CheckExact(T *object)
std::vector< std::pair< ptrdiff_t, PyObject * > > CI_DatamemberCache_t
Definition CPPInstance.h:26
bool CPPInstance_Check(T *object)
Cpp::DeclRef TCppScope_t
Definition API.h:41