diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index d2869264c3..8c2f886fbb 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -816,6 +816,30 @@ template struct is_copy_assignable struct is_copy_assignable> : all_of, is_copy_assignable> {}; +// Helper for type_caster_base. +struct make_constructor { + using Constructor = void *(*)(const void *); + + /* Only enabled when the types are {copy,move}-constructible *and* when the type + does not have a private operator new implementation. */ + template ::value>> + static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) { + return [](const void *arg) -> void * { + return new T(*reinterpret_cast(arg)); + }; + } + + template ::value>> + static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast(x))), Constructor{}) { + return [](const void *arg) -> void * { + return new T(std::move(*const_cast(reinterpret_cast(arg)))); + }; + } + + static Constructor make_copy_constructor(...) { return nullptr; } + static Constructor make_move_constructor(...) { return nullptr; } +}; + PYBIND11_NAMESPACE_END(detail) // polymorphic_type_hook::get(src, tinfo) determines whether the object pointed @@ -905,7 +929,8 @@ template class type_caster_base : public type_caster_generic { auto st = src_and_type(src); return type_caster_generic::cast( st.first, policy, parent, st.second, - make_copy_constructor(src), make_move_constructor(src)); + make_constructor::make_copy_constructor(src), + make_constructor::make_move_constructor(src)); } static handle cast_holder(const itype *src, const void *holder) { @@ -919,28 +944,6 @@ template class type_caster_base : public type_caster_generic { operator itype*() { return (type *) value; } operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); } - -protected: - using Constructor = void *(*)(const void *); - - /* Only enabled when the types are {copy,move}-constructible *and* when the type - does not have a private operator new implementation. */ - template ::value>> - static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) { - return [](const void *arg) -> void * { - return new T(*reinterpret_cast(arg)); - }; - } - - template ::value>> - static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast(x))), Constructor{}) { - return [](const void *arg) -> void * { - return new T(std::move(*const_cast(reinterpret_cast(arg)))); - }; - } - - static Constructor make_copy_constructor(...) { return nullptr; } - static Constructor make_move_constructor(...) { return nullptr; } }; template class type_caster : public type_caster_base { };