LSST Applications g04e9c324dd+8c5ae1fdc5,g123d84c11c+8c5ae1fdc5,g1ec0fe41b4+6ec6b74de1,g1fd858c14a+3332b7fd5e,g29a0cc5914+63e6b38501,g32513d92db+32ea961568,g35bb328faa+8c5ae1fdc5,g46874a5070+b0fbcfa072,g4d44eb3520+57cbe129f8,g53246c7159+8c5ae1fdc5,g5c55814f68+d821c87bfa,g60b5630c4e+b0fbcfa072,g663da51e9b+005a425d83,g67b6fd64d1+d4e0e85a95,g67fd3c3899+b0fbcfa072,g71d780ea3c+e1dc163c68,g78460c75b0+7e33a9eb6d,g786e29fd12+668abc6043,g844c57033c+929b3e9e34,g851e132a97+e172830085,g8852436030+a7ec7e5967,g89139ef638+d4e0e85a95,g8d7436a09f+38661d0626,g989de1cb63+d4e0e85a95,g9f33ca652e+23636040bc,ga1e959baac+5fbc491aed,ga2f891cd6c+b0fbcfa072,gabe3b4be73+8856018cbb,gabf8522325+cc757f8247,gac2eed3f23+d4e0e85a95,gb1101e3267+68a34dc4ce,gb89ab40317+d4e0e85a95,gcf25f946ba+a7ec7e5967,gd107969129+28621171e6,gd6cbbdb0b4+8e46defd2a,ge410e46f29+d4e0e85a95,geaed405ab2+2322f1d6ea,gf5e32f922b+8c5ae1fdc5,w.2025.31
LSST Data Management Base Package
Loading...
Searching...
No Matches
PySharedPtr.h
Go to the documentation of this file.
1// -*- lsst-c++ -*-
2/*
3 * LSST Data Management System
4 * See COPYRIGHT file at the top of the source tree.
5 *
6 * This product includes software developed by the
7 * LSST Project (http://www.lsst.org/).
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the LSST License Statement and
20 * the GNU General Public License along with this program. If not,
21 * see <http://www.lsstcorp.org/LegalNotices/>.
22 */
23
24#ifndef LSST_CPPUTILS_PYTHON_PYSHAREDPTR_H
25#define LSST_CPPUTILS_PYTHON_PYSHAREDPTR_H
26
27#include "pybind11/pybind11.h"
28
29#include <memory>
30
31namespace lsst {
32namespace cpputils {
33namespace python {
34
35/* Workaround for C++ objects outliving Python objects
36 * by Xfel and florianwechsung, https://github.com/pybind/pybind11/issues/1389
37 */
48template <typename T>
49class PySharedPtr final {
50public:
51 using element_type = T;
52
59 explicit PySharedPtr(T* const ptr) : _impl() {
60 if (ptr != nullptr) {
61 // `cast` returns new PyObject only if `*ptr` not yet associated with one
62 PyObject* pyObj = pybind11::cast(ptr).ptr();
63 Py_INCREF(pyObj);
64 // if any operation with shared_ptr fails, pyObj will get decremented correctly
65 std::shared_ptr<PyObject> manager(pyObj, [](PyObject* const obj) noexcept {
66 if (obj != nullptr) Py_DECREF(obj);
67 });
68 _impl = std::shared_ptr<T>(manager, ptr);
69 }
70 }
71
72 PySharedPtr(PySharedPtr const&) noexcept = default;
73 PySharedPtr(PySharedPtr&&) noexcept = default;
74 PySharedPtr& operator=(PySharedPtr const&) noexcept = default;
75 PySharedPtr& operator=(PySharedPtr&&) noexcept = default;
76 ~PySharedPtr() noexcept = default;
77
78 PySharedPtr(std::shared_ptr<T> r) noexcept : _impl(std::move(r)) {}
79 operator std::shared_ptr<T>() noexcept { return _impl; }
80
81 T* get() const noexcept { return _impl.get(); }
82
83private:
85};
86
87} // namespace python
88} // namespace cpputils
89} // namespace lsst
90
91// Macro must be called in the global namespace
93
94#endif
PYBIND11_DECLARE_HOLDER_TYPE(T, lsst::cpputils::python::PySharedPtr< T >)
A shared pointer that tracks both a C++ object and its associated PyObject.
Definition PySharedPtr.h:49
PySharedPtr(PySharedPtr &&) noexcept=default
PySharedPtr(T *const ptr)
Create a pointer that counts as an extra reference in the Python environment.
Definition PySharedPtr.h:59
PySharedPtr(PySharedPtr const &) noexcept=default
STL namespace.