netgen-mesher 6.2.2505.post48.dev0__cp313-cp313-win_amd64.whl → 6.2.2506.post48.dev0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- netgen/__init__.pyi +3 -3
- netgen/cmake/NetgenConfig.cmake +9 -8
- netgen/config/__init__.pyi +7 -7
- netgen/config/config.py +6 -6
- netgen/config/config.pyi +7 -7
- netgen/include/core/archive.hpp +18 -3
- netgen/include/core/array.hpp +20 -4
- netgen/include/core/autodiff.hpp +9 -11
- netgen/include/core/autodiffdiff.hpp +0 -2
- netgen/include/core/bitarray.hpp +1 -1
- netgen/include/core/flags.hpp +1 -1
- netgen/include/core/hashtable.hpp +1 -1
- netgen/include/core/memtracer.hpp +7 -7
- netgen/include/core/ngcore.hpp +5 -0
- netgen/include/core/ngcore_api.hpp +11 -0
- netgen/include/core/register_archive.hpp +8 -0
- netgen/include/core/simd_arm64.hpp +100 -5
- netgen/include/core/simd_generic.hpp +187 -6
- netgen/include/core/simd_math.hpp +3 -2
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/table.hpp +2 -2
- netgen/include/core/taskmanager.hpp +34 -1
- netgen/include/include/netgen_version.hpp +3 -3
- netgen/include/meshing/basegeom.hpp +1 -4
- netgen/include/meshing/global.hpp +0 -17
- netgen/include/meshing/hpref_tet.hpp +41 -0
- netgen/include/meshing/hprefinement.hpp +2 -0
- netgen/include/meshing/meshtype.hpp +1 -0
- netgen/include/meshing/msghandler.hpp +9 -6
- netgen/include/meshing/topology.hpp +2 -2
- netgen/include/nginterface.h +3 -2
- netgen/include/occ/occ_utils.hpp +26 -0
- netgen/include/occ/occgeom.hpp +8 -0
- netgen/include/pybind11/attr.h +40 -8
- netgen/include/pybind11/buffer_info.h +14 -14
- netgen/include/pybind11/cast.h +553 -29
- netgen/include/pybind11/chrono.h +4 -1
- netgen/include/pybind11/conduit/README.txt +15 -0
- netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
- netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
- netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
- netgen/include/pybind11/critical_section.h +56 -0
- netgen/include/pybind11/detail/class.h +172 -97
- netgen/include/pybind11/detail/common.h +270 -189
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +55 -0
- netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
- netgen/include/pybind11/detail/exception_translation.h +71 -0
- netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
- netgen/include/pybind11/detail/init.h +113 -9
- netgen/include/pybind11/detail/internals.h +479 -344
- netgen/include/pybind11/detail/native_enum_data.h +209 -0
- netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
- netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
- netgen/include/pybind11/detail/type_caster_base.h +506 -133
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/matrix.h +19 -10
- netgen/include/pybind11/eigen/tensor.h +15 -11
- netgen/include/pybind11/embed.h +50 -46
- netgen/include/pybind11/eval.h +11 -6
- netgen/include/pybind11/functional.h +58 -49
- netgen/include/pybind11/gil.h +34 -82
- netgen/include/pybind11/gil_safe_call_once.h +12 -1
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +272 -93
- netgen/include/pybind11/pybind11.h +947 -265
- netgen/include/pybind11/pytypes.h +127 -21
- netgen/include/pybind11/stl/filesystem.h +23 -25
- netgen/include/pybind11/stl.h +277 -59
- netgen/include/pybind11/stl_bind.h +42 -7
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/typing.h +177 -4
- netgen/include/pybind11/warnings.h +75 -0
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +220 -141
- netgen/libngpy/_csg.pyi +26 -26
- netgen/libngpy/_geom2d.pyi +34 -25
- netgen/libngpy/_meshing.pyi +262 -111
- netgen/libngpy/_stl.pyi +3 -4
- netgen/libngpy.pyd +0 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/read_gmsh.py +41 -0
- netgen/togl.dll +0 -0
- netgen/version.py +1 -1
- netgen/webgui.py +38 -2
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/METADATA +2 -1
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/RECORD +144 -124
- pyngcore/pyngcore.cp313-win_amd64.pyd +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boundarycondition.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boxcyl.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/circle_on_cube.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cone.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cube.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandring.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandspheres.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemcyl.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemsphere.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylinder.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylsphere.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/doc/ng4.pdf +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipsoid.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipticcyl.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/extrusion.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/fichera.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/frame.step +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/hinge.stl +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/lshape3d.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes2.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/matrix.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ortho.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/part1.stl +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/period.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/exportNeutral.py +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/mesh.py +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/shaft.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/revolution.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/screw.step +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sculpture.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shaft.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shell.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphere.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphereincube.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/square.in2d +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarecircle.in2d +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarehole.in2d +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/torus.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/trafo.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twobricks.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocubes.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocyl.geo +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/AUTHORS +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/LICENSE +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/WHEEL +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/entry_points.txt +0 -0
- {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/top_level.txt +0 -0
|
@@ -9,15 +9,24 @@
|
|
|
9
9
|
|
|
10
10
|
#pragma once
|
|
11
11
|
|
|
12
|
-
#include
|
|
12
|
+
#include <pybind11/gil.h>
|
|
13
|
+
#include <pybind11/pytypes.h>
|
|
14
|
+
#include <pybind11/trampoline_self_life_support.h>
|
|
15
|
+
|
|
13
16
|
#include "common.h"
|
|
17
|
+
#include "cpp_conduit.h"
|
|
14
18
|
#include "descr.h"
|
|
19
|
+
#include "dynamic_raw_ptr_cast_if_possible.h"
|
|
15
20
|
#include "internals.h"
|
|
16
21
|
#include "typeid.h"
|
|
22
|
+
#include "using_smart_holder.h"
|
|
23
|
+
#include "value_and_holder.h"
|
|
17
24
|
|
|
18
25
|
#include <cstdint>
|
|
26
|
+
#include <cstring>
|
|
19
27
|
#include <iterator>
|
|
20
28
|
#include <new>
|
|
29
|
+
#include <stdexcept>
|
|
21
30
|
#include <string>
|
|
22
31
|
#include <type_traits>
|
|
23
32
|
#include <typeindex>
|
|
@@ -36,41 +45,21 @@ private:
|
|
|
36
45
|
loader_life_support *parent = nullptr;
|
|
37
46
|
std::unordered_set<PyObject *> keep_alive;
|
|
38
47
|
|
|
39
|
-
#if defined(WITH_THREAD)
|
|
40
|
-
// Store stack pointer in thread-local storage.
|
|
41
|
-
static PYBIND11_TLS_KEY_REF get_stack_tls_key() {
|
|
42
|
-
# if PYBIND11_INTERNALS_VERSION == 4
|
|
43
|
-
return get_local_internals().loader_life_support_tls_key;
|
|
44
|
-
# else
|
|
45
|
-
return get_internals().loader_life_support_tls_key;
|
|
46
|
-
# endif
|
|
47
|
-
}
|
|
48
|
-
static loader_life_support *get_stack_top() {
|
|
49
|
-
return static_cast<loader_life_support *>(PYBIND11_TLS_GET_VALUE(get_stack_tls_key()));
|
|
50
|
-
}
|
|
51
|
-
static void set_stack_top(loader_life_support *value) {
|
|
52
|
-
PYBIND11_TLS_REPLACE_VALUE(get_stack_tls_key(), value);
|
|
53
|
-
}
|
|
54
|
-
#else
|
|
55
|
-
// Use single global variable for stack.
|
|
56
|
-
static loader_life_support **get_stack_pp() {
|
|
57
|
-
static loader_life_support *global_stack = nullptr;
|
|
58
|
-
return global_stack;
|
|
59
|
-
}
|
|
60
|
-
static loader_life_support *get_stack_top() { return *get_stack_pp(); }
|
|
61
|
-
static void set_stack_top(loader_life_support *value) { *get_stack_pp() = value; }
|
|
62
|
-
#endif
|
|
63
|
-
|
|
64
48
|
public:
|
|
65
49
|
/// A new patient frame is created when a function is entered
|
|
66
|
-
loader_life_support()
|
|
50
|
+
loader_life_support() {
|
|
51
|
+
auto &stack_top = get_internals().loader_life_support_tls;
|
|
52
|
+
parent = stack_top.get();
|
|
53
|
+
stack_top = this;
|
|
54
|
+
}
|
|
67
55
|
|
|
68
56
|
/// ... and destroyed after it returns
|
|
69
57
|
~loader_life_support() {
|
|
70
|
-
|
|
58
|
+
auto &stack_top = get_internals().loader_life_support_tls;
|
|
59
|
+
if (stack_top.get() != this) {
|
|
71
60
|
pybind11_fail("loader_life_support: internal error");
|
|
72
61
|
}
|
|
73
|
-
|
|
62
|
+
stack_top = parent;
|
|
74
63
|
for (auto *item : keep_alive) {
|
|
75
64
|
Py_DECREF(item);
|
|
76
65
|
}
|
|
@@ -79,7 +68,7 @@ public:
|
|
|
79
68
|
/// This can only be used inside a pybind11-bound function, either by `argument_loader`
|
|
80
69
|
/// at argument preparation time or by `py::cast()` at execution time.
|
|
81
70
|
PYBIND11_NOINLINE static void add_patient(handle h) {
|
|
82
|
-
loader_life_support *frame =
|
|
71
|
+
loader_life_support *frame = get_internals().loader_life_support_tls.get();
|
|
83
72
|
if (!frame) {
|
|
84
73
|
// NOTE: It would be nice to include the stack frames here, as this indicates
|
|
85
74
|
// use of pybind11::cast<> outside the normal call framework, finding such
|
|
@@ -122,7 +111,6 @@ PYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector<type_
|
|
|
122
111
|
for (handle parent : reinterpret_borrow<tuple>(t->tp_bases)) {
|
|
123
112
|
check.push_back((PyTypeObject *) parent.ptr());
|
|
124
113
|
}
|
|
125
|
-
|
|
126
114
|
auto const &type_dict = get_internals().registered_types_py;
|
|
127
115
|
for (size_t i = 0; i < check.size(); i++) {
|
|
128
116
|
auto *type = check[i];
|
|
@@ -181,13 +169,7 @@ PYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector<type_
|
|
|
181
169
|
* The value is cached for the lifetime of the Python type.
|
|
182
170
|
*/
|
|
183
171
|
inline const std::vector<detail::type_info *> &all_type_info(PyTypeObject *type) {
|
|
184
|
-
|
|
185
|
-
if (ins.second) {
|
|
186
|
-
// New cache entry: populate it
|
|
187
|
-
all_type_info_populate(type, ins.first->second);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return ins.first->second;
|
|
172
|
+
return all_type_info_get_cache(type).first->second;
|
|
191
173
|
}
|
|
192
174
|
|
|
193
175
|
/**
|
|
@@ -217,12 +199,15 @@ inline detail::type_info *get_local_type_info(const std::type_index &tp) {
|
|
|
217
199
|
}
|
|
218
200
|
|
|
219
201
|
inline detail::type_info *get_global_type_info(const std::type_index &tp) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
202
|
+
return with_internals([&](internals &internals) {
|
|
203
|
+
detail::type_info *type_info = nullptr;
|
|
204
|
+
auto &types = internals.registered_types_cpp;
|
|
205
|
+
auto it = types.find(tp);
|
|
206
|
+
if (it != types.end()) {
|
|
207
|
+
type_info = it->second;
|
|
208
|
+
}
|
|
209
|
+
return type_info;
|
|
210
|
+
});
|
|
226
211
|
}
|
|
227
212
|
|
|
228
213
|
/// Return the type info for a given C++ type; on lookup failure can either throw or return
|
|
@@ -250,80 +235,67 @@ PYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if
|
|
|
250
235
|
return handle(type_info ? ((PyObject *) type_info->type) : nullptr);
|
|
251
236
|
}
|
|
252
237
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
238
|
+
inline bool try_incref(PyObject *obj) {
|
|
239
|
+
// Tries to increment the reference count of an object if it's not zero.
|
|
240
|
+
// TODO: Use PyUnstable_TryIncref when available.
|
|
241
|
+
// See https://github.com/python/cpython/issues/128844
|
|
242
|
+
#ifdef Py_GIL_DISABLED
|
|
243
|
+
// See
|
|
244
|
+
// https://github.com/python/cpython/blob/d05140f9f77d7dfc753dd1e5ac3a5962aaa03eff/Include/internal/pycore_object.h#L761
|
|
245
|
+
uint32_t local = _Py_atomic_load_uint32_relaxed(&obj->ob_ref_local);
|
|
246
|
+
local += 1;
|
|
247
|
+
if (local == 0) {
|
|
248
|
+
// immortal
|
|
249
|
+
return true;
|
|
263
250
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
const detail::type_info *type = nullptr;
|
|
271
|
-
void **vh = nullptr;
|
|
272
|
-
|
|
273
|
-
// Main constructor for a found value/holder:
|
|
274
|
-
value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)
|
|
275
|
-
: inst{i}, index{index}, type{type},
|
|
276
|
-
vh{inst->simple_layout ? inst->simple_value_holder
|
|
277
|
-
: &inst->nonsimple.values_and_holders[vpos]} {}
|
|
278
|
-
|
|
279
|
-
// Default constructor (used to signal a value-and-holder not found by get_value_and_holder())
|
|
280
|
-
value_and_holder() = default;
|
|
281
|
-
|
|
282
|
-
// Used for past-the-end iterator
|
|
283
|
-
explicit value_and_holder(size_t index) : index{index} {}
|
|
284
|
-
|
|
285
|
-
template <typename V = void>
|
|
286
|
-
V *&value_ptr() const {
|
|
287
|
-
return reinterpret_cast<V *&>(vh[0]);
|
|
251
|
+
if (_Py_IsOwnedByCurrentThread(obj)) {
|
|
252
|
+
_Py_atomic_store_uint32_relaxed(&obj->ob_ref_local, local);
|
|
253
|
+
# ifdef Py_REF_DEBUG
|
|
254
|
+
_Py_INCREF_IncRefTotal();
|
|
255
|
+
# endif
|
|
256
|
+
return true;
|
|
288
257
|
}
|
|
289
|
-
|
|
290
|
-
|
|
258
|
+
Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&obj->ob_ref_shared);
|
|
259
|
+
for (;;) {
|
|
260
|
+
// If the shared refcount is zero and the object is either merged
|
|
261
|
+
// or may not have weak references, then we cannot incref it.
|
|
262
|
+
if (shared == 0 || shared == _Py_REF_MERGED) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
291
265
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
? inst->simple_holder_constructed
|
|
299
|
-
: (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u;
|
|
300
|
-
}
|
|
301
|
-
// NOLINTNEXTLINE(readability-make-member-function-const)
|
|
302
|
-
void set_holder_constructed(bool v = true) {
|
|
303
|
-
if (inst->simple_layout) {
|
|
304
|
-
inst->simple_holder_constructed = v;
|
|
305
|
-
} else if (v) {
|
|
306
|
-
inst->nonsimple.status[index] |= instance::status_holder_constructed;
|
|
307
|
-
} else {
|
|
308
|
-
inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed;
|
|
266
|
+
if (_Py_atomic_compare_exchange_ssize(
|
|
267
|
+
&obj->ob_ref_shared, &shared, shared + (1 << _Py_REF_SHARED_SHIFT))) {
|
|
268
|
+
# ifdef Py_REF_DEBUG
|
|
269
|
+
_Py_INCREF_IncRefTotal();
|
|
270
|
+
# endif
|
|
271
|
+
return true;
|
|
309
272
|
}
|
|
310
273
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
274
|
+
#else
|
|
275
|
+
assert(Py_REFCNT(obj) > 0);
|
|
276
|
+
Py_INCREF(obj);
|
|
277
|
+
return true;
|
|
278
|
+
#endif
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Searches the inheritance graph for a registered Python instance, using all_type_info().
|
|
282
|
+
PYBIND11_NOINLINE handle find_registered_python_instance(void *src,
|
|
283
|
+
const detail::type_info *tinfo) {
|
|
284
|
+
return with_instance_map(src, [&](instance_map &instances) {
|
|
285
|
+
auto it_instances = instances.equal_range(src);
|
|
286
|
+
for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {
|
|
287
|
+
for (auto *instance_type : detail::all_type_info(Py_TYPE(it_i->second))) {
|
|
288
|
+
if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) {
|
|
289
|
+
auto *wrapper = reinterpret_cast<PyObject *>(it_i->second);
|
|
290
|
+
if (try_incref(wrapper)) {
|
|
291
|
+
return handle(wrapper);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
324
295
|
}
|
|
325
|
-
|
|
326
|
-
};
|
|
296
|
+
return handle();
|
|
297
|
+
});
|
|
298
|
+
}
|
|
327
299
|
|
|
328
300
|
// Container for accessing and iterating over an instance's values/holders
|
|
329
301
|
struct values_and_holders {
|
|
@@ -493,7 +465,7 @@ PYBIND11_NOINLINE void instance::allocate_layout() {
|
|
|
493
465
|
// NOLINTNEXTLINE(readability-make-member-function-const)
|
|
494
466
|
PYBIND11_NOINLINE void instance::deallocate_layout() {
|
|
495
467
|
if (!simple_layout) {
|
|
496
|
-
PyMem_Free(nonsimple.values_and_holders);
|
|
468
|
+
PyMem_Free(reinterpret_cast<void *>(nonsimple.values_and_holders));
|
|
497
469
|
}
|
|
498
470
|
}
|
|
499
471
|
|
|
@@ -506,32 +478,387 @@ PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp)
|
|
|
506
478
|
}
|
|
507
479
|
|
|
508
480
|
PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
481
|
+
return with_instance_map(ptr, [&](instance_map &instances) {
|
|
482
|
+
auto range = instances.equal_range(ptr);
|
|
483
|
+
for (auto it = range.first; it != range.second; ++it) {
|
|
484
|
+
for (const auto &vh : values_and_holders(it->second)) {
|
|
485
|
+
if (vh.type == type) {
|
|
486
|
+
return handle((PyObject *) it->second);
|
|
487
|
+
}
|
|
515
488
|
}
|
|
516
489
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
inline PyThreadState *get_thread_state_unchecked() {
|
|
522
|
-
#if defined(PYPY_VERSION)
|
|
523
|
-
return PyThreadState_GET();
|
|
524
|
-
#elif PY_VERSION_HEX < 0x030D0000
|
|
525
|
-
return _PyThreadState_UncheckedGet();
|
|
526
|
-
#else
|
|
527
|
-
return PyThreadState_GetUnchecked();
|
|
528
|
-
#endif
|
|
490
|
+
return handle();
|
|
491
|
+
});
|
|
529
492
|
}
|
|
530
493
|
|
|
531
494
|
// Forward declarations
|
|
532
495
|
void keep_alive_impl(handle nurse, handle patient);
|
|
533
496
|
inline PyObject *make_new_instance(PyTypeObject *type);
|
|
534
497
|
|
|
498
|
+
PYBIND11_WARNING_PUSH
|
|
499
|
+
PYBIND11_WARNING_DISABLE_GCC("-Wredundant-decls")
|
|
500
|
+
|
|
501
|
+
// PYBIND11:REMINDER: Needs refactoring of existing pybind11 code.
|
|
502
|
+
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo);
|
|
503
|
+
|
|
504
|
+
PYBIND11_WARNING_POP
|
|
505
|
+
|
|
506
|
+
PYBIND11_NAMESPACE_BEGIN(smart_holder_type_caster_support)
|
|
507
|
+
|
|
508
|
+
struct value_and_holder_helper {
|
|
509
|
+
value_and_holder loaded_v_h;
|
|
510
|
+
|
|
511
|
+
bool have_holder() const {
|
|
512
|
+
return loaded_v_h.vh != nullptr && loaded_v_h.holder_constructed();
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
smart_holder &holder() const { return loaded_v_h.holder<smart_holder>(); }
|
|
516
|
+
|
|
517
|
+
void throw_if_uninitialized_or_disowned_holder(const char *typeid_name) const {
|
|
518
|
+
static const std::string missing_value_msg = "Missing value for wrapped C++ type `";
|
|
519
|
+
if (!holder().is_populated) {
|
|
520
|
+
throw value_error(missing_value_msg + clean_type_id(typeid_name)
|
|
521
|
+
+ "`: Python instance is uninitialized.");
|
|
522
|
+
}
|
|
523
|
+
if (!holder().has_pointee()) {
|
|
524
|
+
throw value_error(missing_value_msg + clean_type_id(typeid_name)
|
|
525
|
+
+ "`: Python instance was disowned.");
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
void throw_if_uninitialized_or_disowned_holder(const std::type_info &type_info) const {
|
|
530
|
+
throw_if_uninitialized_or_disowned_holder(type_info.name());
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// have_holder() must be true or this function will fail.
|
|
534
|
+
void throw_if_instance_is_currently_owned_by_shared_ptr(const type_info *tinfo) const {
|
|
535
|
+
auto *vptr_gd_ptr = tinfo->get_memory_guarded_delete(holder().vptr);
|
|
536
|
+
if (vptr_gd_ptr != nullptr && !vptr_gd_ptr->released_ptr.expired()) {
|
|
537
|
+
throw value_error("Python instance is currently owned by a std::shared_ptr.");
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
void *get_void_ptr_or_nullptr() const {
|
|
542
|
+
if (have_holder()) {
|
|
543
|
+
auto &hld = holder();
|
|
544
|
+
if (hld.is_populated && hld.has_pointee()) {
|
|
545
|
+
return hld.template as_raw_ptr_unowned<void>();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return nullptr;
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
template <typename T, typename D>
|
|
553
|
+
handle smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&src,
|
|
554
|
+
return_value_policy policy,
|
|
555
|
+
handle parent,
|
|
556
|
+
const std::pair<const void *, const type_info *> &st) {
|
|
557
|
+
if (policy == return_value_policy::copy) {
|
|
558
|
+
throw cast_error("return_value_policy::copy is invalid for unique_ptr.");
|
|
559
|
+
}
|
|
560
|
+
if (!src) {
|
|
561
|
+
return none().release();
|
|
562
|
+
}
|
|
563
|
+
void *src_raw_void_ptr = const_cast<void *>(st.first);
|
|
564
|
+
assert(st.second != nullptr);
|
|
565
|
+
const detail::type_info *tinfo = st.second;
|
|
566
|
+
if (handle existing_inst = find_registered_python_instance(src_raw_void_ptr, tinfo)) {
|
|
567
|
+
auto *self_life_support = tinfo->get_trampoline_self_life_support(src.get());
|
|
568
|
+
if (self_life_support != nullptr) {
|
|
569
|
+
value_and_holder &v_h = self_life_support->v_h;
|
|
570
|
+
if (v_h.inst != nullptr && v_h.vh != nullptr) {
|
|
571
|
+
auto &holder = v_h.holder<smart_holder>();
|
|
572
|
+
if (!holder.is_disowned) {
|
|
573
|
+
pybind11_fail("smart_holder_from_unique_ptr: unexpected "
|
|
574
|
+
"smart_holder.is_disowned failure.");
|
|
575
|
+
}
|
|
576
|
+
// Critical transfer-of-ownership section. This must stay together.
|
|
577
|
+
self_life_support->deactivate_life_support();
|
|
578
|
+
holder.reclaim_disowned(tinfo->get_memory_guarded_delete);
|
|
579
|
+
(void) src.release();
|
|
580
|
+
// Critical section end.
|
|
581
|
+
return existing_inst;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
throw cast_error("Invalid unique_ptr: another instance owns this pointer already.");
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
auto inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
|
|
588
|
+
auto *inst_raw_ptr = reinterpret_cast<instance *>(inst.ptr());
|
|
589
|
+
inst_raw_ptr->owned = true;
|
|
590
|
+
void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr();
|
|
591
|
+
valueptr = src_raw_void_ptr;
|
|
592
|
+
|
|
593
|
+
if (static_cast<void *>(src.get()) == src_raw_void_ptr) {
|
|
594
|
+
// This is a multiple-inheritance situation that is incompatible with the current
|
|
595
|
+
// shared_from_this handling (see PR #3023). Is there a better solution?
|
|
596
|
+
src_raw_void_ptr = nullptr;
|
|
597
|
+
}
|
|
598
|
+
auto smhldr = smart_holder::from_unique_ptr(std::move(src), src_raw_void_ptr);
|
|
599
|
+
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
|
600
|
+
|
|
601
|
+
if (policy == return_value_policy::reference_internal) {
|
|
602
|
+
keep_alive_impl(inst, parent);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
return inst.release();
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
template <typename T, typename D>
|
|
609
|
+
handle smart_holder_from_unique_ptr(std::unique_ptr<T const, D> &&src,
|
|
610
|
+
return_value_policy policy,
|
|
611
|
+
handle parent,
|
|
612
|
+
const std::pair<const void *, const type_info *> &st) {
|
|
613
|
+
return smart_holder_from_unique_ptr(
|
|
614
|
+
std::unique_ptr<T, D>(const_cast<T *>(src.release()),
|
|
615
|
+
std::move(src.get_deleter())), // Const2Mutbl
|
|
616
|
+
policy,
|
|
617
|
+
parent,
|
|
618
|
+
st);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
template <typename T>
|
|
622
|
+
handle smart_holder_from_shared_ptr(const std::shared_ptr<T> &src,
|
|
623
|
+
return_value_policy policy,
|
|
624
|
+
handle parent,
|
|
625
|
+
const std::pair<const void *, const type_info *> &st) {
|
|
626
|
+
switch (policy) {
|
|
627
|
+
case return_value_policy::automatic:
|
|
628
|
+
case return_value_policy::automatic_reference:
|
|
629
|
+
break;
|
|
630
|
+
case return_value_policy::take_ownership:
|
|
631
|
+
throw cast_error("Invalid return_value_policy for shared_ptr (take_ownership).");
|
|
632
|
+
case return_value_policy::copy:
|
|
633
|
+
case return_value_policy::move:
|
|
634
|
+
break;
|
|
635
|
+
case return_value_policy::reference:
|
|
636
|
+
throw cast_error("Invalid return_value_policy for shared_ptr (reference).");
|
|
637
|
+
case return_value_policy::reference_internal:
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
if (!src) {
|
|
641
|
+
return none().release();
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
auto src_raw_ptr = src.get();
|
|
645
|
+
assert(st.second != nullptr);
|
|
646
|
+
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
|
|
647
|
+
const detail::type_info *tinfo = st.second;
|
|
648
|
+
if (handle existing_inst = find_registered_python_instance(src_raw_void_ptr, tinfo)) {
|
|
649
|
+
// PYBIND11:REMINDER: MISSING: Enforcement of consistency with existing smart_holder.
|
|
650
|
+
// PYBIND11:REMINDER: MISSING: keep_alive.
|
|
651
|
+
return existing_inst;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
auto inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
|
|
655
|
+
auto *inst_raw_ptr = reinterpret_cast<instance *>(inst.ptr());
|
|
656
|
+
inst_raw_ptr->owned = true;
|
|
657
|
+
void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr();
|
|
658
|
+
valueptr = src_raw_void_ptr;
|
|
659
|
+
|
|
660
|
+
auto smhldr
|
|
661
|
+
= smart_holder::from_shared_ptr(std::shared_ptr<void>(src, const_cast<void *>(st.first)));
|
|
662
|
+
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
|
663
|
+
|
|
664
|
+
if (policy == return_value_policy::reference_internal) {
|
|
665
|
+
keep_alive_impl(inst, parent);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
return inst.release();
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
template <typename T>
|
|
672
|
+
handle smart_holder_from_shared_ptr(const std::shared_ptr<T const> &src,
|
|
673
|
+
return_value_policy policy,
|
|
674
|
+
handle parent,
|
|
675
|
+
const std::pair<const void *, const type_info *> &st) {
|
|
676
|
+
return smart_holder_from_shared_ptr(std::const_pointer_cast<T>(src), // Const2Mutbl
|
|
677
|
+
policy,
|
|
678
|
+
parent,
|
|
679
|
+
st);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
struct shared_ptr_parent_life_support {
|
|
683
|
+
PyObject *parent;
|
|
684
|
+
explicit shared_ptr_parent_life_support(PyObject *parent) : parent{parent} {
|
|
685
|
+
Py_INCREF(parent);
|
|
686
|
+
}
|
|
687
|
+
// NOLINTNEXTLINE(readability-make-member-function-const)
|
|
688
|
+
void operator()(void *) {
|
|
689
|
+
gil_scoped_acquire gil;
|
|
690
|
+
Py_DECREF(parent);
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
struct shared_ptr_trampoline_self_life_support {
|
|
695
|
+
PyObject *self;
|
|
696
|
+
explicit shared_ptr_trampoline_self_life_support(instance *inst)
|
|
697
|
+
: self{reinterpret_cast<PyObject *>(inst)} {
|
|
698
|
+
gil_scoped_acquire gil;
|
|
699
|
+
Py_INCREF(self);
|
|
700
|
+
}
|
|
701
|
+
// NOLINTNEXTLINE(readability-make-member-function-const)
|
|
702
|
+
void operator()(void *) {
|
|
703
|
+
gil_scoped_acquire gil;
|
|
704
|
+
Py_DECREF(self);
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
template <typename T,
|
|
709
|
+
typename D,
|
|
710
|
+
typename std::enable_if<std::is_default_constructible<D>::value, int>::type = 0>
|
|
711
|
+
inline std::unique_ptr<T, D> unique_with_deleter(T *raw_ptr, std::unique_ptr<D> &&deleter) {
|
|
712
|
+
if (deleter == nullptr) {
|
|
713
|
+
return std::unique_ptr<T, D>(raw_ptr);
|
|
714
|
+
}
|
|
715
|
+
return std::unique_ptr<T, D>(raw_ptr, std::move(*deleter));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
template <typename T,
|
|
719
|
+
typename D,
|
|
720
|
+
typename std::enable_if<!std::is_default_constructible<D>::value, int>::type = 0>
|
|
721
|
+
inline std::unique_ptr<T, D> unique_with_deleter(T *raw_ptr, std::unique_ptr<D> &&deleter) {
|
|
722
|
+
if (deleter == nullptr) {
|
|
723
|
+
pybind11_fail("smart_holder_type_casters: deleter is not default constructible and no"
|
|
724
|
+
" instance available to return.");
|
|
725
|
+
}
|
|
726
|
+
return std::unique_ptr<T, D>(raw_ptr, std::move(*deleter));
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
template <typename T>
|
|
730
|
+
struct load_helper : value_and_holder_helper {
|
|
731
|
+
bool was_populated = false;
|
|
732
|
+
bool python_instance_is_alias = false;
|
|
733
|
+
|
|
734
|
+
void maybe_set_python_instance_is_alias(handle src) {
|
|
735
|
+
if (was_populated) {
|
|
736
|
+
python_instance_is_alias = reinterpret_cast<instance *>(src.ptr())->is_alias;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
static std::shared_ptr<T> make_shared_ptr_with_responsible_parent(T *raw_ptr, handle parent) {
|
|
741
|
+
return std::shared_ptr<T>(raw_ptr, shared_ptr_parent_life_support(parent.ptr()));
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
std::shared_ptr<T> load_as_shared_ptr(const type_info *tinfo,
|
|
745
|
+
void *void_raw_ptr,
|
|
746
|
+
handle responsible_parent = nullptr,
|
|
747
|
+
// to support py::potentially_slicing_weak_ptr
|
|
748
|
+
// with minimal added code complexity:
|
|
749
|
+
bool force_potentially_slicing_shared_ptr
|
|
750
|
+
= false) const {
|
|
751
|
+
if (!have_holder()) {
|
|
752
|
+
return nullptr;
|
|
753
|
+
}
|
|
754
|
+
throw_if_uninitialized_or_disowned_holder(typeid(T));
|
|
755
|
+
smart_holder &hld = holder();
|
|
756
|
+
hld.ensure_is_not_disowned("load_as_shared_ptr");
|
|
757
|
+
if (hld.vptr_is_using_noop_deleter) {
|
|
758
|
+
if (responsible_parent) {
|
|
759
|
+
return make_shared_ptr_with_responsible_parent(static_cast<T *>(void_raw_ptr),
|
|
760
|
+
responsible_parent);
|
|
761
|
+
}
|
|
762
|
+
throw std::runtime_error("Non-owning holder (load_as_shared_ptr).");
|
|
763
|
+
}
|
|
764
|
+
auto *type_raw_ptr = static_cast<T *>(void_raw_ptr);
|
|
765
|
+
if (python_instance_is_alias && !force_potentially_slicing_shared_ptr) {
|
|
766
|
+
auto *vptr_gd_ptr = tinfo->get_memory_guarded_delete(holder().vptr);
|
|
767
|
+
if (vptr_gd_ptr != nullptr) {
|
|
768
|
+
std::shared_ptr<void> released_ptr = vptr_gd_ptr->released_ptr.lock();
|
|
769
|
+
if (released_ptr) {
|
|
770
|
+
return std::shared_ptr<T>(released_ptr, type_raw_ptr);
|
|
771
|
+
}
|
|
772
|
+
std::shared_ptr<T> to_be_released(
|
|
773
|
+
type_raw_ptr, shared_ptr_trampoline_self_life_support(loaded_v_h.inst));
|
|
774
|
+
vptr_gd_ptr->released_ptr = to_be_released;
|
|
775
|
+
return to_be_released;
|
|
776
|
+
}
|
|
777
|
+
auto *sptsls_ptr = std::get_deleter<shared_ptr_trampoline_self_life_support>(hld.vptr);
|
|
778
|
+
if (sptsls_ptr != nullptr) {
|
|
779
|
+
// This code is reachable only if there are multiple registered_instances for the
|
|
780
|
+
// same pointee.
|
|
781
|
+
if (reinterpret_cast<PyObject *>(loaded_v_h.inst) == sptsls_ptr->self) {
|
|
782
|
+
pybind11_fail("smart_holder_type_caster_support load_as_shared_ptr failure: "
|
|
783
|
+
"loaded_v_h.inst == sptsls_ptr->self");
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (sptsls_ptr != nullptr || !memory::type_has_shared_from_this(type_raw_ptr)) {
|
|
787
|
+
return std::shared_ptr<T>(
|
|
788
|
+
type_raw_ptr, shared_ptr_trampoline_self_life_support(loaded_v_h.inst));
|
|
789
|
+
}
|
|
790
|
+
if (hld.vptr_is_external_shared_ptr) {
|
|
791
|
+
pybind11_fail("smart_holder_type_casters load_as_shared_ptr failure: not "
|
|
792
|
+
"implemented: trampoline-self-life-support for external shared_ptr "
|
|
793
|
+
"to type inheriting from std::enable_shared_from_this.");
|
|
794
|
+
}
|
|
795
|
+
pybind11_fail(
|
|
796
|
+
"smart_holder_type_casters: load_as_shared_ptr failure: internal inconsistency.");
|
|
797
|
+
}
|
|
798
|
+
std::shared_ptr<void> void_shd_ptr = hld.template as_shared_ptr<void>();
|
|
799
|
+
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
template <typename D>
|
|
803
|
+
std::unique_ptr<T, D> load_as_unique_ptr(const type_info *tinfo,
|
|
804
|
+
void *raw_void_ptr,
|
|
805
|
+
const char *context = "load_as_unique_ptr") {
|
|
806
|
+
if (!have_holder()) {
|
|
807
|
+
return unique_with_deleter<T, D>(nullptr, std::unique_ptr<D>());
|
|
808
|
+
}
|
|
809
|
+
throw_if_uninitialized_or_disowned_holder(typeid(T));
|
|
810
|
+
throw_if_instance_is_currently_owned_by_shared_ptr(tinfo);
|
|
811
|
+
holder().ensure_is_not_disowned(context);
|
|
812
|
+
holder().template ensure_compatible_uqp_del<T, D>(context);
|
|
813
|
+
holder().ensure_use_count_1(context);
|
|
814
|
+
|
|
815
|
+
T *raw_type_ptr = static_cast<T *>(raw_void_ptr);
|
|
816
|
+
|
|
817
|
+
auto *self_life_support = tinfo->get_trampoline_self_life_support(raw_type_ptr);
|
|
818
|
+
// This is enforced indirectly by a static_assert in the class_ implementation:
|
|
819
|
+
assert(!python_instance_is_alias || self_life_support);
|
|
820
|
+
|
|
821
|
+
std::unique_ptr<D> extracted_deleter
|
|
822
|
+
= holder().template extract_deleter<T, D>(context, tinfo->get_memory_guarded_delete);
|
|
823
|
+
|
|
824
|
+
// Critical transfer-of-ownership section. This must stay together.
|
|
825
|
+
if (self_life_support != nullptr) {
|
|
826
|
+
holder().disown(tinfo->get_memory_guarded_delete);
|
|
827
|
+
} else {
|
|
828
|
+
holder().release_ownership(tinfo->get_memory_guarded_delete);
|
|
829
|
+
}
|
|
830
|
+
auto result = unique_with_deleter<T, D>(raw_type_ptr, std::move(extracted_deleter));
|
|
831
|
+
if (self_life_support != nullptr) {
|
|
832
|
+
self_life_support->activate_life_support(loaded_v_h);
|
|
833
|
+
} else {
|
|
834
|
+
void *value_void_ptr = loaded_v_h.value_ptr();
|
|
835
|
+
loaded_v_h.value_ptr() = nullptr;
|
|
836
|
+
deregister_instance(loaded_v_h.inst, value_void_ptr, loaded_v_h.type);
|
|
837
|
+
}
|
|
838
|
+
// Critical section end.
|
|
839
|
+
|
|
840
|
+
return result;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
// This assumes load_as_shared_ptr succeeded(), and the returned shared_ptr is still alive.
|
|
844
|
+
// The returned unique_ptr is meant to never expire (the behavior is undefined otherwise).
|
|
845
|
+
template <typename D>
|
|
846
|
+
std::unique_ptr<T, D> load_as_const_unique_ptr(const type_info *tinfo,
|
|
847
|
+
T *raw_type_ptr,
|
|
848
|
+
const char *context
|
|
849
|
+
= "load_as_const_unique_ptr") {
|
|
850
|
+
if (!have_holder()) {
|
|
851
|
+
return unique_with_deleter<T, D>(nullptr, std::unique_ptr<D>());
|
|
852
|
+
}
|
|
853
|
+
holder().template ensure_compatible_uqp_del<T, D>(context);
|
|
854
|
+
return unique_with_deleter<T, D>(raw_type_ptr,
|
|
855
|
+
std::move(holder().template extract_deleter<T, D>(
|
|
856
|
+
context, tinfo->get_memory_guarded_delete)));
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
PYBIND11_NAMESPACE_END(smart_holder_type_caster_support)
|
|
861
|
+
|
|
535
862
|
class type_caster_generic {
|
|
536
863
|
public:
|
|
537
864
|
PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info)
|
|
@@ -636,6 +963,15 @@ public:
|
|
|
636
963
|
|
|
637
964
|
// Base methods for generic caster; there are overridden in copyable_holder_caster
|
|
638
965
|
void load_value(value_and_holder &&v_h) {
|
|
966
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
967
|
+
smart_holder_type_caster_support::value_and_holder_helper v_h_helper;
|
|
968
|
+
v_h_helper.loaded_v_h = v_h;
|
|
969
|
+
if (v_h_helper.have_holder()) {
|
|
970
|
+
v_h_helper.throw_if_uninitialized_or_disowned_holder(cpptype->name());
|
|
971
|
+
value = v_h_helper.holder().template as_raw_ptr_unowned<void>();
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
639
975
|
auto *&vptr = v_h.value_ptr();
|
|
640
976
|
// Lazy allocation for unallocated values:
|
|
641
977
|
if (vptr == nullptr) {
|
|
@@ -674,6 +1010,13 @@ public:
|
|
|
674
1010
|
}
|
|
675
1011
|
return false;
|
|
676
1012
|
}
|
|
1013
|
+
bool try_cpp_conduit(handle src) {
|
|
1014
|
+
value = try_raw_pointer_ephemeral_from_cpp_conduit(src, cpptype);
|
|
1015
|
+
if (value != nullptr) {
|
|
1016
|
+
return true;
|
|
1017
|
+
}
|
|
1018
|
+
return false;
|
|
1019
|
+
}
|
|
677
1020
|
void check_holder_compat() {}
|
|
678
1021
|
|
|
679
1022
|
PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) {
|
|
@@ -805,6 +1148,10 @@ public:
|
|
|
805
1148
|
return true;
|
|
806
1149
|
}
|
|
807
1150
|
|
|
1151
|
+
if (convert && cpptype && this_.try_cpp_conduit(src)) {
|
|
1152
|
+
return true;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
808
1155
|
return false;
|
|
809
1156
|
}
|
|
810
1157
|
|
|
@@ -832,6 +1179,32 @@ public:
|
|
|
832
1179
|
void *value = nullptr;
|
|
833
1180
|
};
|
|
834
1181
|
|
|
1182
|
+
inline object cpp_conduit_method(handle self,
|
|
1183
|
+
const bytes &pybind11_platform_abi_id,
|
|
1184
|
+
const capsule &cpp_type_info_capsule,
|
|
1185
|
+
const bytes &pointer_kind) {
|
|
1186
|
+
#ifdef PYBIND11_HAS_STRING_VIEW
|
|
1187
|
+
using cpp_str = std::string_view;
|
|
1188
|
+
#else
|
|
1189
|
+
using cpp_str = std::string;
|
|
1190
|
+
#endif
|
|
1191
|
+
if (cpp_str(pybind11_platform_abi_id) != PYBIND11_PLATFORM_ABI_ID) {
|
|
1192
|
+
return none();
|
|
1193
|
+
}
|
|
1194
|
+
if (std::strcmp(cpp_type_info_capsule.name(), typeid(std::type_info).name()) != 0) {
|
|
1195
|
+
return none();
|
|
1196
|
+
}
|
|
1197
|
+
if (cpp_str(pointer_kind) != "raw_pointer_ephemeral") {
|
|
1198
|
+
throw std::runtime_error("Invalid pointer_kind: \"" + std::string(pointer_kind) + "\"");
|
|
1199
|
+
}
|
|
1200
|
+
const auto *cpp_type_info = cpp_type_info_capsule.get_pointer<const std::type_info>();
|
|
1201
|
+
type_caster_generic caster(*cpp_type_info);
|
|
1202
|
+
if (!caster.load(self, false)) {
|
|
1203
|
+
return none();
|
|
1204
|
+
}
|
|
1205
|
+
return capsule(caster.value, cpp_type_info->name());
|
|
1206
|
+
}
|
|
1207
|
+
|
|
835
1208
|
/**
|
|
836
1209
|
* Determine suitable casting operator for pointer-or-lvalue-casting type casters. The type caster
|
|
837
1210
|
* needs to provide `operator T*()` and `operator T&()` operators.
|
|
@@ -1111,11 +1484,11 @@ public:
|
|
|
1111
1484
|
|| policy == return_value_policy::automatic_reference) {
|
|
1112
1485
|
policy = return_value_policy::copy;
|
|
1113
1486
|
}
|
|
1114
|
-
return cast(
|
|
1487
|
+
return cast(std::addressof(src), policy, parent);
|
|
1115
1488
|
}
|
|
1116
1489
|
|
|
1117
1490
|
static handle cast(itype &&src, return_value_policy, handle parent) {
|
|
1118
|
-
return cast(
|
|
1491
|
+
return cast(std::addressof(src), return_value_policy::move, parent);
|
|
1119
1492
|
}
|
|
1120
1493
|
|
|
1121
1494
|
// Returns a (pointer, type_info) pair taking care of necessary type lookup for a
|