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
netgen/include/pybind11/cast.h
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
#include "detail/common.h"
|
|
14
14
|
#include "detail/descr.h"
|
|
15
|
+
#include "detail/native_enum_data.h"
|
|
15
16
|
#include "detail/type_caster_base.h"
|
|
16
17
|
#include "detail/typeid.h"
|
|
17
18
|
#include "pytypes.h"
|
|
@@ -53,6 +54,109 @@ cast_op(make_caster<T> &&caster) {
|
|
|
53
54
|
return std::move(caster).operator result_t();
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
template <typename EnumType>
|
|
58
|
+
class type_caster_enum_type {
|
|
59
|
+
private:
|
|
60
|
+
using Underlying = typename std::underlying_type<EnumType>::type;
|
|
61
|
+
|
|
62
|
+
public:
|
|
63
|
+
static constexpr auto name = const_name<EnumType>();
|
|
64
|
+
|
|
65
|
+
template <typename SrcType>
|
|
66
|
+
static handle cast(SrcType &&src, return_value_policy, handle parent) {
|
|
67
|
+
handle native_enum
|
|
68
|
+
= global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType)));
|
|
69
|
+
if (native_enum) {
|
|
70
|
+
return native_enum(static_cast<Underlying>(src)).release();
|
|
71
|
+
}
|
|
72
|
+
return type_caster_base<EnumType>::cast(
|
|
73
|
+
std::forward<SrcType>(src),
|
|
74
|
+
// Fixes https://github.com/pybind/pybind11/pull/3643#issuecomment-1022987818:
|
|
75
|
+
return_value_policy::copy,
|
|
76
|
+
parent);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
template <typename SrcType>
|
|
80
|
+
static handle cast(SrcType *src, return_value_policy policy, handle parent) {
|
|
81
|
+
return cast(*src, policy, parent);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
bool load(handle src, bool convert) {
|
|
85
|
+
handle native_enum
|
|
86
|
+
= global_internals_native_enum_type_map_get_item(std::type_index(typeid(EnumType)));
|
|
87
|
+
if (native_enum) {
|
|
88
|
+
if (!isinstance(src, native_enum)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
type_caster<Underlying> underlying_caster;
|
|
92
|
+
if (!underlying_caster.load(src.attr("value"), convert)) {
|
|
93
|
+
pybind11_fail("native_enum internal consistency failure.");
|
|
94
|
+
}
|
|
95
|
+
value = static_cast<EnumType>(static_cast<Underlying>(underlying_caster));
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
if (!pybind11_enum_) {
|
|
99
|
+
pybind11_enum_.reset(new type_caster_base<EnumType>());
|
|
100
|
+
}
|
|
101
|
+
return pybind11_enum_->load(src, convert);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
template <typename T>
|
|
105
|
+
using cast_op_type = detail::cast_op_type<T>;
|
|
106
|
+
|
|
107
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
108
|
+
operator EnumType *() {
|
|
109
|
+
if (!pybind11_enum_) {
|
|
110
|
+
return &value;
|
|
111
|
+
}
|
|
112
|
+
return pybind11_enum_->operator EnumType *();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
116
|
+
operator EnumType &() {
|
|
117
|
+
if (!pybind11_enum_) {
|
|
118
|
+
return value;
|
|
119
|
+
}
|
|
120
|
+
return pybind11_enum_->operator EnumType &();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private:
|
|
124
|
+
std::unique_ptr<type_caster_base<EnumType>> pybind11_enum_;
|
|
125
|
+
EnumType value;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
template <typename EnumType, typename SFINAE = void>
|
|
129
|
+
struct type_caster_enum_type_enabled : std::true_type {};
|
|
130
|
+
|
|
131
|
+
template <typename T>
|
|
132
|
+
struct type_uses_type_caster_enum_type {
|
|
133
|
+
static constexpr bool value
|
|
134
|
+
= std::is_enum<T>::value && type_caster_enum_type_enabled<T>::value;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
template <typename EnumType>
|
|
138
|
+
class type_caster<EnumType, detail::enable_if_t<type_uses_type_caster_enum_type<EnumType>::value>>
|
|
139
|
+
: public type_caster_enum_type<EnumType> {};
|
|
140
|
+
|
|
141
|
+
template <typename T, detail::enable_if_t<std::is_enum<T>::value, int> = 0>
|
|
142
|
+
bool isinstance_native_enum_impl(handle obj, const std::type_info &tp) {
|
|
143
|
+
handle native_enum = global_internals_native_enum_type_map_get_item(tp);
|
|
144
|
+
if (!native_enum) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return isinstance(obj, native_enum);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
template <typename T, detail::enable_if_t<!std::is_enum<T>::value, int> = 0>
|
|
151
|
+
bool isinstance_native_enum_impl(handle, const std::type_info &) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
template <typename T>
|
|
156
|
+
bool isinstance_native_enum(handle obj, const std::type_info &tp) {
|
|
157
|
+
return isinstance_native_enum_impl<intrinsic_t<T>>(obj, tp);
|
|
158
|
+
}
|
|
159
|
+
|
|
56
160
|
template <typename type>
|
|
57
161
|
class type_caster<std::reference_wrapper<type>> {
|
|
58
162
|
private:
|
|
@@ -158,7 +262,7 @@ public:
|
|
|
158
262
|
} else {
|
|
159
263
|
handle src_or_index = src;
|
|
160
264
|
// PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
|
|
161
|
-
#if
|
|
265
|
+
#if defined(PYPY_VERSION)
|
|
162
266
|
object index;
|
|
163
267
|
if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())
|
|
164
268
|
index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
|
|
@@ -241,7 +345,9 @@ public:
|
|
|
241
345
|
return PyLong_FromUnsignedLongLong((unsigned long long) src);
|
|
242
346
|
}
|
|
243
347
|
|
|
244
|
-
PYBIND11_TYPE_CASTER(T,
|
|
348
|
+
PYBIND11_TYPE_CASTER(T,
|
|
349
|
+
io_name<std::is_integral<T>::value>(
|
|
350
|
+
"typing.SupportsInt", "int", "typing.SupportsFloat", "float"));
|
|
245
351
|
};
|
|
246
352
|
|
|
247
353
|
template <typename T>
|
|
@@ -303,7 +409,7 @@ public:
|
|
|
303
409
|
template <typename T>
|
|
304
410
|
using cast_op_type = void *&;
|
|
305
411
|
explicit operator void *&() { return value; }
|
|
306
|
-
static constexpr auto name = const_name(
|
|
412
|
+
static constexpr auto name = const_name(PYBIND11_CAPSULE_TYPE_TYPE_HINT);
|
|
307
413
|
|
|
308
414
|
private:
|
|
309
415
|
void *value = nullptr;
|
|
@@ -343,7 +449,7 @@ public:
|
|
|
343
449
|
#else
|
|
344
450
|
// Alternate approach for CPython: this does the same as the above, but optimized
|
|
345
451
|
// using the CPython API so as to avoid an unneeded attribute lookup.
|
|
346
|
-
else if (auto *tp_as_number = src.ptr()->
|
|
452
|
+
else if (auto *tp_as_number = Py_TYPE(src.ptr())->tp_as_number) {
|
|
347
453
|
if (PYBIND11_NB_BOOL(tp_as_number)) {
|
|
348
454
|
res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr());
|
|
349
455
|
}
|
|
@@ -716,7 +822,9 @@ protected:
|
|
|
716
822
|
cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) {
|
|
717
823
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent);
|
|
718
824
|
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent);
|
|
825
|
+
|
|
719
826
|
std::array<object, size> entries{{reinterpret_steal<object>(
|
|
827
|
+
// NOLINTNEXTLINE(bugprone-use-after-move)
|
|
720
828
|
make_caster<Ts>::cast(std::get<Is>(std::forward<T>(src)), policy, parent))...}};
|
|
721
829
|
for (const auto &entry : entries) {
|
|
722
830
|
if (!entry) {
|
|
@@ -740,6 +848,13 @@ class type_caster<std::pair<T1, T2>> : public tuple_caster<std::pair, T1, T2> {}
|
|
|
740
848
|
template <typename... Ts>
|
|
741
849
|
class type_caster<std::tuple<Ts...>> : public tuple_caster<std::tuple, Ts...> {};
|
|
742
850
|
|
|
851
|
+
template <>
|
|
852
|
+
class type_caster<std::tuple<>> : public tuple_caster<std::tuple> {
|
|
853
|
+
public:
|
|
854
|
+
// PEP 484 specifies this syntax for an empty tuple
|
|
855
|
+
static constexpr auto name = const_name("tuple[()]");
|
|
856
|
+
};
|
|
857
|
+
|
|
743
858
|
/// Helper class which abstracts away certain actions. Users can provide specializations for
|
|
744
859
|
/// custom holders, but it's only necessary if the type has a non-standard interface.
|
|
745
860
|
template <typename T>
|
|
@@ -747,6 +862,7 @@ struct holder_helper {
|
|
|
747
862
|
static auto get(const T &p) -> decltype(p.get()) { return p.get(); }
|
|
748
863
|
};
|
|
749
864
|
|
|
865
|
+
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Rewrite comment, with reference to shared_ptr specialization.
|
|
750
866
|
/// Type caster for holder types like std::shared_ptr, etc.
|
|
751
867
|
/// The SFINAE hook is provided to help work around the current lack of support
|
|
752
868
|
/// for smart-pointer interoperability. Please consider it an implementation
|
|
@@ -782,16 +898,19 @@ public:
|
|
|
782
898
|
protected:
|
|
783
899
|
friend class type_caster_generic;
|
|
784
900
|
void check_holder_compat() {
|
|
785
|
-
|
|
901
|
+
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks.
|
|
902
|
+
bool inst_has_unique_ptr_holder
|
|
903
|
+
= (typeinfo->holder_enum_v == holder_enum_t::std_unique_ptr);
|
|
904
|
+
if (inst_has_unique_ptr_holder) {
|
|
786
905
|
throw cast_error("Unable to load a custom holder type from a default-holder instance");
|
|
787
906
|
}
|
|
788
907
|
}
|
|
789
908
|
|
|
790
|
-
|
|
909
|
+
void load_value(value_and_holder &&v_h) {
|
|
791
910
|
if (v_h.holder_constructed()) {
|
|
792
911
|
value = v_h.value_ptr();
|
|
793
912
|
holder = v_h.template holder<holder_type>();
|
|
794
|
-
return
|
|
913
|
+
return;
|
|
795
914
|
}
|
|
796
915
|
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
|
|
797
916
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
|
@@ -828,10 +947,205 @@ protected:
|
|
|
828
947
|
holder_type holder;
|
|
829
948
|
};
|
|
830
949
|
|
|
950
|
+
template <typename, typename SFINAE = void>
|
|
951
|
+
struct copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled : std::true_type {};
|
|
952
|
+
|
|
953
|
+
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Refactor copyable_holder_caster to reduce code duplication.
|
|
954
|
+
template <typename type>
|
|
955
|
+
struct copyable_holder_caster<
|
|
956
|
+
type,
|
|
957
|
+
std::shared_ptr<type>,
|
|
958
|
+
enable_if_t<copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled<type>::value>>
|
|
959
|
+
: public type_caster_base<type> {
|
|
960
|
+
public:
|
|
961
|
+
using base = type_caster_base<type>;
|
|
962
|
+
static_assert(std::is_base_of<base, type_caster<type>>::value,
|
|
963
|
+
"Holder classes are only supported for custom types");
|
|
964
|
+
using base::base;
|
|
965
|
+
using base::cast;
|
|
966
|
+
using base::typeinfo;
|
|
967
|
+
using base::value;
|
|
968
|
+
|
|
969
|
+
bool load(handle src, bool convert) {
|
|
970
|
+
if (base::template load_impl<copyable_holder_caster<type, std::shared_ptr<type>>>(
|
|
971
|
+
src, convert)) {
|
|
972
|
+
sh_load_helper.maybe_set_python_instance_is_alias(src);
|
|
973
|
+
return true;
|
|
974
|
+
}
|
|
975
|
+
return false;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
explicit operator std::shared_ptr<type> *() {
|
|
979
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
980
|
+
pybind11_fail("Passing `std::shared_ptr<T> *` from Python to C++ is not supported "
|
|
981
|
+
"(inherently unsafe).");
|
|
982
|
+
}
|
|
983
|
+
return std::addressof(shared_ptr_storage);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
explicit operator std::shared_ptr<type> &() {
|
|
987
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
988
|
+
shared_ptr_storage = sh_load_helper.load_as_shared_ptr(typeinfo, value);
|
|
989
|
+
}
|
|
990
|
+
return shared_ptr_storage;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
std::weak_ptr<type> potentially_slicing_weak_ptr() {
|
|
994
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
995
|
+
// Reusing shared_ptr code to minimize code complexity.
|
|
996
|
+
shared_ptr_storage
|
|
997
|
+
= sh_load_helper.load_as_shared_ptr(typeinfo,
|
|
998
|
+
value,
|
|
999
|
+
/*responsible_parent=*/nullptr,
|
|
1000
|
+
/*force_potentially_slicing_shared_ptr=*/true);
|
|
1001
|
+
}
|
|
1002
|
+
return shared_ptr_storage;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
static handle
|
|
1006
|
+
cast(const std::shared_ptr<type> &src, return_value_policy policy, handle parent) {
|
|
1007
|
+
const auto *ptr = src.get();
|
|
1008
|
+
auto st = type_caster_base<type>::src_and_type(ptr);
|
|
1009
|
+
if (st.second == nullptr) {
|
|
1010
|
+
return handle(); // no type info: error will be set already
|
|
1011
|
+
}
|
|
1012
|
+
if (st.second->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1013
|
+
return smart_holder_type_caster_support::smart_holder_from_shared_ptr(
|
|
1014
|
+
src, policy, parent, st);
|
|
1015
|
+
}
|
|
1016
|
+
return type_caster_base<type>::cast_holder(ptr, &src);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// This function will succeed even if the `responsible_parent` does not own the
|
|
1020
|
+
// wrapped C++ object directly.
|
|
1021
|
+
// It is the responsibility of the caller to ensure that the `responsible_parent`
|
|
1022
|
+
// has a `keep_alive` relationship with the owner of the wrapped C++ object, or
|
|
1023
|
+
// that the wrapped C++ object lives for the duration of the process.
|
|
1024
|
+
static std::shared_ptr<type> shared_ptr_with_responsible_parent(handle responsible_parent) {
|
|
1025
|
+
copyable_holder_caster loader;
|
|
1026
|
+
loader.load(responsible_parent, /*convert=*/false);
|
|
1027
|
+
assert(loader.typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder);
|
|
1028
|
+
return loader.sh_load_helper.load_as_shared_ptr(
|
|
1029
|
+
loader.typeinfo, loader.value, responsible_parent);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
protected:
|
|
1033
|
+
friend class type_caster_generic;
|
|
1034
|
+
void check_holder_compat() {
|
|
1035
|
+
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks.
|
|
1036
|
+
bool inst_has_unique_ptr_holder
|
|
1037
|
+
= (typeinfo->holder_enum_v == holder_enum_t::std_unique_ptr);
|
|
1038
|
+
if (inst_has_unique_ptr_holder) {
|
|
1039
|
+
throw cast_error("Unable to load a custom holder type from a default-holder instance");
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
void load_value(value_and_holder &&v_h) {
|
|
1044
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1045
|
+
sh_load_helper.loaded_v_h = v_h;
|
|
1046
|
+
sh_load_helper.was_populated = true;
|
|
1047
|
+
value = sh_load_helper.get_void_ptr_or_nullptr();
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1050
|
+
if (v_h.holder_constructed()) {
|
|
1051
|
+
value = v_h.value_ptr();
|
|
1052
|
+
shared_ptr_storage = v_h.template holder<std::shared_ptr<type>>();
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
|
|
1056
|
+
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
|
1057
|
+
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
|
1058
|
+
"type information)");
|
|
1059
|
+
#else
|
|
1060
|
+
"of type '"
|
|
1061
|
+
+ type_id<std::shared_ptr<type>>() + "''");
|
|
1062
|
+
#endif
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
template <typename T = std::shared_ptr<type>,
|
|
1066
|
+
detail::enable_if_t<!std::is_constructible<T, const T &, type *>::value, int> = 0>
|
|
1067
|
+
bool try_implicit_casts(handle, bool) {
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
template <typename T = std::shared_ptr<type>,
|
|
1072
|
+
detail::enable_if_t<std::is_constructible<T, const T &, type *>::value, int> = 0>
|
|
1073
|
+
bool try_implicit_casts(handle src, bool convert) {
|
|
1074
|
+
for (auto &cast : typeinfo->implicit_casts) {
|
|
1075
|
+
copyable_holder_caster sub_caster(*cast.first);
|
|
1076
|
+
if (sub_caster.load(src, convert)) {
|
|
1077
|
+
value = cast.second(sub_caster.value);
|
|
1078
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1079
|
+
sh_load_helper.loaded_v_h = sub_caster.sh_load_helper.loaded_v_h;
|
|
1080
|
+
} else {
|
|
1081
|
+
shared_ptr_storage
|
|
1082
|
+
= std::shared_ptr<type>(sub_caster.shared_ptr_storage, (type *) value);
|
|
1083
|
+
}
|
|
1084
|
+
return true;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return false;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
static bool try_direct_conversions(handle) { return false; }
|
|
1091
|
+
|
|
1092
|
+
smart_holder_type_caster_support::load_helper<remove_cv_t<type>> sh_load_helper; // Const2Mutbl
|
|
1093
|
+
std::shared_ptr<type> shared_ptr_storage;
|
|
1094
|
+
};
|
|
1095
|
+
|
|
831
1096
|
/// Specialize for the common std::shared_ptr, so users don't need to
|
|
832
1097
|
template <typename T>
|
|
833
1098
|
class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};
|
|
834
1099
|
|
|
1100
|
+
PYBIND11_NAMESPACE_END(detail)
|
|
1101
|
+
|
|
1102
|
+
/// Return a std::shared_ptr with the SAME CONTROL BLOCK as the std::shared_ptr owned by the
|
|
1103
|
+
/// class_ holder. For class_-wrapped types with trampolines, the returned std::shared_ptr
|
|
1104
|
+
/// does NOT keep any derived Python objects alive (see issue #1333).
|
|
1105
|
+
///
|
|
1106
|
+
/// For class_-wrapped types using std::shared_ptr as the holder, the following expressions
|
|
1107
|
+
/// produce equivalent results (see tests/test_potentially_slicing_weak_ptr.cpp,py):
|
|
1108
|
+
///
|
|
1109
|
+
/// - obj.cast<std::shared_ptr<T>>()
|
|
1110
|
+
/// - py::potentially_slicing_weak_ptr<T>(obj).lock()
|
|
1111
|
+
///
|
|
1112
|
+
/// For class_-wrapped types with trampolines and using py::smart_holder, obj.cast<>()
|
|
1113
|
+
/// produces a std::shared_ptr that keeps any derived Python objects alive for its own lifetime,
|
|
1114
|
+
/// but this is achieved by introducing a std::shared_ptr control block that is independent of
|
|
1115
|
+
/// the one owned by the py::smart_holder. This can lead to surprising std::weak_ptr behavior
|
|
1116
|
+
/// (see issue #5623). An easy solution is to use py::potentially_slicing_weak_ptr<>(obj),
|
|
1117
|
+
/// as exercised in tests/test_potentially_slicing_weak_ptr.cpp,py (look for
|
|
1118
|
+
/// "set_wp_potentially_slicing"). Note, however, that this reintroduces the inheritance
|
|
1119
|
+
/// slicing issue (see issue #1333). The ideal — but usually more involved — solution is to use
|
|
1120
|
+
/// a Python weakref to the derived Python object, instead of a C++ base-class std::weak_ptr.
|
|
1121
|
+
///
|
|
1122
|
+
/// It is not possible (at least no known approach exists at the time of this writing) to
|
|
1123
|
+
/// simultaneously achieve both desirable properties:
|
|
1124
|
+
///
|
|
1125
|
+
/// - the same std::shared_ptr control block as the class_ holder
|
|
1126
|
+
/// - automatic lifetime extension of any derived Python objects
|
|
1127
|
+
///
|
|
1128
|
+
/// The reason is that this would introduce a reference cycle that cannot be garbage collected:
|
|
1129
|
+
///
|
|
1130
|
+
/// - the derived Python object owns the class_ holder
|
|
1131
|
+
/// - the class_ holder owns the std::shared_ptr
|
|
1132
|
+
/// - the std::shared_ptr would own a reference to the derived Python object,
|
|
1133
|
+
/// completing the cycle
|
|
1134
|
+
template <typename T>
|
|
1135
|
+
std::weak_ptr<T> potentially_slicing_weak_ptr(handle obj) {
|
|
1136
|
+
detail::make_caster<std::shared_ptr<T>> caster;
|
|
1137
|
+
if (caster.load(obj, /*convert=*/true)) {
|
|
1138
|
+
return caster.potentially_slicing_weak_ptr();
|
|
1139
|
+
}
|
|
1140
|
+
const char *obj_type_name = detail::obj_class_name(obj.ptr());
|
|
1141
|
+
throw type_error("\"" + std::string(obj_type_name)
|
|
1142
|
+
+ "\" object is not convertible to std::weak_ptr<T> (with T = " + type_id<T>()
|
|
1143
|
+
+ ")");
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1147
|
+
|
|
1148
|
+
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Rewrite comment, with reference to unique_ptr specialization.
|
|
835
1149
|
/// Type caster for holder types like std::unique_ptr.
|
|
836
1150
|
/// Please consider the SFINAE hook an implementation detail, as explained
|
|
837
1151
|
/// in the comment for the copyable_holder_caster.
|
|
@@ -847,6 +1161,143 @@ struct move_only_holder_caster {
|
|
|
847
1161
|
static constexpr auto name = type_caster_base<type>::name;
|
|
848
1162
|
};
|
|
849
1163
|
|
|
1164
|
+
template <typename, typename SFINAE = void>
|
|
1165
|
+
struct move_only_holder_caster_unique_ptr_with_smart_holder_support_enabled : std::true_type {};
|
|
1166
|
+
|
|
1167
|
+
// SMART_HOLDER_BAKEIN_FOLLOW_ON: Refactor move_only_holder_caster to reduce code duplication.
|
|
1168
|
+
template <typename type, typename deleter>
|
|
1169
|
+
struct move_only_holder_caster<
|
|
1170
|
+
type,
|
|
1171
|
+
std::unique_ptr<type, deleter>,
|
|
1172
|
+
enable_if_t<move_only_holder_caster_unique_ptr_with_smart_holder_support_enabled<type>::value>>
|
|
1173
|
+
: public type_caster_base<type> {
|
|
1174
|
+
public:
|
|
1175
|
+
using base = type_caster_base<type>;
|
|
1176
|
+
static_assert(std::is_base_of<base, type_caster<type>>::value,
|
|
1177
|
+
"Holder classes are only supported for custom types");
|
|
1178
|
+
using base::base;
|
|
1179
|
+
using base::cast;
|
|
1180
|
+
using base::typeinfo;
|
|
1181
|
+
using base::value;
|
|
1182
|
+
|
|
1183
|
+
static handle
|
|
1184
|
+
cast(std::unique_ptr<type, deleter> &&src, return_value_policy policy, handle parent) {
|
|
1185
|
+
auto *ptr = src.get();
|
|
1186
|
+
auto st = type_caster_base<type>::src_and_type(ptr);
|
|
1187
|
+
if (st.second == nullptr) {
|
|
1188
|
+
return handle(); // no type info: error will be set already
|
|
1189
|
+
}
|
|
1190
|
+
if (st.second->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1191
|
+
return smart_holder_type_caster_support::smart_holder_from_unique_ptr(
|
|
1192
|
+
std::move(src), policy, parent, st);
|
|
1193
|
+
}
|
|
1194
|
+
return type_caster_generic::cast(st.first,
|
|
1195
|
+
return_value_policy::take_ownership,
|
|
1196
|
+
{},
|
|
1197
|
+
st.second,
|
|
1198
|
+
nullptr,
|
|
1199
|
+
nullptr,
|
|
1200
|
+
std::addressof(src));
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
static handle
|
|
1204
|
+
cast(const std::unique_ptr<type, deleter> &src, return_value_policy policy, handle parent) {
|
|
1205
|
+
if (!src) {
|
|
1206
|
+
return none().release();
|
|
1207
|
+
}
|
|
1208
|
+
if (policy == return_value_policy::automatic) {
|
|
1209
|
+
policy = return_value_policy::reference_internal;
|
|
1210
|
+
}
|
|
1211
|
+
if (policy != return_value_policy::reference_internal) {
|
|
1212
|
+
throw cast_error("Invalid return_value_policy for const unique_ptr&");
|
|
1213
|
+
}
|
|
1214
|
+
return type_caster_base<type>::cast(src.get(), policy, parent);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
bool load(handle src, bool convert) {
|
|
1218
|
+
if (base::template load_impl<
|
|
1219
|
+
move_only_holder_caster<type, std::unique_ptr<type, deleter>>>(src, convert)) {
|
|
1220
|
+
sh_load_helper.maybe_set_python_instance_is_alias(src);
|
|
1221
|
+
return true;
|
|
1222
|
+
}
|
|
1223
|
+
return false;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
void load_value(value_and_holder &&v_h) {
|
|
1227
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1228
|
+
sh_load_helper.loaded_v_h = v_h;
|
|
1229
|
+
sh_load_helper.loaded_v_h.type = typeinfo;
|
|
1230
|
+
sh_load_helper.was_populated = true;
|
|
1231
|
+
value = sh_load_helper.get_void_ptr_or_nullptr();
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
pybind11_fail("Passing `std::unique_ptr<T>` from Python to C++ requires `py::class_<T, "
|
|
1235
|
+
"py::smart_holder>` (with T = "
|
|
1236
|
+
+ clean_type_id(typeinfo->cpptype->name()) + ")");
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
template <typename T_>
|
|
1240
|
+
using cast_op_type
|
|
1241
|
+
= conditional_t<std::is_same<typename std::remove_volatile<T_>::type,
|
|
1242
|
+
const std::unique_ptr<type, deleter> &>::value
|
|
1243
|
+
|| std::is_same<typename std::remove_volatile<T_>::type,
|
|
1244
|
+
const std::unique_ptr<const type, deleter> &>::value,
|
|
1245
|
+
const std::unique_ptr<type, deleter> &,
|
|
1246
|
+
std::unique_ptr<type, deleter>>;
|
|
1247
|
+
|
|
1248
|
+
explicit operator std::unique_ptr<type, deleter>() {
|
|
1249
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1250
|
+
return sh_load_helper.template load_as_unique_ptr<deleter>(typeinfo, value);
|
|
1251
|
+
}
|
|
1252
|
+
pybind11_fail("Expected to be UNREACHABLE: " __FILE__ ":" PYBIND11_TOSTRING(__LINE__));
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
explicit operator const std::unique_ptr<type, deleter> &() {
|
|
1256
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1257
|
+
// Get shared_ptr to ensure that the Python object is not disowned elsewhere.
|
|
1258
|
+
shared_ptr_storage = sh_load_helper.load_as_shared_ptr(typeinfo, value);
|
|
1259
|
+
// Build a temporary unique_ptr that is meant to never expire.
|
|
1260
|
+
unique_ptr_storage = std::shared_ptr<std::unique_ptr<type, deleter>>(
|
|
1261
|
+
new std::unique_ptr<type, deleter>{
|
|
1262
|
+
sh_load_helper.template load_as_const_unique_ptr<deleter>(
|
|
1263
|
+
typeinfo, shared_ptr_storage.get())},
|
|
1264
|
+
[](std::unique_ptr<type, deleter> *ptr) {
|
|
1265
|
+
if (!ptr) {
|
|
1266
|
+
pybind11_fail("FATAL: `const std::unique_ptr<T, D> &` was disowned "
|
|
1267
|
+
"(EXPECT UNDEFINED BEHAVIOR).");
|
|
1268
|
+
}
|
|
1269
|
+
(void) ptr->release();
|
|
1270
|
+
delete ptr;
|
|
1271
|
+
});
|
|
1272
|
+
return *unique_ptr_storage;
|
|
1273
|
+
}
|
|
1274
|
+
pybind11_fail("Expected to be UNREACHABLE: " __FILE__ ":" PYBIND11_TOSTRING(__LINE__));
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
bool try_implicit_casts(handle src, bool convert) {
|
|
1278
|
+
for (auto &cast : typeinfo->implicit_casts) {
|
|
1279
|
+
move_only_holder_caster sub_caster(*cast.first);
|
|
1280
|
+
if (sub_caster.load(src, convert)) {
|
|
1281
|
+
value = cast.second(sub_caster.value);
|
|
1282
|
+
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
|
|
1283
|
+
sh_load_helper.loaded_v_h = sub_caster.sh_load_helper.loaded_v_h;
|
|
1284
|
+
} else {
|
|
1285
|
+
pybind11_fail("Expected to be UNREACHABLE: " __FILE__
|
|
1286
|
+
":" PYBIND11_TOSTRING(__LINE__));
|
|
1287
|
+
}
|
|
1288
|
+
return true;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
return false;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
static bool try_direct_conversions(handle) { return false; }
|
|
1295
|
+
|
|
1296
|
+
smart_holder_type_caster_support::load_helper<remove_cv_t<type>> sh_load_helper; // Const2Mutbl
|
|
1297
|
+
std::shared_ptr<type> shared_ptr_storage; // Serves as a pseudo lock.
|
|
1298
|
+
std::shared_ptr<std::unique_ptr<type, deleter>> unique_ptr_storage;
|
|
1299
|
+
};
|
|
1300
|
+
|
|
850
1301
|
template <typename type, typename deleter>
|
|
851
1302
|
class type_caster<std::unique_ptr<type, deleter>>
|
|
852
1303
|
: public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};
|
|
@@ -856,18 +1307,20 @@ using type_caster_holder = conditional_t<is_copy_constructible<holder_type>::val
|
|
|
856
1307
|
copyable_holder_caster<type, holder_type>,
|
|
857
1308
|
move_only_holder_caster<type, holder_type>>;
|
|
858
1309
|
|
|
859
|
-
template <
|
|
860
|
-
struct
|
|
1310
|
+
template <bool Value = false>
|
|
1311
|
+
struct always_construct_holder_value {
|
|
861
1312
|
static constexpr bool value = Value;
|
|
862
1313
|
};
|
|
863
1314
|
|
|
1315
|
+
template <typename T, bool Value = false>
|
|
1316
|
+
struct always_construct_holder : always_construct_holder_value<Value> {};
|
|
1317
|
+
|
|
864
1318
|
/// Create a specialization for custom holder types (silently ignores std::shared_ptr)
|
|
865
1319
|
#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...) \
|
|
866
1320
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) \
|
|
867
1321
|
namespace detail { \
|
|
868
1322
|
template <typename type> \
|
|
869
|
-
struct always_construct_holder<holder_type> :
|
|
870
|
-
}; \
|
|
1323
|
+
struct always_construct_holder<holder_type> : always_construct_holder_value<__VA_ARGS__> {}; \
|
|
871
1324
|
template <typename type> \
|
|
872
1325
|
class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>> \
|
|
873
1326
|
: public type_caster_holder<type, holder_type> {}; \
|
|
@@ -878,10 +1331,14 @@ struct always_construct_holder {
|
|
|
878
1331
|
template <typename base, typename holder>
|
|
879
1332
|
struct is_holder_type
|
|
880
1333
|
: std::is_base_of<detail::type_caster_holder<base, holder>, detail::type_caster<holder>> {};
|
|
881
|
-
|
|
1334
|
+
|
|
1335
|
+
// Specializations for always-supported holders:
|
|
882
1336
|
template <typename base, typename deleter>
|
|
883
1337
|
struct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};
|
|
884
1338
|
|
|
1339
|
+
template <typename base>
|
|
1340
|
+
struct is_holder_type<base, smart_holder> : std::true_type {};
|
|
1341
|
+
|
|
885
1342
|
#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888
|
|
886
1343
|
|
|
887
1344
|
// This leads to compilation errors if a specialization is missing.
|
|
@@ -911,7 +1368,7 @@ struct handle_type_name<dict> {
|
|
|
911
1368
|
};
|
|
912
1369
|
template <>
|
|
913
1370
|
struct handle_type_name<anyset> {
|
|
914
|
-
static constexpr auto name = const_name("
|
|
1371
|
+
static constexpr auto name = const_name("set | frozenset");
|
|
915
1372
|
};
|
|
916
1373
|
template <>
|
|
917
1374
|
struct handle_type_name<set> {
|
|
@@ -939,27 +1396,27 @@ struct handle_type_name<bytes> {
|
|
|
939
1396
|
};
|
|
940
1397
|
template <>
|
|
941
1398
|
struct handle_type_name<buffer> {
|
|
942
|
-
static constexpr auto name = const_name(
|
|
1399
|
+
static constexpr auto name = const_name(PYBIND11_BUFFER_TYPE_HINT);
|
|
943
1400
|
};
|
|
944
1401
|
template <>
|
|
945
1402
|
struct handle_type_name<int_> {
|
|
946
|
-
static constexpr auto name =
|
|
1403
|
+
static constexpr auto name = io_name("typing.SupportsInt", "int");
|
|
947
1404
|
};
|
|
948
1405
|
template <>
|
|
949
1406
|
struct handle_type_name<iterable> {
|
|
950
|
-
static constexpr auto name = const_name("Iterable");
|
|
1407
|
+
static constexpr auto name = const_name("collections.abc.Iterable");
|
|
951
1408
|
};
|
|
952
1409
|
template <>
|
|
953
1410
|
struct handle_type_name<iterator> {
|
|
954
|
-
static constexpr auto name = const_name("Iterator");
|
|
1411
|
+
static constexpr auto name = const_name("collections.abc.Iterator");
|
|
955
1412
|
};
|
|
956
1413
|
template <>
|
|
957
1414
|
struct handle_type_name<float_> {
|
|
958
|
-
static constexpr auto name =
|
|
1415
|
+
static constexpr auto name = io_name("typing.SupportsFloat", "float");
|
|
959
1416
|
};
|
|
960
1417
|
template <>
|
|
961
1418
|
struct handle_type_name<function> {
|
|
962
|
-
static constexpr auto name = const_name("Callable");
|
|
1419
|
+
static constexpr auto name = const_name("collections.abc.Callable");
|
|
963
1420
|
};
|
|
964
1421
|
template <>
|
|
965
1422
|
struct handle_type_name<handle> {
|
|
@@ -971,7 +1428,7 @@ struct handle_type_name<none> {
|
|
|
971
1428
|
};
|
|
972
1429
|
template <>
|
|
973
1430
|
struct handle_type_name<sequence> {
|
|
974
|
-
static constexpr auto name = const_name("Sequence");
|
|
1431
|
+
static constexpr auto name = const_name("collections.abc.Sequence");
|
|
975
1432
|
};
|
|
976
1433
|
template <>
|
|
977
1434
|
struct handle_type_name<bytearray> {
|
|
@@ -991,7 +1448,7 @@ struct handle_type_name<type> {
|
|
|
991
1448
|
};
|
|
992
1449
|
template <>
|
|
993
1450
|
struct handle_type_name<capsule> {
|
|
994
|
-
static constexpr auto name = const_name(
|
|
1451
|
+
static constexpr auto name = const_name(PYBIND11_CAPSULE_TYPE_TYPE_HINT);
|
|
995
1452
|
};
|
|
996
1453
|
template <>
|
|
997
1454
|
struct handle_type_name<ellipsis> {
|
|
@@ -999,16 +1456,24 @@ struct handle_type_name<ellipsis> {
|
|
|
999
1456
|
};
|
|
1000
1457
|
template <>
|
|
1001
1458
|
struct handle_type_name<weakref> {
|
|
1002
|
-
static constexpr auto name = const_name("weakref");
|
|
1459
|
+
static constexpr auto name = const_name("weakref.ReferenceType");
|
|
1003
1460
|
};
|
|
1004
1461
|
template <>
|
|
1005
1462
|
struct handle_type_name<args> {
|
|
1006
1463
|
static constexpr auto name = const_name("*args");
|
|
1007
1464
|
};
|
|
1465
|
+
template <typename T>
|
|
1466
|
+
struct handle_type_name<Args<T>> {
|
|
1467
|
+
static constexpr auto name = const_name("*args: ") + make_caster<T>::name;
|
|
1468
|
+
};
|
|
1008
1469
|
template <>
|
|
1009
1470
|
struct handle_type_name<kwargs> {
|
|
1010
1471
|
static constexpr auto name = const_name("**kwargs");
|
|
1011
1472
|
};
|
|
1473
|
+
template <typename T>
|
|
1474
|
+
struct handle_type_name<KWArgs<T>> {
|
|
1475
|
+
static constexpr auto name = const_name("**kwargs: ") + make_caster<T>::name;
|
|
1476
|
+
};
|
|
1012
1477
|
template <>
|
|
1013
1478
|
struct handle_type_name<obj_attr_accessor> {
|
|
1014
1479
|
static constexpr auto name = const_name<obj_attr_accessor>();
|
|
@@ -1172,8 +1637,17 @@ template <typename T,
|
|
|
1172
1637
|
= 0>
|
|
1173
1638
|
T cast(const handle &handle) {
|
|
1174
1639
|
using namespace detail;
|
|
1175
|
-
|
|
1640
|
+
constexpr bool is_enum_cast = type_uses_type_caster_enum_type<intrinsic_t<T>>::value;
|
|
1641
|
+
static_assert(!cast_is_temporary_value_reference<T>::value || is_enum_cast,
|
|
1176
1642
|
"Unable to cast type to reference: value is local to type caster");
|
|
1643
|
+
#ifndef NDEBUG
|
|
1644
|
+
if (is_enum_cast && cast_is_temporary_value_reference<T>::value) {
|
|
1645
|
+
if (detail::global_internals_native_enum_type_map_contains(
|
|
1646
|
+
std::type_index(typeid(intrinsic_t<T>)))) {
|
|
1647
|
+
pybind11_fail("Unable to cast native enum type to reference");
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
#endif
|
|
1177
1651
|
return cast_op<T>(load_type<T>(handle));
|
|
1178
1652
|
}
|
|
1179
1653
|
|
|
@@ -1308,12 +1782,42 @@ inline void object::cast() && {
|
|
|
1308
1782
|
|
|
1309
1783
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
1310
1784
|
|
|
1785
|
+
// forward declaration (definition in pybind11.h)
|
|
1786
|
+
template <typename T>
|
|
1787
|
+
std::string generate_type_signature();
|
|
1788
|
+
|
|
1311
1789
|
// Declared in pytypes.h:
|
|
1312
1790
|
template <typename T, enable_if_t<!is_pyobject<T>::value, int>>
|
|
1313
1791
|
object object_or_cast(T &&o) {
|
|
1314
1792
|
return pybind11::cast(std::forward<T>(o));
|
|
1315
1793
|
}
|
|
1316
1794
|
|
|
1795
|
+
// Declared in pytypes.h:
|
|
1796
|
+
// Implemented here so that make_caster<T> can be used.
|
|
1797
|
+
template <typename D>
|
|
1798
|
+
template <typename T>
|
|
1799
|
+
str_attr_accessor object_api<D>::attr_with_type_hint(const char *key) const {
|
|
1800
|
+
#if !defined(__cpp_inline_variables)
|
|
1801
|
+
static_assert(always_false<T>::value,
|
|
1802
|
+
"C++17 feature __cpp_inline_variables not available: "
|
|
1803
|
+
"https://en.cppreference.com/w/cpp/language/static#Static_data_members");
|
|
1804
|
+
#endif
|
|
1805
|
+
object ann = annotations();
|
|
1806
|
+
if (ann.contains(key)) {
|
|
1807
|
+
throw std::runtime_error("__annotations__[\"" + std::string(key) + "\"] was set already.");
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
ann[key] = generate_type_signature<T>();
|
|
1811
|
+
return {derived(), key};
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
template <typename D>
|
|
1815
|
+
template <typename T>
|
|
1816
|
+
obj_attr_accessor object_api<D>::attr_with_type_hint(handle key) const {
|
|
1817
|
+
(void) attr_with_type_hint<T>(key.cast<std::string>().c_str());
|
|
1818
|
+
return {derived(), reinterpret_borrow<object>(key)};
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1317
1821
|
// Placeholder type for the unneeded (and dead code) static variable in the
|
|
1318
1822
|
// PYBIND11_OVERRIDE_OVERRIDE macro
|
|
1319
1823
|
struct override_unused {};
|
|
@@ -1339,13 +1843,24 @@ enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,
|
|
|
1339
1843
|
// static_assert, even though if it's in dead code, so we provide a "trampoline" to pybind11::cast
|
|
1340
1844
|
// that only does anything in cases where pybind11::cast is valid.
|
|
1341
1845
|
template <typename T>
|
|
1342
|
-
enable_if_t<cast_is_temporary_value_reference<T>::value
|
|
1846
|
+
enable_if_t<cast_is_temporary_value_reference<T>::value
|
|
1847
|
+
&& !detail::is_same_ignoring_cvref<T, PyObject *>::value,
|
|
1848
|
+
T>
|
|
1849
|
+
cast_safe(object &&) {
|
|
1343
1850
|
pybind11_fail("Internal error: cast_safe fallback invoked");
|
|
1344
1851
|
}
|
|
1345
1852
|
template <typename T>
|
|
1346
1853
|
enable_if_t<std::is_void<T>::value, void> cast_safe(object &&) {}
|
|
1347
1854
|
template <typename T>
|
|
1348
|
-
enable_if_t<detail::
|
|
1855
|
+
enable_if_t<detail::is_same_ignoring_cvref<T, PyObject *>::value, PyObject *>
|
|
1856
|
+
cast_safe(object &&o) {
|
|
1857
|
+
return o.release().ptr();
|
|
1858
|
+
}
|
|
1859
|
+
template <typename T>
|
|
1860
|
+
enable_if_t<detail::none_of<cast_is_temporary_value_reference<T>,
|
|
1861
|
+
detail::is_same_ignoring_cvref<T, PyObject *>,
|
|
1862
|
+
std::is_void<T>>::value,
|
|
1863
|
+
T>
|
|
1349
1864
|
cast_safe(object &&o) {
|
|
1350
1865
|
return pybind11::cast<T>(std::move(o));
|
|
1351
1866
|
}
|
|
@@ -1485,7 +2000,7 @@ struct kw_only {};
|
|
|
1485
2000
|
|
|
1486
2001
|
/// \ingroup annotations
|
|
1487
2002
|
/// Annotation indicating that all previous arguments are positional-only; the is the equivalent of
|
|
1488
|
-
/// an unnamed '/' argument
|
|
2003
|
+
/// an unnamed '/' argument
|
|
1489
2004
|
struct pos_only {};
|
|
1490
2005
|
|
|
1491
2006
|
template <typename T>
|
|
@@ -1546,15 +2061,24 @@ struct function_call {
|
|
|
1546
2061
|
handle init_self;
|
|
1547
2062
|
};
|
|
1548
2063
|
|
|
2064
|
+
// See PR #5396 for the discussion that led to this
|
|
2065
|
+
template <typename Base, typename Derived, typename = void>
|
|
2066
|
+
struct is_same_or_base_of : std::is_same<Base, Derived> {};
|
|
2067
|
+
|
|
2068
|
+
// Only evaluate is_base_of if Derived is complete.
|
|
2069
|
+
// is_base_of raises a compiler error if Derived is incomplete.
|
|
2070
|
+
template <typename Base, typename Derived>
|
|
2071
|
+
struct is_same_or_base_of<Base, Derived, decltype(void(sizeof(Derived)))>
|
|
2072
|
+
: any_of<std::is_same<Base, Derived>, std::is_base_of<Base, Derived>> {};
|
|
2073
|
+
|
|
1549
2074
|
/// Helper class which loads arguments for C++ functions called from Python
|
|
1550
2075
|
template <typename... Args>
|
|
1551
2076
|
class argument_loader {
|
|
1552
2077
|
using indices = make_index_sequence<sizeof...(Args)>;
|
|
1553
|
-
|
|
1554
2078
|
template <typename Arg>
|
|
1555
|
-
using argument_is_args =
|
|
2079
|
+
using argument_is_args = is_same_or_base_of<args, intrinsic_t<Arg>>;
|
|
1556
2080
|
template <typename Arg>
|
|
1557
|
-
using argument_is_kwargs =
|
|
2081
|
+
using argument_is_kwargs = is_same_or_base_of<kwargs, intrinsic_t<Arg>>;
|
|
1558
2082
|
// Get kwargs argument position, or -1 if not present:
|
|
1559
2083
|
static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();
|
|
1560
2084
|
|