+};
+
+template<class F> inline
+std::function<void()> wrapMain(F code, std::vector<std::string> args)
+{
+ return MainFunction<F>(std::move(code), std::move(args));
+}
+
+template<class F> inline
+std::function<void()> wrapMain(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);
+ * @encode
+ **/
+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
+ >());
+}
+
+template<class T> class Task;
+
+/** Type-erased run-once task
+ *
+ * * Like std::function but callable only once.
+ * However, it works with move-only types.
+ *
+ * * Like std::packaged_task<> but without the shared state.
+ */
+template<class R, class... Args>
+class Task<R(Args...)> {
+private:
+
+ // Placeholder for some class type:
+ struct whatever {};
+
+ // Union used for storage:
+#if 0
+ typedef typename std::aligned_union<0,
+ void*,
+ std::pair<void(*)(),void*>,
+ std::pair<void(whatever::*)(), whatever*>
+ >::type TaskUnion;
+#else
+ union TaskUnion {
+ void* ptr;
+ std::pair<void(*)(),void*> funcptr;
+ std::pair<void(whatever::*)(), whatever*> memberptr;
+ char any1[sizeof(std::pair<void(*)(),void*>)];
+ char any2[sizeof(std::pair<void(whatever::*)(), whatever*>)];
+ TaskUnion() {}
+ ~TaskUnion() {}
+ };
+#endif
+
+ // Is F suitable for small buffer optimization?
+ template<class F>
+ static constexpr bool canSBO()