replacing std::any with void_ptr_with_type_info

parent 07ad0446
......@@ -245,7 +245,7 @@ struct type_record {
void *(*operator_new)(size_t) = nullptr;
/// 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
void (*dealloc)(detail::value_and_holder &) = nullptr;
......
......@@ -14,7 +14,6 @@
#include "detail/typeid.h"
#include "detail/descr.h"
#include "detail/internals.h"
#include <any>
#include <array>
#include <limits>
#include <tuple>
......@@ -508,7 +507,7 @@ public:
const detail::type_info *tinfo,
void *(*copy_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
return handle();
......@@ -921,7 +920,7 @@ public:
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);
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
......
......@@ -10,7 +10,6 @@
#pragma once
#include "../pytypes.h"
#include <any>
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)
......@@ -124,6 +123,26 @@ struct internals {
#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.
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
struct type_info {
......@@ -131,7 +150,7 @@ struct type_info {
const std::type_info *cpptype;
size_t type_size, type_align, holder_size_in_ptrs;
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);
std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions;
std::vector<std::pair<const std::type_info *, void *(*)(void *)>> implicit_casts;
......
......@@ -1496,33 +1496,23 @@ private:
/// 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
/// `.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)));
if (!v_h.instance_registered()) {
register_instance(inst, v_h.xxx_value_ptr<void>(), v_h.type); // before init_holder
v_h.set_instance_registered();
}
const holder_type *holder_ptr_raw = nullptr;
if (holder_ptr.has_value() && std::any_cast<std::nullptr_t>(&holder_ptr) == nullptr) {
detail::to_cout("before any_cast");
std::string htn(holder_ptr.type().name());
detail::clean_type_id(htn);
detail::to_cout(std::string("holder_ptr.type().name() ") + htn);
detail::to_cout(std::string(" typeid(holder_type *) ") + type_id<holder_type *>());
auto cast_ptr_mutbl = std::any_cast<holder_type *>(&holder_ptr);
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;
if (holder_ptr.ptr != nullptr) {
std::string existing_hptn(holder_ptr.type_info_name_non_const);
detail::clean_type_id(existing_hptn);
std::string instance_hptn = type_id<holder_type *>();
detail::to_cout(std::string("holder_ptr.type_info_name ") + existing_hptn);
detail::to_cout(std::string(" typeid(holder_type *) ") + instance_hptn);
if (existing_hptn != instance_hptn) {
detail::to_cout(std::string("HOLDER_MISMATCH # ") + existing_hptn + " # " + instance_hptn);
}
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.
......
......@@ -33,6 +33,5 @@ def test_virtual():
vb = m.make_shared_vderived_up_cast()
assert vb.get_int() == VDERIVED_GET_INT_RESULT
m.pass_shared_vbase(vb)
with pytest.raises(TypeError):
m.pass_shared_vderived(vb)
m.pass_shared_vderived(vb)
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