mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 21:25:13 +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, typename SFINAE = void> class type_caster : public type_caster_base<type> { };
|
||||||
template <typename type> using make_caster = type_caster<intrinsic_t<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> {
|
template <typename type> class type_caster<std::reference_wrapper<type>> : public type_caster_base<type> {
|
||||||
public:
|
public:
|
||||||
static handle cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {
|
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;
|
template <typename T> using cast_op_type = type;
|
||||||
|
|
||||||
operator type() {
|
operator type() {
|
||||||
return type(first.operator typename make_caster<T1>::template cast_op_type<T1>(),
|
return type(cast_op<T1>(first), cast_op<T2>(second));
|
||||||
second.operator typename make_caster<T2>::template cast_op_type<T2>());
|
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
make_caster<T1> first;
|
make_caster<T1> first;
|
||||||
@ -831,13 +840,11 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
|
template <typename ReturnValue, typename Func, size_t ... Index> ReturnValue call(Func &&f, index_sequence<Index...>) {
|
||||||
return f(std::get<Index>(value)
|
return f(cast_op<Tuple>(std::get<Index>(value))...);
|
||||||
.operator typename make_caster<Tuple>::template cast_op_type<Tuple>()...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t ... Index> type cast(index_sequence<Index...>) {
|
template <size_t ... Index> type cast(index_sequence<Index...>) {
|
||||||
return type(std::get<Index>(value)
|
return type(cast_op<Tuple>(std::get<Index>(value))...);
|
||||||
.operator typename make_caster<Tuple>::template cast_op_type<Tuple>()...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t ... Indices> bool load(handle src, bool convert, index_sequence<Indices...>) {
|
template <size_t ... Indices> bool load(handle src, bool convert, index_sequence<Indices...>) {
|
||||||
@ -1081,10 +1088,10 @@ NAMESPACE_END(detail)
|
|||||||
// pytype -> C++ type
|
// pytype -> C++ type
|
||||||
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
|
template <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>
|
||||||
T cast(const handle &handle) {
|
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");
|
"Unable to cast type to reference: value is local to type caster");
|
||||||
using type_caster = detail::make_caster<T>;
|
return cast_op<T>(load_type<T>(handle));
|
||||||
return detail::load_type<T>(handle).operator typename type_caster::template cast_op_type<T>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pytype -> pytype (calls converting constructor)
|
// 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
|
// 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.
|
// 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) {
|
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 &) {
|
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"); }
|
pybind11_fail("Internal error: cast_ref fallback invoked"); }
|
||||||
|
@ -53,7 +53,7 @@ template <typename Type, typename Key> struct set_caster {
|
|||||||
for (auto entry : s) {
|
for (auto entry : s) {
|
||||||
if (!conv.load(entry, convert))
|
if (!conv.load(entry, convert))
|
||||||
return false;
|
return false;
|
||||||
value.insert(conv.operator typename key_conv::template cast_op_type<Key>());
|
value.insert(cast_op<Key>(conv));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -87,9 +87,7 @@ template <typename Type, typename Key, typename Value> struct map_caster {
|
|||||||
if (!kconv.load(it.first.ptr(), convert) ||
|
if (!kconv.load(it.first.ptr(), convert) ||
|
||||||
!vconv.load(it.second.ptr(), convert))
|
!vconv.load(it.second.ptr(), convert))
|
||||||
return false;
|
return false;
|
||||||
value.emplace(
|
value.emplace(cast_op<Key>(kconv), cast_op<Value>(vconv));
|
||||||
kconv.operator typename key_conv::template cast_op_type<Key>(),
|
|
||||||
vconv.operator typename value_conv::template cast_op_type<Value>());
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -123,7 +121,7 @@ template <typename Type, typename Value> struct list_caster {
|
|||||||
for (auto it : s) {
|
for (auto it : s) {
|
||||||
if (!conv.load(it, convert))
|
if (!conv.load(it, convert))
|
||||||
return false;
|
return false;
|
||||||
value.push_back(conv.operator typename value_conv::template cast_op_type<Value>());
|
value.push_back(cast_op<Value>(conv));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -169,7 +167,7 @@ template <typename Type, size_t Size> struct type_caster<std::array<Type, Size>>
|
|||||||
for (auto it : l) {
|
for (auto it : l) {
|
||||||
if (!conv.load(it, convert))
|
if (!conv.load(it, convert))
|
||||||
return false;
|
return false;
|
||||||
value[ctr++] = conv.operator typename value_conv::template cast_op_type<Type>();
|
value[ctr++] = cast_op<Type>(conv);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -221,7 +219,7 @@ template<typename T> struct optional_caster {
|
|||||||
if (!inner_caster.load(src, convert))
|
if (!inner_caster.load(src, convert))
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user