From 2a7d41c193fe4aa978788b68a3e3522680349ce4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 17 Jan 2021 10:29:56 -0800 Subject: [PATCH] Moving factored-out make_constructor to test_classh_wip.cpp, restoring previous version of cast.h. This is currently the most practical approach. See PR #2798 for background. --- include/pybind11/cast.h | 49 ++++++++++++++++++--------------------- tests/test_classh_wip.cpp | 28 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 5867309f0..6effa1bc0 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -824,30 +824,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 @@ -890,8 +866,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: @@ -952,6 +927,28 @@ public: 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 14913dca0..62e0b5d95 100644 --- a/tests/test_classh_wip.cpp +++ b/tests/test_classh_wip.cpp @@ -102,6 +102,34 @@ protected: 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 = _();