autodecref.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright (C) 2016 The Qt Company Ltd.
  2. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
  3. #ifndef AUTODECREF_H
  4. #define AUTODECREF_H
  5. #include "sbkpython.h"
  6. #include <utility>
  7. struct SbkObject;
  8. namespace Shiboken
  9. {
  10. /**
  11. * AutoDecRef holds a PyObject pointer and decrement its reference counter when destroyed.
  12. */
  13. struct AutoDecRef
  14. {
  15. public:
  16. AutoDecRef(const AutoDecRef &) = delete;
  17. AutoDecRef(AutoDecRef &&o) noexcept : m_pyObj{std::exchange(o.m_pyObj, nullptr)} {}
  18. AutoDecRef &operator=(const AutoDecRef &) = delete;
  19. AutoDecRef &operator=(AutoDecRef &&o) noexcept
  20. {
  21. m_pyObj = std::exchange(o.m_pyObj, nullptr);
  22. return *this;
  23. }
  24. /// AutoDecRef constructor.
  25. /// \param pyobj A borrowed reference to a Python object
  26. explicit AutoDecRef(PyObject *pyObj) noexcept : m_pyObj(pyObj) {}
  27. /// AutoDecRef constructor.
  28. /// \param pyobj A borrowed reference to a wrapped Python object
  29. explicit AutoDecRef(SbkObject *pyObj) noexcept : m_pyObj(reinterpret_cast<PyObject *>(pyObj)) {}
  30. /// AutoDecref default constructor.
  31. /// To be used later with reset():
  32. AutoDecRef() noexcept = default;
  33. /// Decref the borrowed python reference
  34. ~AutoDecRef()
  35. {
  36. Py_XDECREF(m_pyObj);
  37. }
  38. [[nodiscard]] bool isNull() const { return m_pyObj == nullptr; }
  39. /// Returns the pointer of the Python object being held.
  40. [[nodiscard]] PyObject *object() const { return m_pyObj; }
  41. [[nodiscard]] operator PyObject *() const { return m_pyObj; }
  42. operator bool() const { return m_pyObj != nullptr; }
  43. PyObject *operator->() { return m_pyObj; }
  44. template<typename T>
  45. [[deprecated]] T cast()
  46. {
  47. return reinterpret_cast<T>(m_pyObj);
  48. }
  49. /**
  50. * Decref the current borrowed python reference and borrow \p other.
  51. */
  52. void reset(PyObject *other)
  53. {
  54. // Safely decref m_pyObj. See Py_XSETREF in object.h .
  55. PyObject *_py_tmp = m_pyObj;
  56. m_pyObj = other;
  57. Py_XDECREF(_py_tmp);
  58. }
  59. PyObject *release()
  60. {
  61. PyObject *result = m_pyObj;
  62. m_pyObj = nullptr;
  63. return result;
  64. }
  65. private:
  66. PyObject *m_pyObj = nullptr;
  67. };
  68. } // namespace Shiboken
  69. #endif // AUTODECREF_H