mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 16:13:53 +00:00
static handle cast implementations for rtrn_shmp, rtrn_shcp.
This commit is contained in:
parent
649eb91f21
commit
6601ec4ea7
@ -268,30 +268,18 @@ public:
|
|||||||
private:
|
private:
|
||||||
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
|
/// Initialize holder object, variant 1: object derives from enable_shared_from_this
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void init_holder(detail::instance *inst, detail::value_and_holder &v_h,
|
static void init_holder(detail::value_and_holder &/*v_h*/,
|
||||||
const holder_type * /* unused */, const std::enable_shared_from_this<T> * /* dummy */) {
|
const holder_type * /* unused */, const std::enable_shared_from_this<T> * /* dummy */) {
|
||||||
try {
|
throw std::runtime_error("Not implemented: classh::init_holder enable_shared_from_this.");
|
||||||
auto sh = std::dynamic_pointer_cast<type>( // Was: typename holder_type::element_type
|
|
||||||
v_h.value_ptr<type>()->shared_from_this());
|
|
||||||
if (sh) {
|
|
||||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));
|
|
||||||
v_h.set_holder_constructed();
|
|
||||||
}
|
|
||||||
} catch (const std::bad_weak_ptr &) {}
|
|
||||||
|
|
||||||
if (!v_h.holder_constructed() && inst->owned) {
|
|
||||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
|
||||||
v_h.set_holder_constructed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize holder object, variant 2: try to construct from existing holder object, if possible
|
/// Initialize holder object, variant 2: try to construct from existing holder object, if possible
|
||||||
static void init_holder(detail::instance *inst, detail::value_and_holder &v_h,
|
static void init_holder(detail::value_and_holder &v_h,
|
||||||
const holder_type *holder_ptr, const void * /* dummy -- not enable_shared_from_this<T>) */) {
|
const holder_type *holder_ptr, const void * /* dummy -- not enable_shared_from_this<T>) */) {
|
||||||
if (holder_ptr) {
|
if (holder_ptr) {
|
||||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));
|
new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(*holder_ptr));
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
} else if (inst->owned || detail::always_construct_holder<holder_type>::value) {
|
} else { // Was: if (inst->owned || detail::always_construct_holder<holder_type>::value)
|
||||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(
|
new (std::addressof(v_h.holder<holder_type>())) holder_type(
|
||||||
std::move(holder_type::from_raw_ptr_take_ownership(v_h.value_ptr<type>())));
|
std::move(holder_type::from_raw_ptr_take_ownership(v_h.value_ptr<type>())));
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
@ -308,7 +296,7 @@ private:
|
|||||||
register_instance(inst, v_h.value_ptr(), v_h.type);
|
register_instance(inst, v_h.value_ptr(), v_h.type);
|
||||||
v_h.set_instance_registered();
|
v_h.set_instance_registered();
|
||||||
}
|
}
|
||||||
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
|
init_holder(v_h, static_cast<const holder_type *>(holder_ptr), v_h.value_ptr<type>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
||||||
|
@ -93,7 +93,7 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static handle cast(mpty &src, return_value_policy policy, handle parent) {
|
static handle cast(mpty &src, return_value_policy policy, handle parent) {
|
||||||
return cast(const_cast<mpty const &>(src), policy, parent); // Mtbl2Const
|
return cast(const_cast<mpty const &>(src), policy, parent); // Mutbl2Const
|
||||||
}
|
}
|
||||||
|
|
||||||
static handle cast(mpty const *src, return_value_policy policy, handle parent) {
|
static handle cast(mpty const *src, return_value_policy policy, handle parent) {
|
||||||
@ -108,7 +108,7 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static handle cast(mpty *src, return_value_policy policy, handle parent) {
|
static handle cast(mpty *src, return_value_policy policy, handle parent) {
|
||||||
return cast(const_cast<mpty const *>(src), policy, parent); // Mtbl2Const
|
return cast(const_cast<mpty const *>(src), policy, parent); // Mutbl2Const
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T_>
|
template <typename T_>
|
||||||
@ -287,10 +287,43 @@ template <>
|
|||||||
struct type_caster<std::shared_ptr<mpty>> : smart_holder_type_caster_load<mpty> {
|
struct type_caster<std::shared_ptr<mpty>> : smart_holder_type_caster_load<mpty> {
|
||||||
static constexpr auto name = _<std::shared_ptr<mpty>>();
|
static constexpr auto name = _<std::shared_ptr<mpty>>();
|
||||||
|
|
||||||
static handle cast(const std::shared_ptr<mpty> & /*src*/,
|
static handle
|
||||||
return_value_policy /*policy*/,
|
cast(const std::shared_ptr<mpty> &src, return_value_policy policy, handle parent) {
|
||||||
handle /*parent*/) {
|
if (policy != return_value_policy::automatic
|
||||||
return str("cast_shmp").release();
|
&& policy != return_value_policy::reference_internal) {
|
||||||
|
// IMPROVEABLE: Error message.
|
||||||
|
throw cast_error("Invalid return_value_policy for shared_ptr.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto src_raw_ptr = src.get();
|
||||||
|
auto st = type_caster<mpty>::src_and_type(src_raw_ptr);
|
||||||
|
if (st.first == nullptr)
|
||||||
|
return none().release(); // PyErr was set already.
|
||||||
|
|
||||||
|
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
|
||||||
|
const detail::type_info *tinfo = st.second;
|
||||||
|
auto it_instances = get_internals().registered_instances.equal_range(src_raw_void_ptr);
|
||||||
|
// Loop copied from type_caster_generic::cast.
|
||||||
|
for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {
|
||||||
|
for (auto instance_type : detail::all_type_info(Py_TYPE(it_i->second))) {
|
||||||
|
if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype))
|
||||||
|
// MISSING: Enforcement of consistency with existing smart_holder.
|
||||||
|
// MISSING: keep_alive.
|
||||||
|
return handle((PyObject *) it_i->second).inc_ref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
|
||||||
|
instance *inst_raw_ptr = reinterpret_cast<instance *>(inst.ptr());
|
||||||
|
inst_raw_ptr->owned = false; // Not actually used.
|
||||||
|
|
||||||
|
auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(src);
|
||||||
|
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
|
||||||
|
|
||||||
|
if (policy == return_value_policy::reference_internal)
|
||||||
|
keep_alive_impl(inst, parent);
|
||||||
|
|
||||||
|
return inst.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
@ -303,10 +336,12 @@ template <>
|
|||||||
struct type_caster<std::shared_ptr<mpty const>> : smart_holder_type_caster_load<mpty> {
|
struct type_caster<std::shared_ptr<mpty const>> : smart_holder_type_caster_load<mpty> {
|
||||||
static constexpr auto name = _<std::shared_ptr<mpty const>>();
|
static constexpr auto name = _<std::shared_ptr<mpty const>>();
|
||||||
|
|
||||||
static handle cast(const std::shared_ptr<mpty const> & /*src*/,
|
static handle
|
||||||
return_value_policy /*policy*/,
|
cast(const std::shared_ptr<mpty const> &src, return_value_policy policy, handle parent) {
|
||||||
handle /*parent*/) {
|
return type_caster<std::shared_ptr<mpty>>::cast(
|
||||||
return str("cast_shcp").release();
|
std::const_pointer_cast<mpty>(src), // Const2Mutbl
|
||||||
|
policy,
|
||||||
|
parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename>
|
template <typename>
|
||||||
|
@ -39,8 +39,8 @@ def test_load():
|
|||||||
|
|
||||||
|
|
||||||
def test_cast_shared_ptr():
|
def test_cast_shared_ptr():
|
||||||
assert m.rtrn_mpty_shmp() == "cast_shmp"
|
assert m.get_mtxt(m.rtrn_mpty_shmp()) == "rtrn_shmp"
|
||||||
assert m.rtrn_mpty_shcp() == "cast_shcp"
|
assert m.get_mtxt(m.rtrn_mpty_shcp()) == "rtrn_shcp"
|
||||||
|
|
||||||
|
|
||||||
def test_load_shared_ptr():
|
def test_load_shared_ptr():
|
||||||
|
Loading…
Reference in New Issue
Block a user