mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
Store a static type_caster rather than the basic type
This commit is contained in:
parent
f3f53e2b03
commit
3e4fe6c0a8
@ -867,8 +867,8 @@ template <typename type> using cast_is_temporary_value_reference = bool_constant
|
||||
!std::is_base_of<type_caster_generic, make_caster<type>>::value
|
||||
>;
|
||||
|
||||
template <typename T> make_caster<T> load_type(const handle &handle) {
|
||||
make_caster<T> conv;
|
||||
// Basic python -> C++ casting; throws if casting fails
|
||||
template <typename TypeCaster> TypeCaster &load_type(TypeCaster &conv, const handle &handle) {
|
||||
if (!conv.load(handle, true)) {
|
||||
#if defined(NDEBUG)
|
||||
throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)");
|
||||
@ -879,6 +879,12 @@ template <typename T> make_caster<T> load_type(const handle &handle) {
|
||||
}
|
||||
return conv;
|
||||
}
|
||||
// Wrapper around the above that also constructs and returns a type_caster
|
||||
template <typename T> make_caster<T> load_type(const handle &handle) {
|
||||
make_caster<T> conv;
|
||||
load_type(conv, handle);
|
||||
return conv;
|
||||
}
|
||||
|
||||
NAMESPACE_END(detail)
|
||||
|
||||
@ -943,22 +949,16 @@ template <> inline void object::cast() && { return; }
|
||||
|
||||
NAMESPACE_BEGIN(detail)
|
||||
|
||||
struct overload_nothing {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro
|
||||
template <typename ret_type> using overload_local_t = conditional_t<
|
||||
cast_is_temporary_value_reference<ret_type>::value, intrinsic_t<ret_type>, overload_nothing>;
|
||||
|
||||
template <typename T> enable_if_t<std::is_lvalue_reference<T>::value, T> storage_cast(intrinsic_t<T> &v) { return v; }
|
||||
template <typename T> enable_if_t<std::is_pointer<T>::value, T> storage_cast(intrinsic_t<T> &v) { return &v; }
|
||||
struct overload_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro
|
||||
template <typename ret_type> using overload_caster_t = conditional_t<
|
||||
cast_is_temporary_value_reference<ret_type>::value, make_caster<ret_type>, overload_unused>;
|
||||
|
||||
// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then
|
||||
// store the result in the given variable. For other types, this is a no-op.
|
||||
template <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o, intrinsic_t<T> &storage) {
|
||||
using type_caster = make_caster<T>;
|
||||
using itype = intrinsic_t<T>;
|
||||
storage = std::move(load_type<T>(o).operator typename type_caster::template cast_op_type<itype>());
|
||||
return storage_cast<T>(storage);
|
||||
template <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o, make_caster<T> &caster) {
|
||||
return load_type(caster, o).operator typename make_caster<T>::template cast_op_type<T>();
|
||||
}
|
||||
template <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&, overload_nothing &) {
|
||||
template <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&, overload_unused &) {
|
||||
pybind11_fail("Internal error: cast_ref fallback invoked"); }
|
||||
|
||||
// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even
|
||||
|
@ -1486,10 +1486,10 @@ template <class T> function get_overload(const T *this_ptr, const char *name) {
|
||||
pybind11::gil_scoped_acquire gil; \
|
||||
pybind11::function overload = pybind11::get_overload(static_cast<const cname *>(this), name); \
|
||||
if (overload) { \
|
||||
pybind11::object o = overload(__VA_ARGS__); \
|
||||
auto o = overload(__VA_ARGS__); \
|
||||
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \
|
||||
static pybind11::detail::overload_local_t<ret_type> local_value; \
|
||||
return pybind11::detail::cast_ref<ret_type>(std::move(o), local_value); \
|
||||
static pybind11::detail::overload_caster_t<ret_type> caster; \
|
||||
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
|
||||
} \
|
||||
else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
|
||||
} \
|
||||
|
Loading…
Reference in New Issue
Block a user