Add support for "direct" converters

This commit is contained in:
Ivan Smirnov 2016-10-20 16:09:31 +01:00
parent ba08db4da5
commit c275ee6b46
2 changed files with 12 additions and 2 deletions

View File

@ -157,7 +157,7 @@ inline void keep_alive_impl(handle nurse, handle patient);
class type_caster_generic { class type_caster_generic {
public: public:
PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) 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) { PYBIND11_NOINLINE bool load(handle src, bool convert) {
if (!src) if (!src)
@ -208,13 +208,21 @@ public:
} }
} }
/* Perform an implicit conversion */ /* Perform an implicit or a direct conversion */
if (convert) { if (convert) {
for (auto &converter : typeinfo->implicit_conversions) { for (auto &converter : typeinfo->implicit_conversions) {
temp = object(converter(src.ptr(), typeinfo->type), false); temp = object(converter(src.ptr(), typeinfo->type), false);
if (load(temp, false)) if (load(temp, false))
return true; 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; return false;
} }
@ -294,6 +302,7 @@ public:
protected: protected:
const type_info *typeinfo = nullptr; const type_info *typeinfo = nullptr;
std::type_index tindex;
void *value = nullptr; void *value = nullptr;
object temp; object temp;
}; };

View File

@ -321,6 +321,7 @@ struct internals {
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_multimap<const void *, void*> registered_instances; // void * -> PyObject* std::unordered_multimap<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;
std::unordered_map<std::type_index, std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators; std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators;
#if defined(WITH_THREAD) #if defined(WITH_THREAD)
decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x