diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 2be26ad7ec9..1778673ea2a 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 @@ -858,7 +882,8 @@ 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 { +template class type_caster_base : public type_caster_generic, + protected make_constructor { using itype = intrinsic_t; public: @@ -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 { }; diff --git a/tests/test_classh_wip.cpp b/tests/test_classh_wip.cpp index b5a9274fb57..e663df0558d 100644 --- a/tests/test_classh_wip.cpp +++ b/tests/test_classh_wip.cpp @@ -123,8 +123,8 @@ struct type_caster : smart_holder_type_caster_load { 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(mpty *src, return_value_policy policy, handle parent) { @@ -156,33 +156,6 @@ struct type_caster : smart_holder_type_caster_load { // clang-format on - // type_caster_base BEGIN - // clang-format off - - 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 - // Originally type_caster_generic::cast. PYBIND11_NOINLINE static handle cast_const_raw_ptr(const void *_src, return_value_policy policy,