Skip to content

Commit 0d6bceb

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 5cbc400 commit 0d6bceb

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
@@ -832,30 +832,6 @@ template <typename Container> struct is_copy_assignable<Container, enable_if_t<a
832832
template <typename T1, typename T2> struct is_copy_assignable<std::pair<T1, T2>>
833833
: all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};
834834

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

861837
// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed
@@ -898,8 +874,7 @@ struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};
898874
PYBIND11_NAMESPACE_BEGIN(detail)
899875

900876
/// Generic type caster for objects stored on the heap
901-
template <typename type> class type_caster_base : public type_caster_generic,
902-
protected make_constructor {
877+
template <typename type> class type_caster_base : public type_caster_generic {
903878
using itype = intrinsic_t<type>;
904879

905880
public:
@@ -960,6 +935,28 @@ template <typename type> class type_caster_base : public type_caster_generic,
960935

961936
operator itype*() { return (type *) value; }
962937
operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); }
938+
939+
protected:
940+
using Constructor = void *(*)(const void *);
941+
942+
/* Only enabled when the types are {copy,move}-constructible *and* when the type
943+
does not have a private operator new implementation. */
944+
template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
945+
static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) {
946+
return [](const void *arg) -> void * {
947+
return new T(*reinterpret_cast<const T *>(arg));
948+
};
949+
}
950+
951+
template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>
952+
static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast<T *>(x))), Constructor{}) {
953+
return [](const void *arg) -> void * {
954+
return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
955+
};
956+
}
957+
958+
static Constructor make_copy_constructor(...) { return nullptr; }
959+
static Constructor make_move_constructor(...) { return nullptr; }
963960
};
964961

965962
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)