@@ -225,6 +225,7 @@ using cast_op_type = typename std::conditional<std::is_pointer<typename std::rem
225
225
typename std::add_pointer<typename intrinsic_type<T>::type>::type,
226
226
typename std::add_lvalue_reference<typename intrinsic_type<T>::type>::type>::type;
227
227
228
+
228
229
// / Generic type caster for objects stored on the heap
229
230
template <typename type> class type_caster_base : public type_caster_generic {
230
231
public:
@@ -247,22 +248,35 @@ template <typename type> class type_caster_base : public type_caster_generic {
247
248
static handle cast (const type *src, return_value_policy policy, handle parent) {
248
249
return type_caster_generic::cast (
249
250
src, policy, parent, src ? &typeid (*src) : nullptr , &typeid (type),
250
- ©_constructor, &move_constructor );
251
+ make_copy_constructor (src), make_move_constructor (src) );
251
252
}
252
253
253
254
template <typename T> using cast_op_type = pybind11::detail::cast_op_type<T>;
254
255
255
256
operator type*() { return (type *) value; }
256
257
operator type&() { return *((type *) value); }
258
+
257
259
protected:
258
- template <typename T = type, typename std::enable_if<detail::is_copy_constructible<T>::value, int >::type = 0 >
259
- static void *copy_constructor (const void *arg) { return (void *) new type (*((const type *) arg)); }
260
- template <typename T = type, typename std::enable_if<!detail::is_copy_constructible<T>::value, int >::type = 0 >
261
- static void *copy_constructor (const void *) { return nullptr ; }
262
- template <typename T = type, typename std::enable_if<detail::is_move_constructible<T>::value, int >::type = 0 >
263
- static void *move_constructor (const void *arg) { return (void *) new type (std::move (*((type *) arg))); }
264
- template <typename T = type, typename std::enable_if<!detail::is_move_constructible<T>::value, int >::type = 0 >
265
- static void *move_constructor (const void *) { return nullptr ; }
260
+ typedef void *(*Constructor)(const void *stream);
261
+ #if !defined(_MSC_VER)
262
+ /* Only enabled when the types are {copy,move}-constructible *and* when the type
263
+ does not have a private operator new implementaton. */
264
+ template <typename T = type> static auto make_copy_constructor (const T *value) -> decltype(new T(*value), Constructor(nullptr )) {
265
+ return [](const void *arg) -> void * { return new T (*((const T *) arg)); }; }
266
+ template <typename T = type> static auto make_move_constructor (const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr )) {
267
+ return [](const void *arg) -> void * { return (void *) new T (std::move (*((T *) arg))); }; }
268
+ #else
269
+ /* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations.
270
+ Use a workaround that only tests for constructibility for now. */
271
+ template <typename T = type, typename = typename std::enable_if<std::is_copy_constructible<T>::value>::type>
272
+ static Constructor make_copy_constructor (const T *value) {
273
+ return [](const void *arg) -> void * { return new T (*((const T *)arg)); }; }
274
+ template <typename T = type, typename = typename std::enable_if<std::is_move_constructible<T>::value>::type>
275
+ static Constructor make_move_constructor (const T *value) {
276
+ return [](const void *arg) -> void * { return (void *) new T (std::move (*((T *)arg))); }; }
277
+ #endif
278
+ static Constructor make_copy_constructor (...) { return nullptr ; }
279
+ static Constructor make_move_constructor (...) { return nullptr ; }
266
280
};
267
281
268
282
template <typename type, typename SFINAE = void > class type_caster : public type_caster_base <type> { };
0 commit comments