Allows users to specialize polymorphic_type_hook with std::enable_if.

Currently user specializations of the form

template <typename itype> struct polymorphic_type_hook<itype, std::enable_if_t<...>> { ... };

will fail if itype is also polymorphic, because the existing specialization will also
be enabled, which leads to 2 equally viable candidates. With this change, user provided
specializations have higher priority than the built in specialization for polymorphic types.
This commit is contained in:
Ralf W. Grosse-Kunstleve 2019-12-04 15:03:22 -08:00 committed by Wenzel Jakob
parent 0234871649
commit 4697149d19

View File

@ -835,19 +835,25 @@ NAMESPACE_END(detail)
// You may specialize polymorphic_type_hook yourself for types that want to appear
// polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern
// in performance-sensitive applications, used most notably in LLVM.)
//
// polymorphic_type_hook_base allows users to specialize polymorphic_type_hook with
// std::enable_if. User provided specializations will always have higher priority than
// the default implementation and specialization provided in polymorphic_type_hook_base.
template <typename itype, typename SFINAE = void>
struct polymorphic_type_hook
struct polymorphic_type_hook_base
{
static const void *get(const itype *src, const std::type_info*&) { return src; }
};
template <typename itype>
struct polymorphic_type_hook<itype, detail::enable_if_t<std::is_polymorphic<itype>::value>>
struct polymorphic_type_hook_base<itype, detail::enable_if_t<std::is_polymorphic<itype>::value>>
{
static const void *get(const itype *src, const std::type_info*& type) {
type = src ? &typeid(*src) : nullptr;
return dynamic_cast<const void*>(src);
}
};
template <typename itype, typename SFINAE = void>
struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};
NAMESPACE_BEGIN(detail)