Skip to content

Commit abe4f97

Browse files
committed
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 pybind#2798 for background.
1 parent 707940e commit abe4f97

File tree

2 files changed

+51
-26
lines changed

2 files changed

+51
-26
lines changed

include/pybind11/cast.h

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -824,30 +824,6 @@ template <typename Container> struct is_copy_assignable<Container, enable_if_t<a
824824
template <typename T1, typename T2> struct is_copy_assignable<std::pair<T1, T2>>
825825
: all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};
826826

827-
// Helper for type_caster_base.
828-
struct make_constructor {
829-
using Constructor = void *(*)(const void *);
830-
831-
/* Only enabled when the types are {copy,move}-constructible *and* when the type
832-
does not have a private operator new implementation. */
833-
template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
834-
static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) {
835-
return [](const void *arg) -> void * {
836-
return new T(*reinterpret_cast<const T *>(arg));
837-
};
838-
}
839-
840-
template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>
841-
static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast<T *>(x))), Constructor{}) {
842-
return [](const void *arg) -> void * {
843-
return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
844-
};
845-
}
846-
847-
static Constructor make_copy_constructor(...) { return nullptr; }
848-
static Constructor make_move_constructor(...) { return nullptr; }
849-
};
850-
851827
PYBIND11_NAMESPACE_END(detail)
852828

853829
// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed
@@ -890,8 +866,7 @@ struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};
890866
PYBIND11_NAMESPACE_BEGIN(detail)
891867

892868
/// Generic type caster for objects stored on the heap
893-
template <typename type> class type_caster_base : public type_caster_generic,
894-
protected make_constructor {
869+
template <typename type> class type_caster_base : public type_caster_generic {
895870
using itype = intrinsic_t<type>;
896871

897872
public:
@@ -952,6 +927,28 @@ template <typename type> class type_caster_base : public type_caster_generic,
952927

953928
operator itype*() { return (type *) value; }
954929
operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); }
930+
931+
protected:
932+
using Constructor = void *(*)(const void *);
933+
934+
/* Only enabled when the types are {copy,move}-constructible *and* when the type
935+
does not have a private operator new implementation. */
936+
template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
937+
static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) {
938+
return [](const void *arg) -> void * {
939+
return new T(*reinterpret_cast<const T *>(arg));
940+
};
941+
}
942+
943+
template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>
944+
static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast<T *>(x))), Constructor{}) {
945+
return [](const void *arg) -> void * {
946+
return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
947+
};
948+
}
949+
950+
static Constructor make_copy_constructor(...) { return nullptr; }
951+
static Constructor make_move_constructor(...) { return nullptr; }
955952
};
956953

957954
template <typename type, typename SFINAE = void> class type_caster : public type_caster_base<type> { };

tests/test_classh_wip.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,34 @@ struct smart_holder_type_caster_load {
102102
holder_type *loaded_smhldr_ptr = nullptr;
103103
};
104104

105+
// type_caster_base BEGIN
106+
// clang-format off
107+
// Helper factored out of type_caster_base.
108+
struct make_constructor {
109+
using Constructor = void *(*)(const void *);
110+
111+
/* Only enabled when the types are {copy,move}-constructible *and* when the type
112+
does not have a private operator new implementation. */
113+
template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
114+
static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) {
115+
return [](const void *arg) -> void * {
116+
return new T(*reinterpret_cast<const T *>(arg));
117+
};
118+
}
119+
120+
template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>
121+
static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast<T *>(x))), Constructor{}) {
122+
return [](const void *arg) -> void * {
123+
return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
124+
};
125+
}
126+
127+
static Constructor make_copy_constructor(...) { return nullptr; }
128+
static Constructor make_move_constructor(...) { return nullptr; }
129+
};
130+
// clang-format on
131+
// type_caster_base END
132+
105133
template <>
106134
struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
107135
static constexpr auto name = _<mpty>();

0 commit comments

Comments
 (0)