diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 91912de7..46d202a8 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -157,7 +157,7 @@ inline void keep_alive_impl(handle nurse, handle patient); class type_caster_generic { public: PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) - : typeinfo(get_type_info(type_info, false)) { } + : typeinfo(get_type_info(type_info, false)), tindex(type_info) { } PYBIND11_NOINLINE bool load(handle src, bool convert) { if (!src) @@ -208,13 +208,21 @@ public: } } - /* Perform an implicit conversion */ + /* Perform an implicit or a direct conversion */ if (convert) { for (auto &converter : typeinfo->implicit_conversions) { temp = object(converter(src.ptr(), typeinfo->type), false); if (load(temp, false)) return true; } + auto& direct = get_internals().direct_conversions; + auto it = direct.find(tindex); + if (it != direct.end()) { + for (auto& converter : it->second) { + if (converter(src.ptr(), value)) + return true; + } + } } return false; } @@ -294,6 +302,7 @@ public: protected: const type_info *typeinfo = nullptr; + std::type_index tindex; void *value = nullptr; object temp; }; diff --git a/include/pybind11/common.h b/include/pybind11/common.h index 40cee870..be4633cc 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -321,6 +321,7 @@ struct internals { std::unordered_map registered_types_py; // PyTypeObject* -> type_info std::unordered_multimap registered_instances; // void * -> PyObject* std::unordered_set, overload_hash> inactive_overload_cache; + std::unordered_map> direct_conversions; std::forward_list registered_exception_translators; #if defined(WITH_THREAD) decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x