mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-26 15:12:01 +00:00
Clean up cast operator invocations (#531)
This adds a `detail::cast_op<T>(caster)` function which handles the rather verbose: caster.operator typename CasterType::template cast_op_type<T>() which allows various places to use the shorter and clearer: cast_op<T>(caster) instead of the full verbose cast operator invocation.
This commit is contained in:
parent
f200493716
commit
db86f7f285
@ -432,6 +432,16 @@ protected:
|
||||
template <typename type, typename SFINAE = void> class type_caster : public type_caster_base<type> { };
|
||||
template <typename type> using make_caster = type_caster<intrinsic_t<type>>;
|
||||
|
||||
// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T
|
||||
template <typename T>
|
||||
auto cast_op(make_caster<T> &caster) -> decltype(caster.operator typename make_caster<T>::template cast_op_type<T>()) {
|
||||
return caster.operator typename make_caster<T>::template cast_op_type<T>();
|
||||
}
|
||||
template <typename T>
|
||||
auto cast_op(make_caster<T> &&caster) -> decltype(caster.operator typename make_caster<T>::template cast_op_type<T>()) {
|
||||
return cast_op<T>(caster);
|
||||
}
|
||||
|
||||
template <typename type> class type_caster<std::reference_wrapper<type>> : public type_caster_base<type> {
|
||||
public:
|
||||
static handle cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {
|
||||
@ -757,8 +767,7 @@ public:
|
||||
template <typename T> using cast_op_type = type;
|
||||
|
||||
operator type() {
|
||||
return type(first.operator typename make_caster<T1>::template cast_op_type<T1>(),
|
||||
second.operator typename make_caster<T2>::template cast_op_type<T2>());
|
||||
return type(cast_op<T1>(first), cast_op<T2>(second));
|
||||
}
|
||||
protected:
|
||||
make_caster<T1> first;
|
||||
@ -831,13 +840,11 @@ public:
|
||||
|
||||
protected:
|
||||
template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
|
||||
return f(std::get<Index>(value)
|
||||
.operator typename make_caster<Tuple>::template cast_op_type<Tuple>()...);
|
||||
return f(cast_op<Tuple>(std::get<Index>(value))...);
|
||||
}
|
||||
|
||||
template <size_t ... Index> type cast(index_sequence<Index...>) {
|
||||
return type(std::get<Index>(value)
|
||||
.operator typename make_caster<Tuple>::template cast_op_type<Tuple>()...);
|
||||
return type(cast_op<Tuple>(std::get<Index>(value))...);
|
||||
}
|
||||
|
||||
template <size_t ... Indices> bool load(handle src, bool convert, index_sequence<Indices...>) {
|
||||
@ -1081,10 +1088,10 @@ NAMESPACE_END(detail)
|
||||
// pytype -> C++ type
|
||||
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
|
||||
T cast(const handle &handle) {
|
||||
static_assert(!detail::cast_is_temporary_value_reference<T>::value,
|
||||
using namespace detail;
|
||||
static_assert(!cast_is_temporary_value_reference<T>::value,
|
||||
"Unable to cast type to reference: value is local to type caster");
|
||||
using type_caster = detail::make_caster<T>;
|
||||
return detail::load_type<T>(handle).operator typename type_caster::template cast_op_type<T>();
|
||||
return cast_op<T>(load_type<T>(handle));
|
||||
}
|
||||
|
||||
// pytype -> pytype (calls converting constructor)
|
||||
@ -1153,7 +1160,7 @@ template <typename ret_type> using overload_caster_t = conditional_t<
|
||||
// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then
|
||||
// store the result in the given variable. For other types, this is a no-op.
|
||||
template <typename T> enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o, make_caster<T> &caster) {
|
||||
return load_type(caster, o).operator typename make_caster<T>::template cast_op_type<T>();
|
||||
return cast_op<T>(load_type(caster, o));
|
||||
}
|
||||
template <typename T> enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&, overload_unused &) {
|
||||
pybind11_fail("Internal error: cast_ref fallback invoked"); }
|
||||
|
@ -53,7 +53,7 @@ template <typename Type, typename Key> struct set_caster {
|
||||
for (auto entry : s) {
|
||||
if (!conv.load(entry, convert))
|
||||
return false;
|
||||
value.insert(conv.operator typename key_conv::template cast_op_type<Key>());
|
||||
value.insert(cast_op<Key>(conv));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -87,9 +87,7 @@ template <typename Type, typename Key, typename Value> struct map_caster {
|
||||
if (!kconv.load(it.first.ptr(), convert) ||
|
||||
!vconv.load(it.second.ptr(), convert))
|
||||
return false;
|
||||
value.emplace(
|
||||
kconv.operator typename key_conv::template cast_op_type<Key>(),
|
||||
vconv.operator typename value_conv::template cast_op_type<Value>());
|
||||
value.emplace(cast_op<Key>(kconv), cast_op<Value>(vconv));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -123,7 +121,7 @@ template <typename Type, typename Value> struct list_caster {
|
||||
for (auto it : s) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value.push_back(conv.operator typename value_conv::template cast_op_type<Value>());
|
||||
value.push_back(cast_op<Value>(conv));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -169,7 +167,7 @@ template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>>
|
||||
for (auto it : l) {
|
||||
if (!conv.load(it, convert))
|
||||
return false;
|
||||
value[ctr++] = conv.operator typename value_conv::template cast_op_type<Type>();
|
||||
value[ctr++] = cast_op<Type>(conv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -221,7 +219,7 @@ template<typename T> struct optional_caster {
|
||||
if (!inner_caster.load(src, convert))
|
||||
return false;
|
||||
|
||||
value.emplace(inner_caster.operator typename value_conv::template cast_op_type<typename T::value_type>());
|
||||
value.emplace(cast_op<typename T::value_type>(inner_caster));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user