Use C++17 fold expressions when casting tuples and argument lists

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.
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 3af6735..38eb8a8 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -1432,9 +1432,14 @@
 
     template <size_t... Is>
     bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {
+#ifdef __cpp_fold_expressions
+        if ((... || !std::get<Is>(subcasters).load(seq[Is], convert)))
+            return false;
+#else
         for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...})
             if (!r)
                 return false;
+#endif
         return true;
     }
 
@@ -1961,9 +1966,14 @@
 
     template <size_t... Is>
     bool load_impl_sequence(function_call &call, index_sequence<Is...>) {
+#ifdef __cpp_fold_expressions
+        if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])))
+            return false;
+#else
         for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...})
             if (!r)
                 return false;
+#endif
         return true;
     }