diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index f36b3d5a..13e99c41 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -504,12 +504,23 @@ public: } protected: + template /* Used to select the right casting operator in the two functions below */ + using cast_target = + typename std::conditional< + is_tuple::type>::value, /* special case: tuple/pair -> pass by value */ + typename intrinsic_type::type, + typename std::conditional< + std::is_pointer::value, + typename std::add_pointer::type>::type, /* pass using pointer */ + typename std::add_lvalue_reference::type>::type /* pass using reference */ + >::type>; + template ReturnValue call(Func &&f, index_sequence) { - return f((Tuple) std::get(value)...); + return f(std::get(value).operator typename cast_target::type()...); } template type cast(index_sequence) { - return type((Tuple) std::get(value)...); + return type(std::get(value).operator typename cast_target::type()...); } template bool load(handle src, bool convert, index_sequence) { diff --git a/include/pybind11/common.h b/include/pybind11/common.h index 3cefa93a..7a586563 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -257,6 +257,11 @@ template struct is_copy_constructible { static const bool value = std::is_same(nullptr))>::value; }; +/// Helper type determine if another type is a variant of a pair/tuple +template struct is_tuple : std::false_type { }; +template struct is_tuple > : std::true_type { }; +template struct is_tuple > : std::true_type { }; + /// Helper type to replace 'void' in some expressions struct void_type { };