From: Gabriel Corona Date: Thu, 26 May 2016 14:01:59 +0000 (+0200) Subject: Move some C++ helpers in xbt/ X-Git-Tag: v3_14~1159^2~1 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/d1f1e22acb2e2342b535c3847e804b4a5fee3167 Move some C++ helpers in xbt/ --- diff --git a/include/simgrid/simix.hpp b/include/simgrid/simix.hpp index bb75c8a9fb..ad30d41907 100644 --- a/include/simgrid/simix.hpp +++ b/include/simgrid/simix.hpp @@ -18,6 +18,8 @@ #include #include +#include + #include XBT_PUBLIC(void) simcall_run_kernel(std::function const& code); @@ -25,35 +27,6 @@ XBT_PUBLIC(void) simcall_run_kernel(std::function const& code); namespace simgrid { namespace simix { -/** Fulfill a promise by executing a given code */ -template -void fulfill_promise(std::promise& promise, F&& code) -{ - try { - promise.set_value(std::forward(code)()); - } - catch(...) { - promise.set_exception(std::current_exception()); - } -} - -/** Fulfill a promise by executing a given code - * - * This is a special version for `std::promise` because the default - * version does not compile in this case. - */ -template -void fulfill_promise(std::promise& promise, F&& code) -{ - try { - std::forward(code)(); - promise.set_value(); - } - catch(...) { - promise.set_exception(std::current_exception()); - } -} - /** Execute some code in the kernel/maestro * * This can be used to enforce mutual exclusion with other simcall. @@ -75,114 +48,11 @@ typename std::result_of::type kernel(F&& code) std::promise promise; simcall_run_kernel([&]{ xbt_assert(SIMIX_is_maestro(), "Not in maestro"); - fulfill_promise(promise, std::forward(code)); + simgrid::xbt::fulfillPromise(promise, std::forward(code)); }); return promise.get_future().get(); } -class args { -private: - int argc_ = 0; - char** argv_ = nullptr; -public: - - // Main constructors - args() {} - - void assign(int argc, const char*const* argv) - { - clear(); - char** new_argv = xbt_new(char*,argc + 1); - for (int i = 0; i < argc; i++) - new_argv[i] = xbt_strdup(argv[i]); - new_argv[argc] = nullptr; - this->argc_ = argc; - this->argv_ = new_argv; - } - args(int argc, const char*const* argv) - { - this->assign(argc, argv); - } - - char** to_argv() const - { - const int argc = argc_; - char** argv = xbt_new(char*, argc + 1); - for (int i=0; i< argc; i++) - argv[i] = xbt_strdup(argv_[i]); - argv[argc] = nullptr; - return argv; - } - - // Free - void clear() - { - for (int i = 0; i < this->argc_; i++) - free(this->argv_[i]); - free(this->argv_); - this->argc_ = 0; - this->argv_ = nullptr; - } - ~args() { clear(); } - - // Copy - args(args const& that) - { - this->assign(that.argc(), that.argv()); - } - args& operator=(args const& that) - { - this->assign(that.argc(), that.argv()); - return *this; - } - - // Move: - args(args&& that) : argc_(that.argc_), argv_(that.argv_) - { - that.argc_ = 0; - that.argv_ = nullptr; - } - args& operator=(args&& that) - { - this->argc_ = that.argc_; - this->argv_ = that.argv_; - that.argc_ = 0; - that.argv_ = nullptr; - return *this; - } - - int argc() const { return argc_; } - char** argv() { return argv_; } - const char*const* argv() const { return argv_; } - char* operator[](std::size_t i) { return argv_[i]; } -}; - -inline std::function wrap_main( - xbt_main_func_t code, std::shared_ptr args) -{ - if (code) { - return [=]() { - code(args->argc(), args->argv()); - }; - } - else return std::function(); -} - -inline -std::function wrap_main(xbt_main_func_t code, simgrid::simix::args args) -{ - if (code) - return wrap_main(code, std::unique_ptr( - new simgrid::simix::args(std::move(args)))); - else return std::function(); -} - -inline -std::function wrap_main(xbt_main_func_t code, int argc, const char*const* argv) -{ - return wrap_main(code, simgrid::simix::args(argc, argv)); -} - class Context; class ContextFactory; diff --git a/include/xbt/functional.hpp b/include/xbt/functional.hpp new file mode 100644 index 0000000000..31f9430ea4 --- /dev/null +++ b/include/xbt/functional.hpp @@ -0,0 +1,123 @@ +/* Copyright (c) 2015-2016. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef XBT_FUNCTIONAL_HPP +#define XBT_FUNCTIONAL_HPP + +#include + +#include +#include +#include +#include + +#include + +namespace simgrid { +namespace xbt { + +class args { +private: + int argc_ = 0; + char** argv_ = nullptr; +public: + + // Main constructors + args() {} + + void assign(int argc, const char*const* argv) + { + clear(); + char** new_argv = xbt_new(char*,argc + 1); + for (int i = 0; i < argc; i++) + new_argv[i] = xbt_strdup(argv[i]); + new_argv[argc] = nullptr; + this->argc_ = argc; + this->argv_ = new_argv; + } + args(int argc, const char*const* argv) + { + this->assign(argc, argv); + } + + char** to_argv() const + { + const int argc = argc_; + char** argv = xbt_new(char*, argc + 1); + for (int i=0; i< argc; i++) + argv[i] = xbt_strdup(argv_[i]); + argv[argc] = nullptr; + return argv; + } + + // Free + void clear() + { + for (int i = 0; i < this->argc_; i++) + std::free(this->argv_[i]); + std::free(this->argv_); + this->argc_ = 0; + this->argv_ = nullptr; + } + ~args() { clear(); } + + // Copy + args(args const& that) + { + this->assign(that.argc(), that.argv()); + } + args& operator=(args const& that) + { + this->assign(that.argc(), that.argv()); + return *this; + } + + // Move: + args(args&& that) : argc_(that.argc_), argv_(that.argv_) + { + that.argc_ = 0; + that.argv_ = nullptr; + } + args& operator=(args&& that) + { + this->argc_ = that.argc_; + this->argv_ = that.argv_; + that.argc_ = 0; + that.argv_ = nullptr; + return *this; + } + + int argc() const { return argc_; } + char** argv() { return argv_; } + const char*const* argv() const { return argv_; } + char* operator[](std::size_t i) { return argv_[i]; } +}; + +template inline +std::function wrapMain(F code, std::shared_ptr args) +{ + return [=]() { + code(args->argc(), args->argv()); + }; +} + +template inline +std::function wrapMain(F code, simgrid::xbt::args args) +{ + return wrapMain(std::move(code), + std::unique_ptr(new simgrid::xbt::args(std::move(args)))); +} + +template inline +std::function wrapMain(F code, int argc, const char*const* argv) +{ + return wrapMain(std::move(code), args(argc, argv)); +} + +} +} + +#endif diff --git a/include/xbt/future.hpp b/include/xbt/future.hpp new file mode 100644 index 0000000000..d5a31a55ce --- /dev/null +++ b/include/xbt/future.hpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2015-2016. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef XBT_FUTURE_HPP +#define XBT_FUTURE_HPP + +#include +#include +#include + +namespace simgrid { +namespace xbt { + +/** Fulfill a promise by executing a given code */ +template +void fulfillPromise(std::promise& promise, F code) +{ + try { + promise.set_value(code()); + } + catch(...) { + promise.set_exception(std::current_exception()); + } +} + +/** Fulfill a promise by executing a given code + * + * This is a special version for `std::promise` because the default + * version does not compile in this case. + */ +template +void fulfillPromise(std::promise& promise, F code) +{ + try { + (code)(); + promise.set_value(); + } + catch(...) { + promise.set_exception(std::current_exception()); + } +} + +} +} + +#endif diff --git a/src/msg/msg_process.cpp b/src/msg/msg_process.cpp index 41a526372e..3ce8d3225e 100644 --- a/src/msg/msg_process.cpp +++ b/src/msg/msg_process.cpp @@ -9,6 +9,7 @@ #include "msg_private.h" #include "xbt/sysdep.h" #include "xbt/log.h" +#include "xbt/functional.hpp" #include "src/simix/smx_process_private.h" #include "src/simix/smx_private.h" @@ -132,7 +133,8 @@ msg_process_t MSG_process_create_with_environment(const char *name, xbt_main_fun int argc, char **argv, xbt_dict_t properties) { msg_process_t res = MSG_process_create_with_environment(name, - simgrid::simix::wrap_main(code, argc, argv), data, host, + code ? simgrid::xbt::wrapMain(code, argc, argv) : std::function(), + data, host, properties); for (int i = 0; i != argc; ++i) xbt_free(argv[i]); diff --git a/src/simix/libsmx.cpp b/src/simix/libsmx.cpp index 5f66232d2b..794909f9e5 100644 --- a/src/simix/libsmx.cpp +++ b/src/simix/libsmx.cpp @@ -15,6 +15,8 @@ #include +#include + #include "src/mc/mc_replay.h" #include "smx_private.h" #include "src/mc/mc_forward.hpp" @@ -377,7 +379,7 @@ smx_process_t simcall_process_create(const char *name, { if (name == nullptr) name = ""; - auto wrapped_code = simgrid::simix::wrap_main(code, argc, argv); + auto wrapped_code = simgrid::xbt::wrapMain(code, argc, argv); for (int i = 0; i != argc; ++i) xbt_free(argv[i]); xbt_free(argv); diff --git a/src/surf/sg_platf.cpp b/src/surf/sg_platf.cpp index 144002f746..43f06efb85 100644 --- a/src/surf/sg_platf.cpp +++ b/src/surf/sg_platf.cpp @@ -9,6 +9,7 @@ #include "xbt/str.h" #include "xbt/dict.h" #include "xbt/RngStream.h" +#include #include #include "src/surf/HostImpl.hpp" #include "surf/surf.h" @@ -572,7 +573,7 @@ void sg_platf_new_process(sg_platf_process_cbarg_t process) double kill_time = process->kill_time; int auto_restart = process->on_failure == SURF_PROCESS_ON_FAILURE_DIE ? 0 : 1; - std::function code = simgrid::simix::wrap_main(parse_code, process->argc, process->argv); + std::function code = simgrid::xbt::wrapMain(parse_code, process->argc, process->argv); smx_process_arg_t arg = NULL; smx_process_t process_created = NULL; diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index c14bf259e9..0b25bce4f0 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -669,6 +669,8 @@ set(headers_to_install include/xbt/fifo.h include/xbt/file.h include/xbt/function_types.h + include/xbt/functional.hpp + include/xbt/future.hpp include/xbt/graph.h include/xbt/heap.h include/xbt/lib.h