Skip to content

Commit 21e461d

Browse files
committed
Using factored-out make_constructor (PR pybind#2798), removing duplicate code.
1 parent 39c4d3a commit 21e461d

File tree

2 files changed

+28
-52
lines changed

2 files changed

+28
-52
lines changed

include/pybind11/cast.h

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,30 @@ 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+
827851
PYBIND11_NAMESPACE_END(detail)
828852

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

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

872897
public:
@@ -927,28 +952,6 @@ template <typename type> class type_caster_base : public type_caster_generic {
927952

928953
operator itype*() { return (type *) value; }
929954
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; }
952955
};
953956

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

tests/test_classh_wip.cpp

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
123123
policy,
124124
parent,
125125
st.second,
126-
make_copy_constructor(src),
127-
make_move_constructor(src));
126+
make_constructor::make_copy_constructor(src),
127+
make_constructor::make_move_constructor(src));
128128
}
129129

130130
static handle cast(mpty *src, return_value_policy policy, handle parent) {
@@ -156,33 +156,6 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
156156

157157
// clang-format on
158158

159-
// type_caster_base BEGIN
160-
// clang-format off
161-
162-
using Constructor = void *(*)(const void *);
163-
164-
/* Only enabled when the types are {copy,move}-constructible *and* when the type
165-
does not have a private operator new implementation. */
166-
template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>
167-
static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) {
168-
return [](const void *arg) -> void * {
169-
return new T(*reinterpret_cast<const T *>(arg));
170-
};
171-
}
172-
173-
template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>
174-
static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast<T *>(x))), Constructor{}) {
175-
return [](const void *arg) -> void * {
176-
return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));
177-
};
178-
}
179-
180-
static Constructor make_copy_constructor(...) { return nullptr; }
181-
static Constructor make_move_constructor(...) { return nullptr; }
182-
183-
// clang-format on
184-
// type_caster_base END
185-
186159
// Originally type_caster_generic::cast.
187160
PYBIND11_NOINLINE static handle cast_const_raw_ptr(const void *_src,
188161
return_value_policy policy,

0 commit comments

Comments
 (0)