From db86f7f2859398f20180968ba8789595a581338a Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 25 Nov 2016 12:35:00 -0500 Subject: [PATCH] Clean up cast operator invocations (#531) This adds a `detail::cast_op(caster)` function which handles the rather verbose: caster.operator typename CasterType::template cast_op_type() which allows various places to use the shorter and clearer: cast_op(caster) instead of the full verbose cast operator invocation. --- include/pybind11/cast.h | 27 +++++++++++++++++---------- include/pybind11/stl.h | 12 +++++------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 862f40338..b1dc3f4af 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -432,6 +432,16 @@ protected: template class type_caster : public type_caster_base { }; template using make_caster = type_caster>; +// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T +template +auto cast_op(make_caster &caster) -> decltype(caster.operator typename make_caster::template cast_op_type()) { + return caster.operator typename make_caster::template cast_op_type(); +} +template +auto cast_op(make_caster &&caster) -> decltype(caster.operator typename make_caster::template cast_op_type()) { + return cast_op(caster); +} + template class type_caster> : public type_caster_base { public: static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { @@ -757,8 +767,7 @@ public: template using cast_op_type = type; operator type() { - return type(first.operator typename make_caster::template cast_op_type(), - second.operator typename make_caster::template cast_op_type()); + return type(cast_op(first), cast_op(second)); } protected: make_caster first; @@ -831,13 +840,11 @@ public: protected: template ReturnValue call(Func &&f, index_sequence) { - return f(std::get(value) - .operator typename make_caster::template cast_op_type()...); + return f(cast_op(std::get(value))...); } template type cast(index_sequence) { - return type(std::get(value) - .operator typename make_caster::template cast_op_type()...); + return type(cast_op(std::get(value))...); } template bool load(handle src, bool convert, index_sequence) { @@ -1081,10 +1088,10 @@ NAMESPACE_END(detail) // pytype -> C++ type template ::value, int> = 0> T cast(const handle &handle) { - static_assert(!detail::cast_is_temporary_value_reference::value, + using namespace detail; + static_assert(!cast_is_temporary_value_reference::value, "Unable to cast type to reference: value is local to type caster"); - using type_caster = detail::make_caster; - return detail::load_type(handle).operator typename type_caster::template cast_op_type(); + return cast_op(load_type(handle)); } // pytype -> pytype (calls converting constructor) @@ -1153,7 +1160,7 @@ template 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 enable_if_t::value, T> cast_ref(object &&o, make_caster &caster) { - return load_type(caster, o).operator typename make_caster::template cast_op_type(); + return cast_op(load_type(caster, o)); } template enable_if_t::value, T> cast_ref(object &&, overload_unused &) { pybind11_fail("Internal error: cast_ref fallback invoked"); } diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index f806a11a3..766a8f215 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -53,7 +53,7 @@ template 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()); + value.insert(cast_op(conv)); } return true; } @@ -87,9 +87,7 @@ template 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(), - vconv.operator typename value_conv::template cast_op_type()); + value.emplace(cast_op(kconv), cast_op(vconv)); } return true; } @@ -123,7 +121,7 @@ template 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.push_back(cast_op(conv)); } return true; } @@ -169,7 +167,7 @@ template struct type_caster> for (auto it : l) { if (!conv.load(it, convert)) return false; - value[ctr++] = conv.operator typename value_conv::template cast_op_type(); + value[ctr++] = cast_op(conv); } return true; } @@ -221,7 +219,7 @@ template struct optional_caster { if (!inner_caster.load(src, convert)) return false; - value.emplace(inner_caster.operator typename value_conv::template cast_op_type()); + value.emplace(cast_op(inner_caster)); return true; }