You need to sign in or sign up before continuing.

replacing std::any with void_ptr_with_type_info

parent 07ad0446
...@@ -245,7 +245,7 @@ struct type_record { ...@@ -245,7 +245,7 @@ struct type_record {
void *(*operator_new)(size_t) = nullptr; void *(*operator_new)(size_t) = nullptr;
/// Function pointer to class_<..>::init_instance /// Function pointer to class_<..>::init_instance
void (*init_instance)(instance *, std::any) = nullptr; void (*init_instance)(instance *, void_ptr_with_type_info) = nullptr;
/// Function pointer to class_<..>::dealloc /// Function pointer to class_<..>::dealloc
void (*dealloc)(detail::value_and_holder &) = nullptr; void (*dealloc)(detail::value_and_holder &) = nullptr;
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "detail/typeid.h" #include "detail/typeid.h"
#include "detail/descr.h" #include "detail/descr.h"
#include "detail/internals.h" #include "detail/internals.h"
#include <any>
#include <array> #include <array>
#include <limits> #include <limits>
#include <tuple> #include <tuple>
...@@ -508,7 +507,7 @@ public: ...@@ -508,7 +507,7 @@ public:
const detail::type_info *tinfo, const detail::type_info *tinfo,
void *(*copy_constructor)(const void *), void *(*copy_constructor)(const void *),
void *(*move_constructor)(const void *), void *(*move_constructor)(const void *),
std::any existing_holder = std::any{}) { void_ptr_with_type_info existing_holder = void_ptr_with_type_info{}) {
if (!tinfo) // no type info: error will be set already if (!tinfo) // no type info: error will be set already
return handle(); return handle();
...@@ -921,7 +920,7 @@ public: ...@@ -921,7 +920,7 @@ public:
make_copy_constructor(src), make_move_constructor(src)); make_copy_constructor(src), make_move_constructor(src));
} }
static handle cast_holder(const itype *src, std::any holder) { static handle cast_holder(const itype *src, void_ptr_with_type_info holder) {
auto st = src_and_type(src); auto st = src_and_type(src);
return type_caster_generic::cast( // HOLDER_SHARED_MAKE_UNIQUE STACK #5 return type_caster_generic::cast( // HOLDER_SHARED_MAKE_UNIQUE STACK #5
st.first, return_value_policy::take_ownership, {}, st.second, // tinfo=st.second TODODODO return_value_policy::existing_holder st.first, return_value_policy::take_ownership, {}, st.second, // tinfo=st.second TODODODO return_value_policy::existing_holder
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#pragma once #pragma once
#include "../pytypes.h" #include "../pytypes.h"
#include <any>
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
...@@ -124,6 +123,26 @@ struct internals { ...@@ -124,6 +123,26 @@ struct internals {
#endif #endif
}; };
struct void_ptr_with_type_info {
const void *ptr;
std::string type_info_name_non_const;
std::string type_info_name_orig;
void_ptr_with_type_info()
: ptr{nullptr},
type_info_name_non_const{typeid(std::nullptr_t).name()},
type_info_name_orig{typeid(std::nullptr_t).name()} {}
template <typename T>
void_ptr_with_type_info(T orig_ptr)
: ptr{orig_ptr},
type_info_name_non_const{
typeid(typename std::add_pointer<typename std::remove_cv<
typename std::remove_pointer<T>::type>::type>::type)
.name()},
type_info_name_orig{typeid(T).name()} {}
};
/// Additional type information which does not fit into the PyTypeObject. /// Additional type information which does not fit into the PyTypeObject.
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`. /// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
struct type_info { struct type_info {
...@@ -131,7 +150,7 @@ struct type_info { ...@@ -131,7 +150,7 @@ struct type_info {
const std::type_info *cpptype; const std::type_info *cpptype;
size_t type_size, type_align, holder_size_in_ptrs; size_t type_size, type_align, holder_size_in_ptrs;
void *(*operator_new)(size_t); void *(*operator_new)(size_t);
void (*init_instance)(instance *, std::any); void (*init_instance)(instance *, void_ptr_with_type_info);
void (*dealloc)(value_and_holder &v_h); void (*dealloc)(value_and_holder &v_h);
std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions; std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions;
std::vector<std::pair<const std::type_info *, void *(*)(void *)>> implicit_casts; std::vector<std::pair<const std::type_info *, void *(*)(void *)>> implicit_casts;
......
...@@ -1496,33 +1496,23 @@ private: ...@@ -1496,33 +1496,23 @@ private:
/// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes an /// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes an
/// optional pointer to an existing holder to use; if not specified and the instance is /// optional pointer to an existing holder to use; if not specified and the instance is
/// `.aaa_owned`, a new holder will be constructed to manage the value pointer. /// `.aaa_owned`, a new holder will be constructed to manage the value pointer.
static void init_instance(detail::instance *inst, std::any holder_ptr) { // TODODODO std::any static void init_instance(detail::instance *inst, detail::void_ptr_with_type_info holder_ptr) {
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type))); auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
if (!v_h.instance_registered()) { if (!v_h.instance_registered()) {
register_instance(inst, v_h.xxx_value_ptr<void>(), v_h.type); // before init_holder register_instance(inst, v_h.xxx_value_ptr<void>(), v_h.type); // before init_holder
v_h.set_instance_registered(); v_h.set_instance_registered();
} }
const holder_type *holder_ptr_raw = nullptr; if (holder_ptr.ptr != nullptr) {
if (holder_ptr.has_value() && std::any_cast<std::nullptr_t>(&holder_ptr) == nullptr) { std::string existing_hptn(holder_ptr.type_info_name_non_const);
detail::to_cout("before any_cast"); detail::clean_type_id(existing_hptn);
std::string htn(holder_ptr.type().name()); std::string instance_hptn = type_id<holder_type *>();
detail::clean_type_id(htn); detail::to_cout(std::string("holder_ptr.type_info_name ") + existing_hptn);
detail::to_cout(std::string("holder_ptr.type().name() ") + htn); detail::to_cout(std::string(" typeid(holder_type *) ") + instance_hptn);
detail::to_cout(std::string(" typeid(holder_type *) ") + type_id<holder_type *>()); if (existing_hptn != instance_hptn) {
auto cast_ptr_mutbl = std::any_cast<holder_type *>(&holder_ptr); detail::to_cout(std::string("HOLDER_MISMATCH # ") + existing_hptn + " # " + instance_hptn);
if (cast_ptr_mutbl != nullptr) {
holder_ptr_raw = *cast_ptr_mutbl;
} else {
auto cast_ptr_const = std::any_cast<const holder_type *>(&holder_ptr);
if (cast_ptr_const == nullptr) {
detail::to_cout("any_cast mutbl + const failure");
throw std::runtime_error("Incompatible holder types.");
}
holder_ptr_raw = *cast_ptr_const;
} }
detail::to_cout("after any_cast");
} }
init_holder(inst, v_h, holder_ptr_raw, v_h.xxx_value_ptr<type>()); // calling init_holder // HOLDER_SHARED_MAKE_UNIQUE STACK #3 init_holder(inst, v_h, (const holder_type *) holder_ptr.ptr, v_h.xxx_value_ptr<type>()); // calling init_holder // HOLDER_SHARED_MAKE_UNIQUE STACK #3
} }
/// Deallocates an instance; via holder, if constructed; otherwise via operator delete. /// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
......
...@@ -33,6 +33,5 @@ def test_virtual(): ...@@ -33,6 +33,5 @@ def test_virtual():
vb = m.make_shared_vderived_up_cast() vb = m.make_shared_vderived_up_cast()
assert vb.get_int() == VDERIVED_GET_INT_RESULT assert vb.get_int() == VDERIVED_GET_INT_RESULT
m.pass_shared_vbase(vb) m.pass_shared_vbase(vb)
with pytest.raises(TypeError): m.pass_shared_vderived(vb)
m.pass_shared_vderived(vb)
m.to_cout("") m.to_cout("")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment