+};
+
+template <class F> inline std::function<void()> wrap_main(F code, std::vector<std::string>&& args)
+{
+ return MainFunction<F>(std::move(code), std::move(args));
+}
+
+template <class F> inline std::function<void()> wrap_main(F code, int argc, const char* const argv[])
+{
+ std::vector<std::string> args(argv, argv + argc);
+ return MainFunction<F>(std::move(code), std::move(args));
+}
+
+namespace bits {
+template <class F, class Tuple, std::size_t... I>
+constexpr auto apply(F&& f, Tuple&& t, simgrid::xbt::index_sequence<I...>)
+ -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...))
+{
+ return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
+}
+}
+
+/** Call a functional object with the values in the given tuple (from C++17)
+ *
+ * @code{.cpp}
+ * int foo(int a, bool b);
+ *
+ * auto args = std::make_tuple(1, false);
+ * int res = apply(foo, args);
+ * @endcode
+ **/
+template <class F, class Tuple>
+constexpr auto apply(F&& f, Tuple&& t)
+ -> decltype(simgrid::xbt::bits::apply(
+ std::forward<F>(f),
+ std::forward<Tuple>(t),
+ simgrid::xbt::make_index_sequence<
+ std::tuple_size<typename std::decay<Tuple>::type>::value
+ >()))
+{
+ return simgrid::xbt::bits::apply(
+ std::forward<F>(f),
+ std::forward<Tuple>(t),
+ simgrid::xbt::make_index_sequence<
+ std::tuple_size<typename std::decay<Tuple>::type>::value
+ >());
+}