HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PY_OpaqueObject.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  * Instances of this class hold a reference to a Python object. When this
8  * object is destroyed, the reference count on the Python object will be
9  * decremented.
10  *
11  * Unlike PY_AutoObject.h, it is ok to include this header file from other
12  * header files.
13  */
14 
15 #ifndef __PY_OpaqueObject_h__
16 #define __PY_OpaqueObject_h__
17 
18 #include "PY_API.h"
19 #include <stdlib.h>
20 #include <cstddef>
21 
22 class PY_PyObject;
23 
25 {
26 public:
27  PY_OpaqueObject() noexcept {};
28  PY_OpaqueObject(std::nullptr_t) noexcept {};
29 
30  /// Construct instances of this class with an opaque PY_PyObject pointer
31  /// (which may be null). On destruction, the reference counter will be
32  /// decremented. By default, opaque_py_object will have its reference count
33  /// incremented on construction. To avoid this, set new_ref=true to signify
34  /// that we are being passed ownership of a new object.
35  explicit
36  PY_OpaqueObject(void *opaque_py_object, bool new_ref = false) noexcept
37  {
38  reset(opaque_py_object, new_ref);
39  }
41  {
42  reset();
43  }
44 
45  /// Copy construct/assign
46  /// @{
47  PY_OpaqueObject(const PY_OpaqueObject &opaque_object) noexcept
48  {
49  reset(opaque_object.myOpaqueObject, /*new_ref*/false);
50  }
51  PY_OpaqueObject &operator=(const PY_OpaqueObject &opaque_object) noexcept
52  {
53  if (this != &opaque_object)
54  reset(opaque_object.myOpaqueObject, /*new_ref*/false);
55  return *this;
56  }
57  /// @}
58 
59  /// Move construct/assign
60  /// @{
61  PY_OpaqueObject(PY_OpaqueObject &&opaque_object) noexcept
62  : myOpaqueObject(opaque_object.myOpaqueObject)
63  {
64  opaque_object.myOpaqueObject = nullptr;
65  }
66  PY_OpaqueObject &operator=(PY_OpaqueObject &&opaque_object) noexcept
67  {
68  reset(opaque_object.myOpaqueObject, /*new_ref*/true);
69  opaque_object.myOpaqueObject = nullptr;
70  return *this;
71  }
72  PY_OpaqueObject &operator=(std::nullptr_t) noexcept
73  {
74  reset();
75  return *this;
76  }
77  /// @}
78 
79  /// Releases ownership and sets to nullptr
80  void reset() noexcept;
81 
82  /// Release ownerhsip of old ptr and assign a new PY_PyObject.
83  /// If !new_ref (aka borrowed), opaque_py_object's refcount is incremented
84  void reset(void *opaque_py_object, bool new_ref) noexcept;
85 
86  /// Set to the Py_None()
87  void resetToNone();
88 
89  /// Return a borrowed reference to our opaque PyObject *. If the caller
90  /// will hold a reference to this object after the PY_OpaqueObject has been
91  /// deleted, it is up to the caller to increment the reference count.
92  void *opaqueObject() const noexcept
93  { return myOpaqueObject; }
94 
95  /// Releases ownership of the managed object as a void *, and resets.
96  void *releaseOpaqueObject() noexcept
97  {
98  auto ptr = opaqueObject();
99  myOpaqueObject = nullptr;
100  return ptr;
101  }
102 
103  /// Return a borrowed reference as a PyObject *.
104  ///
105  /// Using this method requires that the caller includes PY_CPythonAPI.h,
106  /// only call this in a .C file to avoid polluting Python header symbols
107  /// into rest of the codebase.
108  PY_PyObject *pyObject() const noexcept
109  { return static_cast<PY_PyObject*>(myOpaqueObject); }
110 
111  /// Releases ownership of the managed object as PY_Object *, and resets.
112  ///
113  /// Using this method requires that the caller includes PY_CPythonAPI.h,
114  /// only call this in a .C file to avoid polluting Python header symbols
115  /// into rest of the codebase.
117  {
118  auto ptr = pyObject();
119  myOpaqueObject = nullptr;
120  return ptr;
121  }
122 
123  /// The comparison operators and equalsOpaqueObject compare using the __eq__
124  /// operator.
125  /// @{
126  bool operator==(const PY_OpaqueObject &opaque_object) const noexcept
127  { return equalsOpaqueObject(opaque_object.myOpaqueObject); }
128  bool operator!=(const PY_OpaqueObject &opaque_object) const noexcept
129  { return !operator==(opaque_object); }
130  bool equalsOpaqueObject(void *opaque_py_object) const noexcept;
131  /// @}
132 
133  /// Return true if *this owns an object (ie. != nullptr)
134  explicit operator bool() const noexcept
135  { return myOpaqueObject != nullptr; }
136 
137  friend bool
138  operator==(const PY_OpaqueObject &opaque_object, std::nullptr_t) noexcept
139  {
140  return opaque_object.myOpaqueObject == nullptr;
141  }
142  friend bool
143  operator==(std::nullptr_t, const PY_OpaqueObject &opaque_object) noexcept
144  {
145  return opaque_object.myOpaqueObject == nullptr;
146  }
147  friend bool
148  operator!=(const PY_OpaqueObject &opaque_object, std::nullptr_t) noexcept
149  {
150  return opaque_object.myOpaqueObject != nullptr;
151  }
152  friend bool
153  operator!=(std::nullptr_t, const PY_OpaqueObject &opaque_object) noexcept
154  {
155  return opaque_object.myOpaqueObject != nullptr;
156  }
157 
158 private:
159  void *myOpaqueObject = nullptr;
160 };
161 
162 #endif
bool operator==(const PY_OpaqueObject &opaque_object) const noexcept
PY_OpaqueObject(PY_OpaqueObject &&opaque_object) noexcept
bool operator!=(const PY_OpaqueObject &opaque_object) const noexcept
friend bool operator!=(const PY_OpaqueObject &opaque_object, std::nullptr_t) noexcept
PY_OpaqueObject() noexcept
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
void * releaseOpaqueObject() noexcept
Releases ownership of the managed object as a void *, and resets.
GLboolean reset
Definition: glad.h:5138
friend bool operator==(const PY_OpaqueObject &opaque_object, std::nullptr_t) noexcept
PY_PyObject * releasePyObject() noexcept
PY_PyObject
#define PY_API
Definition: PY_API.h:10
PY_OpaqueObject & operator=(std::nullptr_t) noexcept
PY_OpaqueObject & operator=(PY_OpaqueObject &&opaque_object) noexcept
PY_OpaqueObject & operator=(const PY_OpaqueObject &opaque_object) noexcept
PY_OpaqueObject(const PY_OpaqueObject &opaque_object) noexcept
PY_OpaqueObject(void *opaque_py_object, bool new_ref=false) noexcept
friend bool operator==(std::nullptr_t, const PY_OpaqueObject &opaque_object) noexcept
friend bool operator!=(std::nullptr_t, const PY_OpaqueObject &opaque_object) noexcept
auto ptr(T p) -> const void *
Definition: format.h:2448
PY_OpaqueObject(std::nullptr_t) noexcept
PY_PyObject * pyObject() const noexcept