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