mirror of
https://github.com/pybind/pybind11.git
synced 2024-12-01 17:37:15 +00:00
Bring smart_holder init_instance_for_type<> directly into the init_instance() specialization. Also bring in dynamic_raw_ptr_cast_if_possible.h. Does not build because try_initialization_using_shared_from_this() is still missing.
This commit is contained in:
parent
00a91571fb
commit
fbf88cb298
39
include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h
Normal file
39
include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) 2021 The Pybind Development Team.
|
||||||
|
// All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
|
template <typename To, typename From, typename SFINAE = void>
|
||||||
|
struct dynamic_raw_ptr_cast_is_possible : std::false_type {};
|
||||||
|
|
||||||
|
template <typename To, typename From>
|
||||||
|
struct dynamic_raw_ptr_cast_is_possible<
|
||||||
|
To,
|
||||||
|
From,
|
||||||
|
detail::enable_if_t<!std::is_same<To, void>::value && std::is_polymorphic<From>::value>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
template <typename To,
|
||||||
|
typename From,
|
||||||
|
detail::enable_if_t<!dynamic_raw_ptr_cast_is_possible<To, From>::value, int> = 0>
|
||||||
|
To *dynamic_raw_ptr_cast_if_possible(From * /*ptr*/) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename To,
|
||||||
|
typename From,
|
||||||
|
detail::enable_if_t<dynamic_raw_ptr_cast_is_possible<To, From>::value, int> = 0>
|
||||||
|
To *dynamic_raw_ptr_cast_if_possible(From *ptr) {
|
||||||
|
return dynamic_cast<To *>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
@ -11,6 +11,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "detail/class.h"
|
#include "detail/class.h"
|
||||||
|
#include "detail/dynamic_raw_ptr_cast_if_possible.h"
|
||||||
#include "detail/init.h"
|
#include "detail/init.h"
|
||||||
#include "detail/smart_holder_poc.h"
|
#include "detail/smart_holder_poc.h"
|
||||||
#include "attr.h"
|
#include "attr.h"
|
||||||
@ -1968,8 +1969,37 @@ private:
|
|||||||
|
|
||||||
template <typename H = holder_type,
|
template <typename H = holder_type,
|
||||||
detail::enable_if_t<std::is_same<H, pybindit::memory::smart_holder>::value, int> = 0>
|
detail::enable_if_t<std::is_same<H, pybindit::memory::smart_holder>::value, int> = 0>
|
||||||
static void init_instance(detail::instance * /*inst*/, const void * /*holder_ptr*/) {
|
static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) {
|
||||||
// detail::type_caster<T>::template init_instance_for_type<T, A>(inst, holder_ptr);
|
// Need for const_cast is a consequence of the type_info::init_instance type:
|
||||||
|
// void (*init_instance)(instance *, const void *);
|
||||||
|
auto *holder_void_ptr = const_cast<void *>(holder_const_void_ptr);
|
||||||
|
|
||||||
|
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
|
||||||
|
if (!v_h.instance_registered()) {
|
||||||
|
register_instance(inst, v_h.value_ptr(), v_h.type);
|
||||||
|
v_h.set_instance_registered();
|
||||||
|
}
|
||||||
|
auto *uninitialized_location = std::addressof(v_h.holder<holder_type>());
|
||||||
|
auto *value_ptr_w_t = v_h.value_ptr<type>();
|
||||||
|
bool pointee_depends_on_holder_owner
|
||||||
|
= detail::dynamic_raw_ptr_cast_if_possible<type_alias>(value_ptr_w_t) != nullptr;
|
||||||
|
if (holder_void_ptr) {
|
||||||
|
// Note: inst->owned ignored.
|
||||||
|
auto *holder_ptr = static_cast<holder_type *>(holder_void_ptr);
|
||||||
|
new (uninitialized_location) holder_type(std::move(*holder_ptr));
|
||||||
|
} else if (!try_initialization_using_shared_from_this(
|
||||||
|
uninitialized_location, value_ptr_w_t, value_ptr_w_t)) {
|
||||||
|
if (inst->owned) {
|
||||||
|
new (uninitialized_location) holder_type(holder_type::from_raw_ptr_take_ownership(
|
||||||
|
value_ptr_w_t, /*void_cast_raw_ptr*/ pointee_depends_on_holder_owner));
|
||||||
|
} else {
|
||||||
|
new (uninitialized_location)
|
||||||
|
holder_type(holder_type::from_raw_ptr_unowned(value_ptr_w_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v_h.holder<holder_type>().pointee_depends_on_holder_owner
|
||||||
|
= pointee_depends_on_holder_owner;
|
||||||
|
v_h.set_holder_constructed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
|
||||||
|
Loading…
Reference in New Issue
Block a user