Skip to content

Commit a837940

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 06f9900 commit a837940

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
@@ -816,30 +816,6 @@ template <typename Container> struct is_copy_assignable<Container, enable_if_t<a
816816
template <typename T1, typename T2> struct is_copy_assignable<std::pair<T1, T2>>
817817
: all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};
818818

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

845821
// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed
@@ -882,8 +858,7 @@ struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};
882858
PYBIND11_NAMESPACE_BEGIN(detail)
883859

884860
/// Generic type caster for objects stored on the heap
885-
template <typename type> class type_caster_base : public type_caster_generic,
886-
protected make_constructor {
861+
template <typename type> class type_caster_base : public type_caster_generic {
887862
using itype = intrinsic_t<type>;
888863

889864
public:
@@ -944,6 +919,28 @@ template <typename type> class type_caster_base : public type_caster_generic,
944919

945920
operator itype*() { return (type *) value; }
946921
operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); }
922+
923+
protected:
924+
using Constructor = void *(*)(const void *);
925+
926+
/* Only enabled when the types are {copy,move}-constructible *and* when the type
927+
does not have a private operator new implementation. */
928+
template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
929+
static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) {
930+
return [](const void *arg) -> void * {
931+
return new T(*reinterpret_cast<const T *>(arg));
932+
};
933+
}
934+
935+
template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>
936+
static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast<T *>(x))), Constructor{}) {
937+
return [](const void *arg) -> void * {
938+
return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
939+
};
940+
}
941+
942+
static Constructor make_copy_constructor(...) { return nullptr; }
943+
static Constructor make_move_constructor(...) { return nullptr; }
947944
};
948945

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