From f9f3bd711f266c435fa7cd8198e5696e3fb37eef Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Mon, 30 Dec 2019 01:26:32 +0100 Subject: [PATCH] Use C++17 fold expressions when casting tuples and argument lists (#2043) This commit introduces the use of C++17-style fold expressions when casting tuples & the argument lists of functions. This change can improve performance of the resulting bindings: because fold expressions have short-circuiting semantics, pybind11 e.g. won't try to cast the second argument of a function if the first one failed. This is particularly effective when working with functions that have many overloads with long argument lists. --- include/pybind11/cast.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 3af673511..38eb8a88f 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1432,9 +1432,14 @@ protected: template bool load_impl(const sequence &seq, bool convert, index_sequence) { +#ifdef __cpp_fold_expressions + if ((... || !std::get(subcasters).load(seq[Is], convert))) + return false; +#else for (bool r : {std::get(subcasters).load(seq[Is], convert)...}) if (!r) return false; +#endif return true; } @@ -1961,9 +1966,14 @@ private: template bool load_impl_sequence(function_call &call, index_sequence) { +#ifdef __cpp_fold_expressions + if ((... || !std::get(argcasters).load(call.args[Is], call.args_convert[Is]))) + return false; +#else for (bool r : {std::get(argcasters).load(call.args[Is], call.args_convert[Is])...}) if (!r) return false; +#endif return true; }