netgen-mesher 6.2.2504.post11.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.
Files changed (153) hide show
  1. netgen/__init__.pyi +3 -3
  2. netgen/cmake/NetgenConfig.cmake +10 -9
  3. netgen/config/__init__.pyi +8 -8
  4. netgen/config/config.py +7 -7
  5. netgen/config/config.pyi +8 -8
  6. netgen/include/core/archive.hpp +18 -3
  7. netgen/include/core/array.hpp +20 -4
  8. netgen/include/core/autodiff.hpp +9 -11
  9. netgen/include/core/autodiffdiff.hpp +0 -2
  10. netgen/include/core/bitarray.hpp +1 -1
  11. netgen/include/core/flags.hpp +1 -1
  12. netgen/include/core/hashtable.hpp +1 -1
  13. netgen/include/core/memtracer.hpp +7 -7
  14. netgen/include/core/ngcore.hpp +5 -0
  15. netgen/include/core/ngcore_api.hpp +11 -0
  16. netgen/include/core/paje_trace.hpp +9 -8
  17. netgen/include/core/profiler.hpp +5 -5
  18. netgen/include/core/register_archive.hpp +8 -0
  19. netgen/include/core/simd.hpp +69 -1
  20. netgen/include/core/simd_arm64.hpp +205 -1
  21. netgen/include/core/simd_avx.hpp +72 -4
  22. netgen/include/core/simd_avx512.hpp +9 -0
  23. netgen/include/core/simd_generic.hpp +274 -8
  24. netgen/include/core/simd_math.hpp +178 -0
  25. netgen/include/core/simd_sse.hpp +11 -1
  26. netgen/include/core/statushandler.hpp +37 -0
  27. netgen/include/core/table.hpp +3 -2
  28. netgen/include/core/taskmanager.hpp +34 -1
  29. netgen/include/core/utils.hpp +3 -8
  30. netgen/include/include/netgen_version.hpp +4 -4
  31. netgen/include/meshing/basegeom.hpp +1 -4
  32. netgen/include/meshing/global.hpp +0 -17
  33. netgen/include/meshing/hpref_tet.hpp +41 -0
  34. netgen/include/meshing/hprefinement.hpp +2 -0
  35. netgen/include/meshing/meshtype.hpp +2 -1
  36. netgen/include/meshing/msghandler.hpp +9 -6
  37. netgen/include/meshing/topology.hpp +2 -2
  38. netgen/include/nginterface.h +3 -2
  39. netgen/include/occ/occ_utils.hpp +26 -0
  40. netgen/include/occ/occgeom.hpp +8 -0
  41. netgen/include/pybind11/attr.h +40 -8
  42. netgen/include/pybind11/buffer_info.h +14 -14
  43. netgen/include/pybind11/cast.h +553 -29
  44. netgen/include/pybind11/chrono.h +4 -1
  45. netgen/include/pybind11/conduit/README.txt +15 -0
  46. netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
  47. netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
  48. netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
  49. netgen/include/pybind11/critical_section.h +56 -0
  50. netgen/include/pybind11/detail/class.h +172 -97
  51. netgen/include/pybind11/detail/common.h +270 -189
  52. netgen/include/pybind11/detail/cpp_conduit.h +75 -0
  53. netgen/include/pybind11/detail/descr.h +55 -0
  54. netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
  55. netgen/include/pybind11/detail/exception_translation.h +71 -0
  56. netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
  57. netgen/include/pybind11/detail/init.h +113 -9
  58. netgen/include/pybind11/detail/internals.h +479 -344
  59. netgen/include/pybind11/detail/native_enum_data.h +209 -0
  60. netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
  61. netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
  62. netgen/include/pybind11/detail/type_caster_base.h +506 -133
  63. netgen/include/pybind11/detail/using_smart_holder.h +22 -0
  64. netgen/include/pybind11/detail/value_and_holder.h +90 -0
  65. netgen/include/pybind11/eigen/matrix.h +19 -10
  66. netgen/include/pybind11/eigen/tensor.h +15 -11
  67. netgen/include/pybind11/embed.h +50 -46
  68. netgen/include/pybind11/eval.h +11 -6
  69. netgen/include/pybind11/functional.h +58 -49
  70. netgen/include/pybind11/gil.h +34 -82
  71. netgen/include/pybind11/gil_safe_call_once.h +12 -1
  72. netgen/include/pybind11/gil_simple.h +37 -0
  73. netgen/include/pybind11/native_enum.h +67 -0
  74. netgen/include/pybind11/numpy.h +272 -93
  75. netgen/include/pybind11/pybind11.h +947 -265
  76. netgen/include/pybind11/pytypes.h +127 -21
  77. netgen/include/pybind11/stl/filesystem.h +23 -25
  78. netgen/include/pybind11/stl.h +277 -59
  79. netgen/include/pybind11/stl_bind.h +42 -7
  80. netgen/include/pybind11/subinterpreter.h +299 -0
  81. netgen/include/pybind11/trampoline_self_life_support.h +65 -0
  82. netgen/include/pybind11/typing.h +177 -4
  83. netgen/include/pybind11/warnings.h +75 -0
  84. netgen/include/visualization/mvdraw.hpp +48 -12
  85. netgen/include/visualization/vssolution.hpp +3 -1
  86. netgen/lib/libnggui.lib +0 -0
  87. netgen/lib/ngcore.lib +0 -0
  88. netgen/lib/nglib.lib +0 -0
  89. netgen/libnggui.dll +0 -0
  90. netgen/libngguipy.pyd +0 -0
  91. netgen/libngpy/_NgOCC.pyi +224 -139
  92. netgen/libngpy/_csg.pyi +26 -26
  93. netgen/libngpy/_geom2d.pyi +34 -25
  94. netgen/libngpy/_meshing.pyi +262 -111
  95. netgen/libngpy/_stl.pyi +3 -4
  96. netgen/libngpy.pyd +0 -0
  97. netgen/ngcore.dll +0 -0
  98. netgen/nglib.dll +0 -0
  99. netgen/read_gmsh.py +41 -0
  100. netgen/togl.dll +0 -0
  101. netgen/version.py +1 -1
  102. netgen/webgui.py +38 -2
  103. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/METADATA +2 -1
  104. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/RECORD +153 -132
  105. pyngcore/pyngcore.cp313-win_amd64.pyd +0 -0
  106. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boundarycondition.geo +0 -0
  107. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boxcyl.geo +0 -0
  108. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/circle_on_cube.geo +0 -0
  109. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cone.geo +0 -0
  110. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cube.geo +0 -0
  111. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandring.geo +0 -0
  112. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandspheres.geo +0 -0
  113. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemcyl.geo +0 -0
  114. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemsphere.geo +0 -0
  115. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylinder.geo +0 -0
  116. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylsphere.geo +0 -0
  117. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/doc/ng4.pdf +0 -0
  118. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipsoid.geo +0 -0
  119. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipticcyl.geo +0 -0
  120. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/extrusion.geo +0 -0
  121. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/fichera.geo +0 -0
  122. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/frame.step +0 -0
  123. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/hinge.stl +0 -0
  124. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/lshape3d.geo +0 -0
  125. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes.geo +0 -0
  126. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes2.geo +0 -0
  127. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/matrix.geo +0 -0
  128. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ortho.geo +0 -0
  129. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/part1.stl +0 -0
  130. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/period.geo +0 -0
  131. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/exportNeutral.py +0 -0
  132. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/mesh.py +0 -0
  133. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/shaft.geo +0 -0
  134. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/revolution.geo +0 -0
  135. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/screw.step +0 -0
  136. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sculpture.geo +0 -0
  137. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shaft.geo +0 -0
  138. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shell.geo +0 -0
  139. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphere.geo +0 -0
  140. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphereincube.geo +0 -0
  141. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/square.in2d +0 -0
  142. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarecircle.in2d +0 -0
  143. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarehole.in2d +0 -0
  144. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/torus.geo +0 -0
  145. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/trafo.geo +0 -0
  146. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twobricks.geo +0 -0
  147. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocubes.geo +0 -0
  148. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocyl.geo +0 -0
  149. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/AUTHORS +0 -0
  150. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/LICENSE +0 -0
  151. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/WHEEL +0 -0
  152. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/entry_points.txt +0 -0
  153. {netgen_mesher-6.2.2504.post11.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 "../pytypes.h"
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() : parent{get_stack_top()} { set_stack_top(this); }
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
- if (get_stack_top() != this) {
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
- set_stack_top(parent);
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 = get_stack_top();
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
- auto ins = all_type_info_get_cache(type);
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
- auto &types = get_internals().registered_types_cpp;
221
- auto it = types.find(tp);
222
- if (it != types.end()) {
223
- return it->second;
224
- }
225
- return nullptr;
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
- // Searches the inheritance graph for a registered Python instance, using all_type_info().
254
- PYBIND11_NOINLINE handle find_registered_python_instance(void *src,
255
- const detail::type_info *tinfo) {
256
- auto it_instances = get_internals().registered_instances.equal_range(src);
257
- for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {
258
- for (auto *instance_type : detail::all_type_info(Py_TYPE(it_i->second))) {
259
- if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) {
260
- return handle((PyObject *) it_i->second).inc_ref();
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
- return handle();
265
- }
266
-
267
- struct value_and_holder {
268
- instance *inst = nullptr;
269
- size_t index = 0u;
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
- // True if this `value_and_holder` has a non-null value pointer
290
- explicit operator bool() const { return value_ptr() != nullptr; }
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
- template <typename H>
293
- H &holder() const {
294
- return reinterpret_cast<H &>(vh[1]);
295
- }
296
- bool holder_constructed() const {
297
- return inst->simple_layout
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
- bool instance_registered() const {
312
- return inst->simple_layout
313
- ? inst->simple_instance_registered
314
- : ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0);
315
- }
316
- // NOLINTNEXTLINE(readability-make-member-function-const)
317
- void set_instance_registered(bool v = true) {
318
- if (inst->simple_layout) {
319
- inst->simple_instance_registered = v;
320
- } else if (v) {
321
- inst->nonsimple.status[index] |= instance::status_instance_registered;
322
- } else {
323
- inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_instance_registered;
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
- auto &instances = get_internals().registered_instances;
510
- auto range = instances.equal_range(ptr);
511
- for (auto it = range.first; it != range.second; ++it) {
512
- for (const auto &vh : values_and_holders(it->second)) {
513
- if (vh.type == type) {
514
- return handle((PyObject *) it->second);
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
- return handle();
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(&src, policy, parent);
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(&src, return_value_policy::move, parent);
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