diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index b41a0717f..1ac42038d 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -24,8 +24,11 @@ #include #include #include +#include #include #include +#include +#include #include #include @@ -44,8 +47,26 @@ class type_caster_for_class_ : public type_caster_base {}; template class type_caster : public type_caster_for_class_ {}; +inline std::unordered_map &odr_guard_registry() { + static std::unordered_map reg; + return reg; +} + template -struct type_caster_odr_guard : type_caster {}; +struct type_caster_odr_guard : type_caster { + type_caster_odr_guard() { + auto it_ti = std::type_index(typeid(IntrinsicType)); + auto tc_ti = std::type_index(typeid(type_caster)); + auto match = odr_guard_registry().find(it_ti); + if (match == odr_guard_registry().end()) { + odr_guard_registry().insert({it_ti, tc_ti}); + } else if (match->second != tc_ti) { + throw std::system_error(std::make_error_code(std::errc::state_not_recoverable), + "pybind11::detail::type_caster<" + type_id() + + "> ODR VIOLATION DETECTED"); + } + } +}; template using make_caster = type_caster_odr_guard>;