mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-16 21:57:55 +00:00
address issue with std::type_info across module boundaries (fixes #86)
This commit is contained in:
parent
2547ca468c
commit
b6cf75d66a
@ -59,20 +59,9 @@ PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
|
|||||||
PYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_info &tp) {
|
PYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_info &tp) {
|
||||||
auto &types = get_internals().registered_types_cpp;
|
auto &types = get_internals().registered_types_cpp;
|
||||||
|
|
||||||
auto it = types.find(&tp);
|
auto it = types.find(std::type_index(tp));
|
||||||
if (it != types.end()) {
|
if (it != types.end())
|
||||||
return (detail::type_info *) it->second;
|
return (detail::type_info *) it->second;
|
||||||
} else {
|
|
||||||
/* Unknown type?! Since std::type_info* often varies across
|
|
||||||
module boundaries, the following does an explicit check */
|
|
||||||
for (auto const &type : types) {
|
|
||||||
auto *first = (const std::type_info *) type.first;
|
|
||||||
if (strcmp(first->name(), tp.name()) == 0) {
|
|
||||||
types[&tp] = type.second;
|
|
||||||
return (detail::type_info *) type.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +133,7 @@ public:
|
|||||||
if (it_instance != internals.registered_instances.end() && !dont_cache)
|
if (it_instance != internals.registered_instances.end() && !dont_cache)
|
||||||
return handle((PyObject *) it_instance->second).inc_ref();
|
return handle((PyObject *) it_instance->second).inc_ref();
|
||||||
|
|
||||||
auto it = internals.registered_types_cpp.find(type_info);
|
auto it = internals.registered_types_cpp.find(std::type_index(*type_info));
|
||||||
if (it == internals.registered_types_cpp.end()) {
|
if (it == internals.registered_types_cpp.end()) {
|
||||||
std::string tname = type_info->name();
|
std::string tname = type_info->name();
|
||||||
detail::clean_type_id(tname);
|
detail::clean_type_id(tname);
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
|
#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
|
||||||
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
|
#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)
|
||||||
@ -216,9 +217,9 @@ struct overload_hash {
|
|||||||
|
|
||||||
/// Internal data struture used to track registered instances and types
|
/// Internal data struture used to track registered instances and types
|
||||||
struct internals {
|
struct internals {
|
||||||
std::unordered_map<const void *, void*> registered_types_cpp; // std::type_info* -> type_info
|
std::unordered_map<std::type_index, void*> registered_types_cpp; // std::type_index -> type_info
|
||||||
std::unordered_map<const void *, void*> registered_types_py; // PyTypeObject* -> type_info
|
std::unordered_map<const void *, void*> registered_types_py; // PyTypeObject* -> type_info
|
||||||
std::unordered_map<const void *, void*> registered_instances; // void * -> PyObject*
|
std::unordered_map<const void *, void*> registered_instances; // void * -> PyObject*
|
||||||
std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache;
|
std::unordered_set<std::pair<const PyObject *, const char *>, overload_hash> inactive_overload_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ protected:
|
|||||||
const std::type_info *t = types[type_index++];
|
const std::type_info *t = types[type_index++];
|
||||||
if (!t)
|
if (!t)
|
||||||
pybind11_fail("Internal error while parsing type signature (1)");
|
pybind11_fail("Internal error while parsing type signature (1)");
|
||||||
auto it = registered_types.find(t);
|
auto it = registered_types.find(std::type_index(*t));
|
||||||
if (it != registered_types.end()) {
|
if (it != registered_types.end()) {
|
||||||
signature += ((const detail::type_info *) it->second)->type->tp_name;
|
signature += ((const detail::type_info *) it->second)->type->tp_name;
|
||||||
} else {
|
} else {
|
||||||
@ -524,7 +524,7 @@ protected:
|
|||||||
tinfo->type = (PyTypeObject *) type;
|
tinfo->type = (PyTypeObject *) type;
|
||||||
tinfo->type_size = rec->type_size;
|
tinfo->type_size = rec->type_size;
|
||||||
tinfo->init_holder = rec->init_holder;
|
tinfo->init_holder = rec->init_holder;
|
||||||
internals.registered_types_cpp[rec->type] = tinfo;
|
internals.registered_types_cpp[std::type_index(*(rec->type))] = tinfo;
|
||||||
internals.registered_types_py[type] = tinfo;
|
internals.registered_types_py[type] = tinfo;
|
||||||
|
|
||||||
auto scope_module = (object) rec->scope.attr("__module__");
|
auto scope_module = (object) rec->scope.attr("__module__");
|
||||||
@ -844,7 +844,7 @@ public:
|
|||||||
|
|
||||||
template <typename target> class_ alias() {
|
template <typename target> class_ alias() {
|
||||||
auto &instances = pybind11::detail::get_internals().registered_types_cpp;
|
auto &instances = pybind11::detail::get_internals().registered_types_cpp;
|
||||||
instances[&typeid(target)] = instances[&typeid(type)];
|
instances[std::type_index(typeid(target))] = instances[std::type_index(typeid(type))];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@ -976,8 +976,8 @@ template <typename InputType, typename OutputType> void implicitly_convertible()
|
|||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
auto & registered_types = detail::get_internals().registered_types_cpp;
|
auto ®istered_types = detail::get_internals().registered_types_cpp;
|
||||||
auto it = registered_types.find(&typeid(OutputType));
|
auto it = registered_types.find(std::type_index(typeid(OutputType)));
|
||||||
if (it == registered_types.end())
|
if (it == registered_types.end())
|
||||||
pybind11_fail("implicitly_convertible: Unable to find type " + type_id<OutputType>());
|
pybind11_fail("implicitly_convertible: Unable to find type " + type_id<OutputType>());
|
||||||
((detail::type_info *) it->second)->implicit_conversions.push_back(implicit_caster);
|
((detail::type_info *) it->second)->implicit_conversions.push_back(implicit_caster);
|
||||||
|
Loading…
Reference in New Issue
Block a user