Copy-paste-and-specialize copyable_holder_caster<shared_ptr>, move_only_holder_caster<unique_ptr>. No functional changes.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2024-07-01 11:47:34 -07:00
parent e4d0a55575
commit 5518e01562

View File

@ -828,6 +828,84 @@ protected:
holder_type holder;
};
// BAKEIN_WIP
template <typename type>
struct copyable_holder_caster<type, std::shared_ptr<type>> : public type_caster_base<type> {
public:
using base = type_caster_base<type>;
static_assert(std::is_base_of<base, type_caster<type>>::value,
"Holder classes are only supported for custom types");
using base::base;
using base::cast;
using base::typeinfo;
using base::value;
bool load(handle src, bool convert) {
return base::template load_impl<copyable_holder_caster<type, std::shared_ptr<type>>>(
src, convert);
}
explicit operator type *() { return this->value; }
// static_cast works around compiler error with MSVC 17 and CUDA 10.2
// see issue #2180
explicit operator type &() { return *(static_cast<type *>(this->value)); }
explicit operator std::shared_ptr<type> *() { return std::addressof(holder); }
explicit operator std::shared_ptr<type> &() { return holder; }
static handle cast(const std::shared_ptr<type> &src, return_value_policy, handle) {
const auto *ptr = holder_helper<std::shared_ptr<type>>::get(src);
return type_caster_base<type>::cast_holder(ptr, &src);
}
protected:
friend class type_caster_generic;
void check_holder_compat() {
if (typeinfo->default_holder) {
throw cast_error("Unable to load a custom holder type from a default-holder instance");
}
}
bool load_value(value_and_holder &&v_h) {
if (v_h.holder_constructed()) {
value = v_h.value_ptr();
holder = v_h.template holder<std::shared_ptr<type>>();
return true;
}
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
"type information)");
#else
"of type '"
+ type_id<std::shared_ptr<type>>() + "''");
#endif
}
template <typename T = std::shared_ptr<type>,
detail::enable_if_t<!std::is_constructible<T, const T &, type *>::value, int> = 0>
bool try_implicit_casts(handle, bool) {
return false;
}
template <typename T = std::shared_ptr<type>,
detail::enable_if_t<std::is_constructible<T, const T &, type *>::value, int> = 0>
bool try_implicit_casts(handle src, bool convert) {
for (auto &cast : typeinfo->implicit_casts) {
copyable_holder_caster sub_caster(*cast.first);
if (sub_caster.load(src, convert)) {
value = cast.second(sub_caster.value);
holder = std::shared_ptr<type>(sub_caster.holder, (type *) value);
return true;
}
}
return false;
}
static bool try_direct_conversions(handle) { return false; }
std::shared_ptr<type> holder;
};
/// Specialize for the common std::shared_ptr, so users don't need to
template <typename T>
class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};
@ -847,6 +925,19 @@ struct move_only_holder_caster {
static constexpr auto name = type_caster_base<type>::name;
};
// BAKEIN_WIP
template <typename type, typename deleter>
struct move_only_holder_caster<type, std::unique_ptr<type, deleter>> {
static_assert(std::is_base_of<type_caster_base<type>, type_caster<type>>::value,
"Holder classes are only supported for custom types");
static handle cast(std::unique_ptr<type, deleter> &&src, return_value_policy, handle) {
auto *ptr = src.get();
return type_caster_base<type>::cast_holder(ptr, std::addressof(src));
}
static constexpr auto name = type_caster_base<type>::name;
};
template <typename type, typename deleter>
class type_caster<std::unique_ptr<type, deleter>>
: public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};