diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 33f374192e6..c5b4132ae7c 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -816,30 +816,6 @@ 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 @@ -882,8 +858,7 @@ struct polymorphic_type_hook : public polymorphic_type_hook_base {}; PYBIND11_NAMESPACE_BEGIN(detail) /// Generic type caster for objects stored on the heap -template class type_caster_base : public type_caster_generic, - protected make_constructor { +template class type_caster_base : public type_caster_generic { using itype = intrinsic_t; public: @@ -944,6 +919,28 @@ 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 { }; diff --git a/tests/test_classh_wip.cpp b/tests/test_classh_wip.cpp index 14913dca0a8..62e0b5d9534 100644 --- a/tests/test_classh_wip.cpp +++ b/tests/test_classh_wip.cpp @@ -102,6 +102,34 @@ struct smart_holder_type_caster_load { holder_type *loaded_smhldr_ptr = nullptr; }; +// type_caster_base BEGIN +// clang-format off +// Helper factored out of 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; } +}; +// clang-format on +// type_caster_base END + template <> struct type_caster : smart_holder_type_caster_load { static constexpr auto name = _();